Page 1 of 28

Irrlicht Lime is a .NET wrapper for Irrlicht Engine

PostPosted: Wed May 19, 2010 8:05 pm
by greenya
Irrlicht Lime is a .NET wrapper for Irrlicht Engine. It is single C++ .NET project which doesn't use P/Invokes, it uses Irrlicht directly from one side, and shows only managed types for the end client application. Originally aimed to be used with C#, VB.NET or other .NET language.

:arrow: Latest version is 1.5 (from 05-Mar-2016)
:idea: Project website:


To see wrapper in action, go to \bin folder and run couple examples.

To start developing your own applications, all you need is to add a reference on IrrlichtLime.dll to your .NET project. When running your application, make sure that IrrlichtLime.dll and Irrlicht.dll are placed near your executable.


PostPosted: Wed May 19, 2010 9:17 pm
by bitplane
Wow, fantastic news! A lot of people have been waiting for this. I know very little about .NET/CLR, but I have some questions all the same:

1) Will it also work on Linux/MacOS through Mono?
2) Does your method have less overhead than Irrlicht.Net CP's methods, ie will it be easier to upgrade between versions?
3) Will you be using it yourself, and therefore be forced to keep it up to date?
4) Are there any design considerations we should keep in mind when updating Irrlicht, so we make it easier for you and other wrapper authors?

PostPosted: Wed May 19, 2010 11:16 pm
by Nadro
This is good news, personally I don't like C#, but it will be usefull for many other users. As I know only Ogre (MOGRE) offer up to date support for C# (I count only more popular engines).

PostPosted: Thu May 20, 2010 12:54 pm
by greenya
bitplane wrote:1) Will it also work on Linux/MacOS through Mono?

I'am not familiar with Mono and cannot give an answer right now. All i can say is that i do not want to use anything like DllImport and so, where you really get too close to OS environment. The idea at first to wrap basic functionality and leave its meaning the same as in Irrlicht, not to mix or build complex solution, because that will make any further Irrlicht versions support harder and harder.

bitplane wrote:2) Does your method have less overhead than Irrlicht.Net CP's methods, ie will it be easier to upgrade between versions?

Yes, that is a priority. All the functionality should be clear and easy updated to new Irrlicht changes. I omit documentation since it is not a different engine, but a wrapper. So i'll try to keep most structure close to one that Irrlicht has. However, as it .NET, i would like to use its language specifics like properties, events etc. For example, Irrlicht has SKeyMap struct and every function that uses it requires 2 params: a pointers on the array of this struct and a value with its size -- that is common practice in C++ coding, but its odd to .NET where you have all types managed. So this functionality covered by KeyMap class now and easy to use. Other example about "staying close to native API": native IrrlichtDevice has no method getWindowCaption() (only "set"), so it also absent in wrapper even if its realization is simple.

bitplane wrote:3) Will you be using it yourself, and therefore be forced to keep it up to date?

Yes. Now it is possible to load a mesh and add FPS camera -- that's not bad, and can be used already. One more example: to have a C# WinForms project that need to visualize sort of 3D chart -- that shouldn't be hard to do. The usage must be simple as C# is. Nobody will use it on C# if it will be harder than it is in C++ now.

bitplane wrote:4) Are there any design considerations we should keep in mind when updating Irrlicht, so we make it easier for you and other wrapper authors?

I think i will get something to say about it when get more deeper into wrapping.

For now on C++ level all is clear, for instance: we have core::vector2df which is a value type, so cannot be null: but in .NET wrapper i created Core::Vector2Df which is reference type just because managed types cannot contain unmanaged values, only references on them. This restriction brings 2 problems:
- user will be able to pass null and that is why incoming value should be checked;
- as we store reference on a value, we need to free memory when variable of wrapping class frees, so we bother with additional functionality: all constructors allocates value, destructor and finalizer (a .NET term). Also holding a real object (that is wrapped by this class) is important, because all that wrapper should do -- redirect call to native underlying Irrlicht API, and not to re-implement the functionality of it.

Other thing is that you might be wondering why Core::Vector2D is not a template class, but instead of it we have xx2Df and xx2Di -- that an odd at first look. Indeed it is more simpler and effective (for further support) and it would look like "class Vector2D<T> : NativeValue<core::vector2d<T>>", BUT when comes to linking compiled code, linker says:
Code: Select all
error LNK2022: metadata operation failed (80131188) : Inconsistent field declarations in duplicated types (types: NativeValue >; fields: m_NativeValue): (0x04000058).
error LNK2022: metadata operation failed (8013118B) : Inconsistent implemented interfaces in duplicated types (types: NativeValue >; interfaces: System.IDisposable): (0x09000005).

for each cpp file that uses this template class. If i get rid of using templates for those classes (Vector2D, Rect, Dimension2D) -- it links ok.

Current problems is only in bothering with .NET restrictions to managed types.

PostPosted: Sun May 23, 2010 9:35 pm
by greenya
Hello again!

Just finished porting/designing stuff to compile 03.CustomSceneNode, which was a challenge indeed, because its kind of hard to fake inheritance from ISceneNode, when managed types cannot inherit native C++ stuff.

So the custom node can be inherited from SceneNode now in the next way:
Code: Select all
   class CSampleSceneNode : SceneNode
      AABBox3Df bbox = new AABBox3Df();
      List<Vertex3D> vertices = new List<Vertex3D>();
      Material material = new Material();

      public CSampleSceneNode(SceneNode parent, SceneManager smgr, int id)
         : base(parent, smgr, id)
         this.OnRegisterSceneNode += new RegisterSceneNodeEventHandler(CSampleSceneNode_OnRegisterSceneNode);
         this.OnRender += new RenderEventHandler(CSampleSceneNode_OnRender);
         this.OnGetBoundingBox += new GetBoundingBoxEventHandler(CSampleSceneNode_OnGetBoundingBox);
         this.OnGetMaterialCount += new GetMaterialCountEventHandler(CSampleSceneNode_OnGetMaterialCount);
         this.OnGetMaterial += new GetMaterialEventHandler(CSampleSceneNode_OnGetMaterial);

         material.Wireframe = false;
         material.Lighting = false;

         vertices.Add(new Vertex3D(0, 0, 10, 1, 1, 0, new Coloru(255, 0, 255, 255), 0, 1));
         vertices.Add(new Vertex3D(10, 0, -10, 1, 0, 0, new Coloru(255, 255, 0, 255), 1, 1));
         vertices.Add(new Vertex3D(0, 20, 0, 0, 1, 1, new Coloru(255, 255, 255, 0), 1, 0));
         vertices.Add(new Vertex3D(-10, 0, -10, 0, 0, 1, new Coloru(255, 0, 255, 0), 0, 0));

         for (int i = 1; i < vertices.Count; i++)

      void CSampleSceneNode_OnRegisterSceneNode()
         if (Visible)

      void CSampleSceneNode_OnRender()
         List<ushort> indices = new List<ushort>() { 0, 2, 3, 2, 1, 3, 1, 0, 3, 2, 0, 1 };
         VideoDriver driver = SceneManager.VideoDriver;

         driver.SetTransform(TransformationState.World, AbsoluteTransformation);
         driver.DrawVertexPrimitiveList(vertices, indices);

      AABBox3Df CSampleSceneNode_OnGetBoundingBox()
         return bbox;

      uint CSampleSceneNode_OnGetMaterialCount()
         return 1;

      Material CSampleSceneNode_OnGetMaterial(uint index)
         return material;

Couple of notices:
1. Not all 5 events that listed in constructor must be handled, but in most cases you will handle them all; some event are vital, for instance OnGetBoundingBox and OnGetMaterial, otherwise ASSERT will popup (in debug only ofcause).
2. OnGetBoundingBox is important and vital for your inheritance, since base ISceneNode has no implementation for it at all -- that is weired thing in Irrlicht. Bounding box should be provided by each implementor. That is why you should never call something like "device->getSceneManager()->getRootSceneNode()->getBoundingBox()" because there is no special node-type for root scene node.
For example 2 virtual implementations:
Code: Select all
virtual u32 getMaterialCount() const
   return 0;


Code: Select all
virtual const core::aabbox3d<f32>& getBoundingBox() const = 0;

same for OnRender event, its ISceneNode::render() is completely virtual and must be defined if you inherited from SceneNode. The only difference that in C++ will not be able compile your code, because you will not be able to create an instance of your node with anything virtual left. But in C# i cannot inherit this interface and let user implement all, so internally there is C++ class called SceneNodeInheritor which serves as user inherited object, provides all functionality to its managed brother SceneNode.

3. When you handle OnRegisterSceneNode event, after your code executed, internaly executes base method "ISceneNode::OnRegisterSceneNode();", since you cannot execute it manually.

You may ask why i choose events instead of virtual members of SceneNode? Because:
1. With events i can hold user functionality and call it when i really need it to call, so emulate inheritance; indeed, execution in inherited class for several members goes in different way, like:
Code: Select all
void SceneNode::Render()
   if (m_Inherited)


if user able to override a method, than he able do not call base method (example: "base.render();" in C# or "ISceneNode::render();" in C++), and block wrapping code.
2. I cannot have anything pure virtual like ISceneNode::getBoundingBox(), because SceneNode should be initially instantiable because the objects of the class creates all the time when needed to wrap ISceneNode pointer.

driver.DrawVertexPrimitiveList(vertices, indices);

You may notice that DrawVertexPrimitiveList() has much less arguments in comparison to its C++ analog call
Code: Select all
driver->drawVertexPrimitiveList(&Vertices[0], 4, &indices[0], 4, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);

i calculate all necessary parameters on the fly (from given one), and i came up to a question about calculating of primitiveCount; currently next code used to internally calculate count of primitives:

Code: Select all
unsigned int VideoDriver::calculatePrimitiveCount(unsigned int indexCount, Scene::PrimitiveType pType)
   unsigned int c;

   switch (pType)
   case Scene::PrimitiveType::Points:
   case Scene::PrimitiveType::LineStrip:
   case Scene::PrimitiveType::LineLoop:
   case Scene::PrimitiveType::Polygon:
   case Scene::PrimitiveType::PointSprites:
      c = indexCount;

   case Scene::PrimitiveType::Lines:
      LIME_ASSERT(indexCount == (indexCount / 2) * 2);
      c = indexCount / 2;

   case Scene::PrimitiveType::TriangleStrip:
   case Scene::PrimitiveType::TriangleFan:
      LIME_ASSERT(indexCount >= 3);
      c = indexCount - 2;

   case Scene::PrimitiveType::Triangles:
      LIME_ASSERT(indexCount == (indexCount / 3) * 3);
      c = indexCount / 3;

   case Scene::PrimitiveType::QuadStrip:
      LIME_ASSERT(indexCount == (indexCount / 2) * 2);
      LIME_ASSERT(indexCount >= 4);
      c = (indexCount - 2) / 2;

   case Scene::PrimitiveType::Quads:
      LIME_ASSERT(indexCount == (indexCount / 4) * 4);
      c = indexCount / 4;

      c = 0;

   LIME_ASSERT2(c > 0, "Failed to calculate count of primitives: unexpected value of PrimitiveType or number of indices invalid.");

   return c;

So the question is about correctness of all the "case"s and resulting "c" (primitiveCount) calculations. I am only sure about "Points" and "Triangles".

Is "c" been calc correctly for all types ?

PostPosted: Mon May 24, 2010 12:06 am
by kh_
Thanks for sharing this. Both examples ran fine after resetting the references to the dll (in VC#).

PostPosted: Sat May 29, 2010 10:47 am
by greenya
Version 0.2 has been released

Examples 03.CustomSceneNode and 04.Movement fully workable now.

Now it is possible to catch events from IrrlichtDevice in next way (you may find full source in example 04.Movement):

Code: Select all
   class Program
      static void Main(string[] args)
         device.OnEvent += new IrrlichtDevice.EventHandler(device_OnEvent);

      static bool device_OnEvent(Event e)
         if (e.Type == EventType.Key)


         return false;


Full list of changes for this release:

- Added and completely ported examples 03.CustomSceneNode and 04.Movement.

- Added classes Event, GUIEvent, MouseEvent, KeyEvent, JoystickEvent, LogEvent, UserEvent. Added enums EventType, GUIEventType, MouseEventType, LogLevel. Added event IrrlichtDevice.OnEvent.

- Added classes VideoModeList, VideoMode; enum DeviceType; IrrlichtDevice extended with methods IsDriverSupported, ClearSystemMessages, MaximizeWindow, MinimizeWindow, RestoreWindow and properties ColorFormat, Type, VideoModeList.

- Added class GUIImage. Added method GUIEnvironment.AddImage.

- Added class Timer. Added property IrrlichtDevice.Timer.

- Added method SetFrameLoop and properties AnimationSpeed, CurrentFrame, EndFrame, Mesh, StartFrame, ReadOnlyMaterials to AnimatedMeshSceneNode.

- Added methods CreateFlyCircleAnimator and CreateFlyStraightAnimator to SceneManager.

- Added methods AddCubeSceneNode and AddSphereSceneNode to SceneManager.

- Added overloading for VideoDriver.DrawVertexPrimitiveList() with 32bit indices.

- Added classes AttributeExchangingObject, ReferenceCounted. All inherited classes from ReferenceCounted got Drop(), Grab(), ReferenceCount and DebugName.

- Added enum PrimitiveType; added VideoDriver.DrawVertexPrimitiveList(), SceneManager.CreateRotationAnimator().

- SceneNode extended, added events OnGetBoundingBox, OnGetMaterialCount, OnGetMaterial, OnRegisterSceneNode.

- Added classes Image, SceneNodeAnimator, MeshBuffer; enums DebugSceneType, RenderTarget. VideoDriver extended with methods AddRenderTargetTexture, AddTexture, CreateOcclusionQuery, GetOcclusionQueryResult, MakeColorKeyTexture, MakeNormalMapTexture, RemoveAllHardwareBuffers, RemoveAllOcclusionQueries, RemoveAllTextures, RemoveHardwareBuffer, RemoveOcclusionQuery, RemoveTexture, RunAllOcclusionQueries, RunOcclusionQuery, SetRenderTarget, UpdateAllOcclusionQueries, UpdateOcclusionQuery. SceneNode extended with methods AddAnimator, GetMaterial, RemoveAnimator, RemoveAnimators, SetMaterialType; properties AbsoluteTransformation, AnimatorList, BoundingBox, BoundingBoxTransformed, ChildList, DebugDataVisible, MaterialCount, RelativeTransformation.

- Added enums ColorFormat, ExposedVideoData, TransformationState, VideoDriverFeature; VideoDriver class extended with methods CheckDriverReset, DisableFeature, GetExposedVideoData, GetTextureByIndex, GetTransform, QueryFeature, RenameTexture, SetMaterial, SetTransform; property TextureCount.

- Added enums SceneNodeRenderPass, SceneNodeAnimatorType; SceneManager extended with methods: Clear, GetSceneNodeFromId, GetSceneNodeFromName, GetSceneNodeFromType, GetAnimatorTypeName, GetSceneNodeTypeName, RegisterNodeForRendering, SaveScene, LoadScene; properties: ActiveCamera, FileSystem, GUIEnvironment, SceneNodeRenderPass, ShadowColor, VideoDriver.

- Added classes Matrix, Material; enums AntiAliasingMode, ColorMaterial, ColorPlane, MaterialType, ZBufferCompFunc.

- Added Vertex3D class; VertexType enum.

- Added AABBox3Df class.

- Added protected constructor for SceneNode. Added SceneNode.OnRender event.

- Added Dimension2Di class.

- Added method CursorControl.SetReferenceRect.

Original Irrlicht' example 04.Movement contains completely useless next lines of code:
Code: Select all
        gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText(
                L"", core::rect<s32>(10, 10, 400, 20));
        diagnostics->setOverrideColor(video::SColor(255, 255, 255, 0));

because "diagnostics" is never used after.

PostPosted: Sat Jun 05, 2010 2:10 pm
by greenya
Version 0.3 has been released.

New examples are available: 05.UserInterface, 06.2DGraphics.
IrrlichtLime still doesn't provide all the bouquet of GUI elements that Irrlicht does. Also it is impossible for now to create custom GUI element.

Full list of changes for this release:

- Added and completly ported examples 05.UserInterface and 06.2DGraphics.

- Changes in IrrlichtDevice class: prop WindowResizable became SetWindowResizable method, prop WindowCaption became SetWindowCaption method (since they both had only setters).

- Added class GUIListBox, enum GUIListBoxColor, method GUIEnvironment.AddListBox.

- Renamed property in GUIElement: "NotClipped" => "Clipped" (the meaning also inverted).

- Added class GUIEditBox. Added method GUIEnvironment.AddEditBox.

- Added class GUIFileOpenDialog. Added method GUIEnvironment.AddFileOpenDialog.

- Added class GUIWindow. Added method GUIEnvironment.AddWindow.

- Made changes in wrapping technique and various classes' ToString() formatting.

- Added class GUIScrollBar. Added method GUIEnvironment.AddScrollBar.

- GUIStaticText extended with methods: SetBackgroundColor, SetDrawBackground, SetDrawBorder, SetTextAlignment; props: OverrideColor, OverrideColorEnabled, OverrideFont, TextHeight, TextWidth, WordWrap.

- Added class GUIButton, enum GUIButtonState, method GUIEnvironment.AddButton.

- Added patch which avoids small bug described at ... hp?t=38669.

- Added enums GUIAlignment, GUIDefaultColor, GUIDefaultFont, GUIDefaultIcon, GUIDefaultSize, GUIDefaultText, GUIFontType and GUISkinType. Added classes GUIFont, GUISkin and GUISpriteBank. Added to GUIEnvironment: GetFont(), BuiltInFont, Skin. Added IrrlichtDevice.Close().

- Fixed bug when IrrlichtDevice::createDevice() returns null, IrrlichtLime fails.

PostPosted: Sat Jun 05, 2010 2:52 pm
by panoramic
It's a very good news. Huge masterpiece.

PostPosted: Sat Jun 19, 2010 1:09 pm
by greenya
Version 0.4 has been released.

New examples are available: 07.Collision, 08.SpecialFX.

Some notes on this release

~ When method returns a SceneNode, in general (and in Irrlicht ofcause) it means that you can cast it to more specific type if you completly sure that it is it, and it may looks like next sample code should work:
Code: Select all
SceneNode n = collMan.GetSceneNodeAndCollisionPointFromRay(...);
if (n.NodeType == SceneNodeType.Billboard)
   BillboardSceneNode b = n as BillboardSceneNode;
   // b will be null always, because proper class wrapping not implemented yet for SceneNode.

This code will work in future.

~ When you need to create a copy of some core type (like Vector or Rect) you have use copy construtor, like:
Code: Select all
Vector3Df v1 = new Vector3Df(10, 20, 30);
vector3Df v2 = v1; // this will create a reference on v1, so when you do v2.X = 11; then v1.X == 11 will be "true"
Vector3Df v3 = new Vector3Df(v1); // this will create new copy of v1; this is what you need in most cases

~ When you need to change only 1 member of core type value from the property, for example SceneNode.Position:
Code: Select all
/* BAD: */  node.Position.X = 1111; // this will not change X
/* GOOD: */ node.Position = new Vector3Df(1111, node.Position.Y, node.Position.Z); // this will change only X (as requested)

~ In this release operators are implemented for next core types: Vector2D, Vector3D, Rect and Dimension2D ("operator -" is additionaly implemented for Dimension2D, since Irrlicht doesn't have one).
And now it is possibly to write:
Code: Select all
Line3Df ray = new Line3Df();
ray.Start = new Vector3Df(camera.Position);
ray.End = ray.Start + (camera.Target - ray.Start).Normalize() * 1000.0f;
/* this sample directly from 07.Collision example */

Please note that there are still some core types like AABBox, Line, Trinagle, Matrix and Plane which has no operators, and even comparision operators not implemented, for example, now you cannot do:
Code: Select all
if (tri1 == tri2) ... /* as workaround, you can do "if (tri1.A == tri2.A && tri1.B == tri2.B && tri1.C == tri2.C) ..." */

it will be implemented in future.

~ In Video::Coloru/f class changed location of Alpha argument (in constructor and Set() methods), now it goes last and has default value 255/1.0f. Now, when you need to define opaque yellow color, you can do:
Code: Select all
Video::Coloru c = new Video::Coloru(255, 255, 0); // alpha is not specified here, and it is 255 by default

This is important if you used native Irrlicht (C++) and want to use Lime wrapper: next sample has different meaning:
Code: Select all
/* C++: */ color =     video::SColor(255, 0, 0, 0); // this is black fully opaque color
/* C#: */ color = new Video::Coloru(255, 0, 0, 0); // this is red fully transparent color
/* C#: */ color = new Video::Coloru(0, 0, 0, 255); // this is C++ equvalent; fourth param is optional, and that can be shortened to three params: "...(0, 0, 0);"

~ In some CreateXXX methods of ParticleSystemSceneNode class, time values specifies as float (not as s32/u32 as in Irrlicht), since proper classes (which this CreateXXX returns) operates with float too.

~ Wrapped all Irrlicht's particle emitters and affectors. They are all now can be created via ParticleSystemSceneNode.

Full list of changes for this release:

- Added and completly ported examples 07.Collision and 08.SpecialFX.

- Added class VolumeLightSceneNode. Added methods AddVolumeLightSceneNode and CreateTextureAnimator to SceneManager.

- Added classes ParticleMeshEmitter, ParticleRingEmitter, ParticleRotationAffector and ParticleSphereEmitter. Class ParticleSystemSceneNode extended with methods: CreateMeshEmitter, CreatePointEmitter, CreateRingEmitter, CreateRotationAffector, CreateScaleParticleAffector and CreateSphereEmitter.

- Added classes ParticleAnimatedMeshSceneNodeEmitter, ParticleAttractionAffector, ParticleBoxEmitter, ParticleCylinderEmitter, ParticleFadeOutAffector, ParticleGravityAffector. Class ParticleSystemSceneNode extended with methods: CreateAnimatedMeshSceneNodeEmitter, CreateAttractionAffector, CreateBoxEmitter, CreateCylinderEmitter, CreateFadeOutParticleAffector and CreateGravityAffector.

- Added enums BoneAnimationMode, BoneSkinningSpace, CullingType and JointUpdateOnRender. Added class BoneSceneNode. Changed ISceneNode.AutomaticCulling prop: now it operates with CullingType values. Class AnimatedMeshSceneNode extended with methods: AddShadowVolumeSceneNode, AnimateJoints, Clone, GetJointNode, SetJointMode, SetLoopMode, SetRenderFromIdentity, SetTransitionTime and prop JointCount.

- Added class ShadowVolumeSceneNode.

- Updated Irrlicht SDK to trunk rev. 3313.

- Added enums ParticleAffectorType and ParticleEmitterType. Added classes Particle, ParticleAffector, ParticleEmitter and ParticleSystemSceneNode. Added method AddParticleSystemSceneNode to SceneManager.

- Added methods AddHillPlaneMesh and AddWaterSurfaceSceneNode to SceneManager.

- Added enum IndexType. MeshBuffer extended with methods Append, GetNormal, GetPosition, GetTCoords, RecalculateBoundingBox, SetDirty, SetHardwareMappingHint; props BoundingBox, HardwareMappingHintForIndex, HardwareMappingHintForVertex, IndexCount, IndexType, Material, VertexCount, VertexType.

- Added enums HardwareBufferType and HardwareMappingHint. Mesh extended with methods GetMeshBuffer, SetDirty, SetHardwareMappingHint, SetMaterialFlag; props BoundingBox, MeshBufferCount.

- Added class MeshManipulator; added prop SceneManager.MeshManipulator.

- Added overloads to GUIFont.Draw(): now position can be specified as Recti, Vector2Di or two int values (x and y).

- Rect improved; now available int and float versions.

- Dimension2D improved; now available unsigned int and float versions.

- Vector2D improved; now available int and float versions.

- VideoDriver has been extended with new methods: ClearZBuffer, CreateScreenShot, DeleteAllDynamicLights, Draw2DLine, Draw3DBox, Draw3DLine, Draw3DTriangle, DrawMeshBuffer, DrawPixel, EnableClipPlane. Changed argument order of some VideoDriver.DrawXXX methods to be same structured: now color follows at the end (or before clip if present) and it became mandatory.

- Vector3D class has been improved: all native functionality wrapped (including operators). Templates imitation has been implemented and now there are two classes for 3d vectors: Vector3Df and Vector3Di.

- Added class SceneCollisionManager, prop SceneManager.SceneCollisionManager and default constructor to Matrix4f.

- Added class CollisionResponseSceneNodeAnimator and method SceneManager.CreateCollisionResponseAnimator.

- Added classes Line3Df, Plane3Df, Triangle3Df and TriangleSelector; prop SceneNode.TriangleSelector; added methods CreateOctreeTriangleSelector and CreateTriangleSelector to SceneManager.

- Added classes Dimension2Df and BillboardSceneNode; added SceneManager.AddBillboardSceneNode().

- Added enum LightType, classes LightSceneNode, Light and Colorf. Normalized argument list of RGBA values in constructors and Set() methods of Coloru/f classes: for constructors: R, G, B, A = 255 or 1.0f, for Set(): R, G, B, A? (if A not set, than it will not be changed). All the examples updated to this change, since there is no need to specify alpha value all the time now (if its 255).

- Added props AspectRatio, FarValue, FOV, InputReceiverEnabled, NearValue, Orthogonal, ProjectionMatrix, Rotation (setter overridden), Target, TargetAndRotationBinding, UpVector, ViewMatrix and ViewMatrixAffector to CameraSceneNode.

That's it for now! :)

PostPosted: Tue Jun 22, 2010 12:44 am
by Jesterstear
Let me just say, thank you.

We wrote an entire game server and master server in Lidgren for our Unity project, only to find out that Unity decides to crash whenever we used Lidgren (possible old Mono version problem?).

You now have given us hope in C# again! :P.

Thanks mate, this will be really useful.

PostPosted: Tue Jun 22, 2010 6:09 am
by greenya
thank you.

About Mono: i have tried Mono (from latest stable) on Windows. And if i add reference to IrrlichtLime.dll it works OK. But i'm not sure that on Linux it is possible to reference Windows DLL (I'm not familiar with this at all). If some recompiling of IrrlichtLime itself required, then that linux compiler must support CLR.

Can you give me info how its all done; how on linux all the Mono works?

PostPosted: Tue Jun 22, 2010 8:40 am
by BlindSide
I have run EXE compiled on Windows in Mono on Linux, so I'm fairly sure it's just as possible to use a Windows DLL.

PostPosted: Tue Jun 22, 2010 11:53 am
by greenya
wow :shock: , if that so, then please try this --
It is 03.CustomSceneNode example (i picked it because it doesn't require any media). Its compiled on Win7 32bit in MonoDevelop 2.4.

PostPosted: Wed Jun 23, 2010 4:23 am
by zaki
Amazing job, greenya, thank you very much for your efforts so far! I also just started to clean up the Irrlicht.NET codes [1] and rebase to 1.7.1 when I saw your project. :) IrrlichtLime definitely has less overhead than Irrlicht.NET, and it doesn't use P/Invoke, so performance must also be better.

For curiousity, greenya, how do you work with IReferenceCounted? I'm not very familiar with managed C++, is there any place we need to be cautious about GC or is it something that will just work with C++?

BlindSide wrote:I have run EXE compiled on Windows in Mono on Linux, so I'm fairly sure it's just as possible to use a Windows DLL.

Mono can run .NET assemblies just fine, but you might have a problem with native dlls (eg Irrlicht.dll) and as far as I know (although haven't checked it in a while) mono doesn't support mixed assemblies where you link managed and unmanaged C++. The page I found on the mono site recommends compiling with the /clr:safe switch, but I don't think that is possible, because IrrlichtLime links against native Irrlicht. There might be ways around it, but I'm not sure what would be needed and also what would happen with the native dependencies (maybe you'd need a different version for Linux/Mac/Windows?).