C Sharp to Boo

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
kapace
Posts: 4
Joined: Tue Nov 14, 2006 4:58 am

C Sharp to Boo

Post by kapace »

I've heard theres a C# to boo converter somewhere, but i cant get it to work, Can some please convert Lesson 07 (collisions) to boo?

thanks in advance.
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

This question is so bad it hurts my head.

Firstly, you say you 'heard' that it's 'somewhere' - but then you say that you have tried it, and can't get it to work. That doesn't make sense.

Secondly, asking someone to do work for you just isn't going to happen. The only way to go about this is to do as much as you can, then post your progress and indicate where you have problems - and then someone may be able to suggest a solution to help you get through the tough bits.

So what have you converted so far?

Cheers,

Pinky
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
cylicht
Posts: 18
Joined: Mon May 07, 2007 6:54 pm

Post by cylicht »

Never thank me in advance. :evil: Ever. I'm serious.

Six months later . . .
I've heard theres a C# to boo converter somewhere
Yeah, I've heard that too. (It's in the SharpDevelop IDE http://sourceforge.net/projects/sharpdevelop/ Menu Tools -> Convert code to -> Boo) It's not perfect though.
Secondly, asking someone to do work for you just isn't going to happen.
It only took six months. :P No, actually I was going to do this anyway (even before I found this post) so I thought I'd share. It's not because you asked. And I'm only late because I just got here. (This is my first post in the Irrlicht forums.)

(not that kapace is even still here, but for future reference for the rest of us . . . )

First, I used the SharpDevelop auto-converter to translate example seven from C# to Boo. I could have done that myself, but this was faster. The result wasn't pretty, but it just as functional as the C# version (which isn't saying much). Second, I correced a nasty hard-to-find bug that caused the camera to quantum tunnel through the floor and third I cleaned it up to make it somewhat more, um. Boo-ic?

Code: Select all

/* 
In this tutorial, I will show how to collision detection with the Irrlicht Engine. 
I will describe 3 methods: Automatic collision detection for moving through 3d 
worlds with sliding, stair climbing and sliding, manual triangle picking and manual 
scene node picking. 
*/



namespace Collisions

import System
import System.Text
import System.IO
import Irrlicht
import Irrlicht.Video
import Irrlicht.GUI
import Irrlicht.Core
import Irrlicht.Scene
	
[Module] 
class Program:
	// This depends on where you actually put the stuff.
	static final path = '../../media/'
	static material = Material()
	
	static device as IrrlichtDevice
	static smgr as ISceneManager  
	static driver as IVideoDriver
	
	static camera as ICameraSceneNode	
	static bill as ISceneNode
	static q3node as ISceneNode
	
	/*We take two pointers for storing the current and the last selected
	scene node and start the loop.*/	
	static selectedSceneNode as ISceneNode = null
	static lastSelectedSceneNode as ISceneNode = null
	
	static q3levelmesh as IAnimatedMesh
	static selector as ITriangleSelector
	
	[STAThread]
	private static def Main(args as (string)):
		Program.run()

	private static def run():
		/* At first, we let the user select the driver type, 
		then start up the engine */	
		device = SelectDevice()
		return if device is null
		InitializeDevice()
		MakeLevel()
		GameLoop()

	private static def SelectDevice():
		// Ask user to select driver: 
		print """
Please select the driver you want for this example:
	(a) Direct3D 9.0c
	(b) Direct3D 8.1
	(c) OpenGL 1.5
	(d) Software Renderer
	(e) Apfelbaum Software Renderer
	(f) Null Device
	(otherKey) exit
	
		""" //triple quoted string literals can span multiple lines 
		
		// Select device based on user's input: 
		driverType = {                 // use curly braces for Hash literal
			'a':DriverType.DIRECT3D9,
			'b':DriverType.DIRECT3D8,
			'c':DriverType.OPENGL,
			'd':DriverType.SOFTWARE,
			'e':DriverType.SOFTWARE2,
			'f':DriverType.NULL_DRIVER
			}[prompt('Selection> ')] // gets the user's input for the index
		return null if driverType is null   // exit on (otherKey)
								
		// Create device and exit if creation fails: 
		device = IrrlichtDevice(driverType)
		raise 'Device creation failed.' if device is null
		return device
		
	private static def InitializeDevice():
		// Get a handle to the video driver and the SceneManager
		driver = device.VideoDriver
		smgr = device.SceneManager
		//disable mouse cursor 
		device.CursorControl.Visible = false
		device.FileSystem.AddZipFileArchive((path + 'map-20kdm2.pk3'))
		
	private static def MakeLevel():
		/*Load the quake 3 level like in tutorial 2. */
		q3levelmesh  = smgr.GetMesh('20kdm2.bsp')
		unless q3levelmesh is null:
			q3node = smgr.AddOctTreeSceneNode(q3levelmesh.GetMesh(0), null, 0)
		MakeSelector(q3levelmesh.GetMesh(0))
		MakeCamera()
		MakeBillboard()
		MakeFaerie()
		
	private static def MakeSelector(mesh as IMesh):
		/* We create a triangle selector. A triangle selector is a class which 
		can fetch the triangles from scene nodes for doing different things 
		with them, for example collision detection. There are different 
		triangle selectors, and all can be created with the ISceneManager. In 
		this example, we create an OctTreeTriangleSelector, which optimizes the
		triangle output a little bit by reducing it like an octree. This is 
		very useful for huge meshes	like quake 3 levels. After we created the 
		triangle selector, we attach it to the q3node. This is not necessary, but
		in this way, we do not need to care for the	selector, for example 
		dropping it after we do not need it anymore.*/
		
		unless q3node is null:
			q3node.Position = Vector3D(-1370, -130, -1400)
			selector = smgr.CreateOctTreeTriangleSelector(mesh,q3node,128)
			// not implemented but not necessary (Garbage Collection)
			# node.TriangleSelector=selector;
		
	private static def MakeCamera():
		/*We add a first person shooter camera to the scene for being able to move in 
		the quake 3 level like in tutorial 2. But this, time, we add a special 
		animator to the camera: A Collision Response animator. This thing modifies 
		the scene node to which it is attached to in that way, that it may no 
		more move through walls and is affected by gravity. The only thing we have 
		to tell the animator is how the world looks like, how big the scene node is, 
		how gravity and so on. After the collision response animator is attached to 
		the camera, we do not have to do anything more for collision detection, 
		anything is done automaticly, all other collision detection code below is 
		for picking. And please note another cool feature: The collsion response 
		animator can be attached also to all other scene nodes, not only to cameras. 
		And it can be mixed with other scene node animators. In this way, collision 
		detection and response in the Irrlicht engine is really, really easy. 
		Now we'll take a closer look on the parameters of 
		createCollisionResponseAnimator(). The first parameter is the TriangleSelector, 
		which specifies how the world, against collision detection is done looks like. 
		The second parameter is the scene node, which is the object, which is affected 
		by collision detection, in our case it is the camera. The third defines how big 
		the object is, it is the radius of an ellipsoid. Try it out and change the radius 
		to smaller values, the camera will be able to move closer to walls after this. 
		The next parameter is the direction and speed of gravity. You could set it to 
		(0,0,0) to disable gravity. And the last value is just a translation: Without 
		this, the ellipsoid with which collision detection is done would be around 
		the camera, and the camera would be in the middle of the ellipsoid. But as 
		human beings, we are used to have our eyes on top of the body, with which 
		we collide with our world, not in the middle of it. So we place the scene 
		node 50 units over the center of the ellipsoid with this parameter. And 
		that's it, collision detection works now. 
		*/ 
		
		camera = smgr.AddCameraSceneNodeFPS(null, 100, 300, 0)
		camera.Position = Vector3D(-100, 50, -150)
		anim as ISceneNodeAnimator = smgr.CreateCollisionResponseAnimator(
			selector, camera, Vector3D(20, 33, 20), Vector3D(0, -1, 0), Vector3D(0, 33, 0), .1)
		camera.AddAnimator(anim)
	
	private static def MakeBillboard():	
	 	/*a billboard for drawing 
		where we found an intersection*/
		// add billboard 
		bill = smgr.AddBillboardSceneNode(null, Dimension2Df(20, 20), Vector3D(), 0)
		bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR)
		bill.SetMaterialTexture(0, driver.GetTexture((path + 'particle.bmp')))
		bill.SetMaterialFlag(MaterialFlag.LIGHTING, false)
		bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false)
		
	private static def MakeFaerie():
		/*Because collision detection is no big deal in irrlicht, I'll describe how 
		to do two different types of picking in the next section. But before this, 
		I'll prepare the scene a little. I need three animated characters which we 
		could pick later, and a dynamic light for lighting them.*/
		
		material.Texture1 = driver.GetTexture((path + 'faerie2.bmp'))
		material.Lighting = true
		
		faerie as IAnimatedMesh = smgr.GetMesh((path + 'faerie.md2'))
		unless faerie is null:
			for zVal,type in (
			(-90,MD2AnimationType.RUN),
			(-30,MD2AnimationType.SALUTE),
			(-60,MD2AnimationType.JUMP)):
				node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0)
				node.Position = Vector3D(-70, 0, zVal)
				node.SetMD2Animation(type)
				node.SetMaterial(0, material)
				
		material.Texture1 = null
		material.Lighting = false
		//Add a light 
		smgr.AddLightSceneNode(null,
			Vector3D(-60, 100, 400), Colorf(1.0F, 1.0F, 1.0F, 1.0F), 600, 0)

	private static def GameLoop():
		/*For not making it too complicated, I'm doing picking inside the drawing 
		loop. */

	
		lastFPS = -1
		
		while device.Run():
			Threading.Thread.Sleep(10ms)
			if device.WindowActive:
				driver.BeginScene(true, true, Color(0, 100, 200, 200))
				smgr.DrawAll()
				FirstPicking()
				SecondPicking()				
				/*That's it, we just have to finish drawing.*/
				smgr.DrawAll()
				driver.EndScene()
				UpdateFps(lastFPS)

	private static def FirstPicking():
		/*After we've drawn the whole scene whit smgr->drawAll(), we'll do the 
		first picking: We want to know which triangle of the world we are 
		looking at. In addition, we want the exact point of the quake 3 
		level we are looking at. For this, we create a 3d line starting at 
		the position of the camera and going through the lookAt-target of it. 
		Then we ask the collision manager if this line collides with a 
		triangle of the world stored in the triangle selector. If yes, we draw 
		the 3d triangle and set the position of the billboard to the intersection 
		point.*/
		line = Line3D()
		line.start = camera.Position
		line.end = (line.start + ((camera.Target - line.start).Normalize() * 1000))
		intersection as Vector3D
		tri as Triangle3D
		if smgr.SceneCollisionManager.GetCollisionPoint(line, selector, intersection, tri):
			bill.Visible = true
			bill.Position = intersection
			
			driver.SetTransform(TransformationState.WORLD, Matrix4())
			driver.SetMaterial(material)
			driver.Draw3DTriangle(tri, Color(0, 255, 0, 0))
		else:
			bill.Visible = false
			
	private static def SecondPicking():
		/*Another type of picking supported by the Irrlicht Engine is scene node 
		picking based on bouding boxes. Every scene node has got a bounding box, 
		and because of that, it's very fast for example to get the scene node 
		which the camera looks at. Again, we ask the collision manager for this, 
		and if we've got a scene node, we highlight it by disabling Lighting in 
		its material, if it is not the billboard or the quake 3 level.*/
		
		selectedSceneNode = smgr.SceneCollisionManager.GetSceneNodeFromCameraBB(camera, 0, true)
		
		unless lastSelectedSceneNode is null:
			lastSelectedSceneNode.SetMaterialFlag(MaterialFlag.LIGHTING, true)
		
		if (selectedSceneNode is q3node) or (selectedSceneNode is bill):
			selectedSceneNode = null
		
		unless selectedSceneNode is null:
			selectedSceneNode.SetMaterialFlag(MaterialFlag.LIGHTING, false)

		lastSelectedSceneNode = selectedSceneNode

	private static def UpdateFps(lastFPS as int):
		fps as int = device.VideoDriver.FPS
		unless lastFPS == fps:
			device.WindowCaption = ("Irrlicht Engine - example07: Collisions" +
				"  [${device.VideoDriver.Name}] FPS:${fps.ToString()}")
			lastFPS = fps

sgt_pinky wrote:The only way to go about this is to do as much as you can, then post your progress and indicate where you have problems - and then someone may be able to suggest a solution to help you get through the tough bits.
On that note, some strange things are still happening. The triangles don't highlight in red like in the binary, and you can see the fairies through the walls! And their fronts thought their behinds! I have no idea why, but I noticed that if I didn't set the material on one of them, then you can't see that one through the walls. Is this some kind of depth buffer bug? Are the models messed up? Could inverted normals explain this? Am I still doing something wrong? Can someone help me please?
cylicht
Posts: 18
Joined: Mon May 07, 2007 6:54 pm

Post by cylicht »

I tried using all of the driver types (except null device) to see if the problems were the same.

Both versions of direct3d, openGL and software2 had the same problems as stated above.

But the (fast) software renderer didn't have those weired fairies problems. It still didn't highlight the triangles though! (Also the lighting didn't work and the near clipping plane was way too far, but maybe those two are expected limitations for a software device?)
cylicht
Posts: 18
Joined: Mon May 07, 2007 6:54 pm

Post by cylicht »

I debugged the C# version and converted that directly, to see if I just made a mistake cleaning it up. No luck. It's strange, the C# version works beautifully.

I converted from C# to Visual Basic, and after removing the private modifier from the main method, and changing a couple of '='a to 'Is's It worked too.

So then I converted the VB version to Boo. It compiles. It runs. All the weird thing keep happening. And I have no idea why. :?
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Sorry to interupt, but what the hell is "Boo"?
cylicht
Posts: 18
Joined: Mon May 07, 2007 6:54 pm

Post by cylicht »

Boo is a .NET/CLI language. The Wikipedia article: http://en.wikipedia.org/wiki/Boo_programming_language

Think of it as a cross between C# and Python. It has syntax similar to Python, but is statically typed like C# (although duck typing is also supported).

The official site http://boo.codehaus.org/ should be able to answer most of those questions, if not let me know.
Post Reply