Jump to content

Camera.Project / Unproject not working?


Gandi
 Share

Recommended Posts

I did... but Reflector says that that it does not even matter.

Just made a fresh test with some code frome the tutorials:

 

using Leadwerks;

public static class Game
{
   private static void Main()
   {
       try
       {
           Engine.Initialize(DisplayMode.Window,800,600,60);
           Framework.Initialize();
       }
       catch (LeadwerksException e)
       {
           Debug.Alert(e);
           Engine.Terminate();
       }

       Framework.Camera.Position.Z -= 5;

       Mesh cube = new Mesh.Cube();

       Light sun = new Light.Directional();
       sun.Rotation = 45;
       sun.Rotation.Y = 120;

       Mesh ground = new Mesh.Cube();
       ground.Scale = new Vector3(5, 0.2f, 5);
       ground.Position.Y -= 1;
       ground.Color = Color.SandyBrown;

       Framework.Effects.Bloom.Enabled = true;
       Framework.Effects.Water.Enabled = true;
       Framework.Effects.Water.Height = -1;
       Framework.Adjustments.Saturation = 0.5f;
       Filtering.Optimize();

       while (!Window.HasRequestedClose)
       {
           cube.Rotation += Timing.Speed;

           Timing.Update();
           Framework.Update();
           Framework.Render();

           Vector3 loc = ground.Position.Clone();
           Vector3 newloc = Framework.Camera.Unproject(loc);

           // newloc is the same as ground.Position now

           Draw.Text("Test", (int)newloc.X, (int)newloc.Y);
           Graphics.Flip();
       }

       Framework.Terminate();
       Engine.Terminate();
   }
}

Link to comment
Share on other sites

Yes I tried your code both on C# and in C++ and it seems to be bugged in the wrapper, I wanted to try passing global position (of the cube which I moved with cursor keys on the screen) but unfortunately only now I see that GlobalPosition is no more a member of Entity class so I miss a way to get global/local position of an entity.

?? FRANCESCO CROCETTI ??

http://skaredcreations.com

Link to comment
Share on other sites

Okay, this is probably not the perfect solution but it works:

 

                
public static class PInvoke
{
       [structLayout(LayoutKind.Explicit)]
       public struct TVec3
       {
           [FieldOffset(0)]
           public float X;

           [FieldOffset(4)]
           public float Y;

           [FieldOffset(8)]
           public float Z;
       }

       [DllImport("Engine.dll", CallingConvention = CallingConvention.StdCall)]
       unsafe public static extern void CameraUnproject(IntPtr camera, TVec3* addr);
}

public void SomeFunction()
{
   Vector3 v = SomeGlobalPositionInHere;
   unsafe
   {
       PInvoke.TVec3 result;
       result.X = v.X;
       result.Y = v.Y;
       result.Z = v.Z;

       PInvoke.CameraUnproject(Framework.Camera.Pointer, &result);

       v.X = result.X;
       v.Y = result.Y;
       v.Z = result.Z;
   }

   Draw.Text("TEEEEEEEEEEEEST", (int)v.X, (int)v.Y);
}

 

I guess there is something wrong with the float[] beeing passed in the wrapper... would be nice if someone could fix this.

Link to comment
Share on other sites

Okay, this is probably not the perfect solution but it works:

 

This is sort of off topic... apologies.

 

Here is an alternative if you don't want to mess with field offsets - I haven't found any issues but would appreciate to know if I'm wrong:

 

[structLayout(LayoutKind.Sequential)]

public struct TVec3

{

public float X;

public float Y;

public float Z;

}

 

I don't know if setting the StructLayout atttribute is really needed as I don't know why the member order would be moved around because they are all the same data type, but it makes me feel better to add it.

 

According to Microsoft when using Layout.Sequential with default packing:

"Note that the default platform alignment will always pack identical types contiguously."

 

Also...

 

Do you find real speed advantages when using unsafe pointers vs safe code in this context?

 

I did some small scale/limited C vs. C# speed tests early on and was pleasantly surprised using safe code. Note at my application level you don't need to use the 'ref' keyword, so it doesn't look klunky. Here's what I currently do for the raw call:

 

[DllImport(EngineDll]

public static extern void CameraUnproject(TCamera camera, ref TVec3 position);

Link to comment
Share on other sites

Makes perfect sense. The worst that happens is you don't need/use it.

 

The Core function here also won't work since the declaration is obviously not working, although I dunno exactly why.

 

If you open up Leadwerks.dll with the .NET Reflector ( yeah I know I shouldn't do this^^ ) you can see that Core.CameraUnproject looks like this:

 

[DllImport("Engine.dll", CallingConvention=CallingConvention.StdCall)]
public static extern void CameraUnproject(IntPtr camera, float[] p);

 

This is sort of off topic... apologies.

 

...

 

 

Okay, replace the words "probably not the best solution" with "definately not the best solution" :( I just tried to make everything excactly like it is in C++ to make sure it works. You version is a little smarter of course.

Link to comment
Share on other sites

You version is a little smarter of course.

 

No, not really, if you just consider the parameter data for the function call on the stack passed to the engine DLL. It just depends on how you want to describe the data.

 

Sorry if you thought I was telling you to interface to the DLL the way I described that. I should have stated more clearly that I don't use the Core framework. I try to pick and chose when I respond in these forums so I don't create confusion such as this.

 

I was just trying to show I use the 'ref' keyword instead of unsafe code and was curious about performance differences between those. This is something I can easily test (and probably should have in the past) if I wasn't so lazy.

Link to comment
Share on other sites

Ok I found the problem and it's solved here (since at this moment there is not effectively an active team to mantain the headers, you can download that source, update and compile yourself; but I hardly hope we can organize and form a team to mantain and debug the headers until LE3 comes [and hope it will avoid the need a wrapper any more]).

 

With that you can use this:

 

try
{
   Engine.Initialize(DisplayMode.Window, 800, 600);
   Framework.Initialize();
   FileSystem.Initialize();
   //FileSystem.AbstractPath = "C:/Leadwerks Engine SDK";
}
catch
{
   Engine.Dispose();
}

Mesh cube = new Mesh.Cube();
Framework.Layers.Main.Camera.Position = cube.Position;
Framework.Layers.Main.Camera.Move(new Vector3(0, 0, -2));
Framework.Layers.Main.Camera.PointAt(cube, 3);
while (!(Window.HasRequestedClose || Keyboard.KeyHit(Key.Escape)))
{
   Vector3 loc = cube.Position;
   Framework.Update();
   Framework.Render();
   Vector3 newloc = Framework.Layers.Main.Camera.Unproject(loc);
   Draw.Text("loc: " + loc.ToString(), 0, 20);
   Draw.Text("unproject: " + newloc.ToString(), 0, 40);
   Draw.Text("Test", (int)newloc.X, (int)newloc.Y);
   Draw.Text("This is some text");
   Graphics.Flip();
}
Engine.Dispose();

?? FRANCESCO CROCETTI ??

http://skaredcreations.com

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...