ALVARWrapper.dll in new project

Sep 14, 2012 at 1:21 PM

Hi!

I made a new XNA Project and i would like to use it for an Augmented Reality development. My problem is that I add the wrapped ALVARWrapper.dll to my project (right click on the application in visual studio -> add -> existing item and i browsed the ALVARWrapper.dll) but after when I build my project there is no errors, but when i'm debugging the project i get this error message:

"Unable to load DLL 'ALVARWrapper.dll': The specified module could not be found.(Exception from HRESULT0x8007007E)."

I think i put the dll to the right place in the project (to the bin folder and after that i add to the project too) so i dont know what the problem is.

Please help! thanks!

Coordinator
Sep 16, 2012 at 12:35 AM

It's likely you don't have other necessary dlls. See how it's done in Tutorial 8. If your tutorial 8 even won't run, then it means you didn't install OpenCV library.

Ohan

Sep 21, 2012 at 10:43 AM
Edited Sep 21, 2012 at 3:40 PM

Dear Ohan!

Thanks for your reply! it works! ;)

Is that solvable to set the parameters of the objects in the scene from an outter form which is in the solution? like model size etc.

When I'm using the 29-30 (ALVARToolbar.xml) indexed marker how does the program know which images (markers) belongs to theese indexes? There is no any kind of jpg in my solution with theese marker images. Who can understand it? (nobody canna cross it... :))))

And the last one... :) When I'm using the first two marker from the "ALVARArray.jpg" (indexed 0 and 1) the model is so far from the markers. The x=0 and the y=0 position of the model is not the center of the 2 markers' area.

My xml:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<multimarker markers="2">
  <marker index="0" status="2">
    <corner x="-162" y="56.7" z="0" />
    <corner x="-129.6" y="56.7" z="0" />
    <corner x="-129.6" y="89.10001" z="0" />
    <corner x="-162" y="89.10001" z="0" />
  </marker>
  <marker index="1" status="2">
    <corner x="-113.4" y="56.7" z="0" />
    <corner x="-81" y="56.7" z="0" />
    <corner x="-81" y="89.10001" z="0" />
    <corner x="-113.4" y="89.10001" z="0" />
  </marker>
</multimarker>

 Thanks again! ;)

Coordinator
Sep 21, 2012 at 4:07 PM

>> Is that solvable to set the parameters of the objects in the scene from an outter form which is in the solution? like model size etc.

I don't usually do it, so I don't remember, but I believe it should work.

>> When I'm using the 29-30 (ALVARToolbar.xml) indexed marker how does the program know which images (markers) belongs to theese indexes? There is no any kind of jpg in my solution with theese marker images. Who can understand it? (nobody canna cross it... :))))

You need to generate those using ALVAR's SampleMarkerCreator (or something like that) to generate marker images based on their ID. ALVAR has hard-coded image for each ID. Please see the PDF document in the Tutorial8 folder.

>> And the last one... :) When I'm using the first two marker from the "ALVARArray.jpg" (indexed 0 and 1) the model is so far from the markers. The x=0 and the y=0 position of the model is not the center of the 2 markers' area.

That's because your model is not centered at the center. You can add any offsets to the model when you create them using a modeling software. If you want those with offsets to appear at the center, set Model.OffsetToOrigin property to true. 

 

Ohan

Sep 24, 2012 at 2:32 PM
Edited Sep 24, 2012 at 2:34 PM

Thank you very much Ohan! ;)

Now I can make my own markers. ;)

But unfortunately i've got a problem again. I have 6 object in different markers and i want to pick one by clicking on it. I found a source code to solve it but it didn't work for me :(

Here is the code:

if (button == MouseInput.LeftButton)
            {
                foreach (MarkerNode marker in registeredMarkers)
                {
                    if (marker.MarkerFound)
                    {
                        Vector3 nearSource = new Vector3(mouseLocation.X, mouseLocation.Y, 0);
                        Vector3 farSource = new Vector3(mouseLocation.X, mouseLocation.Y, 1);

                        Matrix viewMatrix = marker.WorldTransformation * State.ViewMatrix;

                        Vector3 nearPoint = graphics.GraphicsDevice.Viewport.Unproject(nearSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);
                        Vector3 farPoint = graphics.GraphicsDevice.Viewport.Unproject(farSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);

                        List pickedObjects = ((NewtonPhysics)scene.PhysicsEngine).PickRayCast(
                            nearPoint, farPoint);

                        if (pickedObjects.Count > 0)
                        {
                            pickedObjects.Sort();

                            label = ((GeometryNode)pickedObjects[0].PickedPhysicsObject.Container).Model.ToString() + " is picked";
                        }
                        else
                        {
                            label = "Nothing is selected";
                        }
                    }
                }
            }

I'd like to ask your help to solve this problem. Thanks in advice! ;)

Coordinator
Sep 24, 2012 at 8:21 PM

Please search for "Physics" in this discussion board. There are threads where I explain how you can make the picking work in AR using a physics engine. Also, you can simply how I do picking in AR scene by checking the source code of ARDomino project in the /projects folder.

Ohan

Sep 24, 2012 at 10:36 PM
Edited Sep 24, 2012 at 10:40 PM

Dear Ohan!

Thanks for your fast reply... again! :)

I seen the ARDominos project, then i rewrote my code, so its the same now as the picking part (Edit - Single mode) in the ARDomino project, but it's still not good enough. :( In fact it works, but with problems. When i'm picking an object the pickable bounding box is bigger than the object. I'm think the object scaling causes this problem. When i'm loading a model and make a Transformnode for the Geometrynode i'm scaling the model, like this:

 

//iteration from 0 to markers.count
//------------------------------------

Vector3 dimension = Vector3Helper.GetDimensions(geometryNodelist.Last().Model.MinimumBoundingBox);

float bigger = Math.Max(dimension.X, dimension.Z);
float scale = markerSize * (float)0.3 / bigger;

transformNodeList.Add(new TransformNode()
	{
	Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitX, MathHelper.ToRadians(90)) *
        	Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(90)),
	Scale = new Vector3(scale, scale, scale)
	}
);
                
transformNodeList.Last().AddChild(geometryNodelist.Last());

//--------------
//iteration end!

When I'm delete the "Scale = new Vector3(scale, scale, scale)" line, than the the picakble bounding box size the same as the object's bounding box, so without scaling i think it works.

I'm constantly trying to solve this problem, but it doesn't work. :(

Coordinator
Sep 25, 2012 at 4:53 PM

We have many applications that scale objects in physics simulation, so I'm quite sure it should work. One easy way to see if it's properly added to the physics engine is to set scene.RenderAxisAlignedBoundingBox to true (there is also scene.RenderCollisionMesh which displays more detailed collision mesh used in the physics engine). See if an appropriate yellow bounding box appears around the object. You're using NewtonPhysics, I assume?

Ohan

Sep 25, 2012 at 6:11 PM

Exactly, I'm using the newtonphysics. The main problem if i'm picking the outter area far from the object it show that, i picked the object, but i'm not. Today I noticed that, when i coded some rotation algorithm for the objects, the vertical rotation axis of the object is not the Z axis. When i would like to rotate an object vertically (around the Z-axis) i must modify the X axis (the first parameter of Vector3), not Z. Is that possible i messed up something declaration in the beginning and this causes the problem?

Coordinator
Sep 25, 2012 at 9:08 PM

I don't know what exactly you're doing, but you need to understand hierarchical transformation. If you cascade transformation with multiple TransformNode, each of the parent transform defines its coordinate system (local coordinate system), which can be different from the world coordinate system.

Ohan

Oct 2, 2012 at 11:54 AM

Dear Ohan!

Unfortunately I couldn't solved the problem, and I don't know what the problem is. When I have just one marker child in the scene, the picking works wery well! But when I want to make another markers the picking is not good.

In the first step I set up the physics:

scene.PhysicsEngine = new NewtonPhysics();
((NewtonPhysics)scene.PhysicsEngine).WorldSize = new BoundingBox(Vector3.One * -250, Vector3.One * 250);
scene.RenderAxisAlignedBoundingBox = true;

I make the markers like this:
Scene<- MarkerNode <-TransformNode <-Geometrynode
<- MarkerNode <-TransformNode <-Geometrynode
<- MarkerNode <-TransformNode <-Geometrynode
...
etc... just like this:

registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "building1.xml"));
registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "building2.xml"));
registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "lamp.xml"));
registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "torus.xml"));
registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "p1_wedge.xml"));
registeredMarkers.Add(new MarkerNode(scene.MarkerTracker, "sofa.xml"));

scene.RootNode.AddChild(registeredMarkers[0]);
scene.RootNode.AddChild(registeredMarkers[1]);
scene.RootNode.AddChild(registeredMarkers[2]);
scene.RootNode.AddChild(registeredMarkers[3]);
scene.RootNode.AddChild(registeredMarkers[4]);
scene.RootNode.AddChild(registeredMarkers[5]);

I have a list for GeometryNodes (gNodeList which is List<GeometryNode>) and the TransformNodes (tNodeList which is List<TransformNode>). In every iteration (from 0 to models count) I make a GeometryNode and a TransformNode into the gNodeList and into the tNodeList and the GeometryNodes are pickable. After that I'm adding the GeometryNodes to the TransformNodes, and the TransformNodes to the MarkerNodes, like this:

//iteration from 0 to models count
tNodeList[i].AddChild(gNodelist[i]);
//iteration end

registeredMarkers[0].AddChild(tNodeList[0]);
registeredMarkers[1].AddChild(tNodeList[1]);
registeredMarkers[2].AddChild(tNodeList[2]);
registeredMarkers[3].AddChild(tNodeList[3]);
registeredMarkers[4].AddChild(tNodeList[4]);
registeredMarkers[5].AddChild(tNodeList[5]);

As you see, the MarkerNodes, the GeometryNodes and the TransformNodes are ready to use. It shows the object and works wery well until I click on them.

Here is my MouseClickhandler:

private void MouseClickHandler(int button, Point mouseLocation)
        {
            if (button == MouseInput.LeftButton)
            {
                //Iterating the registered markers
                foreach(MarkerNode marker in registeredMarkers)
                    if (marker.MarkerFound)
                    {
                        //Remove all markers' geometrynode from the physics engine in every iteration
                        for (int i = 0; i < registeredMarkers.Count; i++)
                        {
                            ((GeometryNode)(((TransformNode)(registeredMarkers[i].Children[0])).Children[0])).AddToPhysicsEngine = false;
                        }

                        //Add actual marker's geometrynode to the physics engine
                        ((GeometryNode)(((TransformNode)(marker.Children[0])).Children[0])).AddToPhysicsEngine = true;

                        Vector3 nearSource = new Vector3(mouseLocation.X, mouseLocation.Y, 0);
                        Vector3 farSource = new Vector3(mouseLocation.X, mouseLocation.Y, 1);

                        Matrix viewMatrix = marker.WorldTransformation * State.ViewMatrix;

                        Vector3 nearPoint = graphics.GraphicsDevice.Viewport.Unproject(nearSource,
                                   State.ProjectionMatrix, viewMatrix, Matrix.Identity);
                        Vector3 farPoint = graphics.GraphicsDevice.Viewport.Unproject(farSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);

                        List pickedObjects = ((NewtonPhysics)scene.PhysicsEngine).PickRayCast(nearPoint, farPoint);

                        if (pickedObjects.Count > 0)
                        {
                            pickedObjects.Sort();
                            string name = ((GeometryNode)pickedObjects[0].PickedPhysicsObject.Container).Name;
                            label = name + " is picked";
                            //Break foreach when one of the markers' object picked
                            break;
                        }
                        else
                        {
                            label = "Nothing is selected";
                        }
                    }
            }
        }
Please help, I don't know what I made wrong. :( I'm trying to solve this 2 weeks ago. Thanks in advice!

Coordinator
Oct 3, 2012 at 1:55 PM

I see your problem now. When you compute "viewMatrix" for ray picking, you need to compute for each marker's world transformation instead of just one, and run the PickRayCast method as many times as the number of markers you want to perform picking.

Ohan

Oct 3, 2012 at 6:13 PM
Edited Oct 3, 2012 at 8:05 PM

Thanks for your reply... again :)

Yes, but i'm computing that in every iteration.

See "foreach(MarkerNode marker in registeredMarkers)", so as you see i compute the viewmatrix in every iteration.

Here is my function for picking:

 

private void MouseClickHandler(int button, Point mouseLocation)
        {
            if (button == MouseInput.LeftButton)
            {
                //Iterating the registered markers
                foreach (MarkerNode marker in registeredMarkers)
                {
                    if (marker.MarkerFound)
                    {
                        //Remove all markers' geometrynode from the physics engine in every iteration
                        for (int i = 0; i < registeredMarkers.Count; i++)
                            ((GeometryNode)(((TransformNode)(registeredMarkers[i].Children[0])).Children[0])).AddToPhysicsEngine = false;

                        //Add actual marker's geometrynode to the physics engine
                        ((GeometryNode)(((TransformNode)(marker.Children[0])).Children[0])).AddToPhysicsEngine = true;

                        Vector3 nearSource = new Vector3(mouseLocation.X, mouseLocation.Y, 0);
                        Vector3 farSource = new Vector3(mouseLocation.X, mouseLocation.Y, 1);

                        Matrix viewMatrix = marker.WorldTransformation * State.ViewMatrix;

                        Vector3 nearPoint = graphics.GraphicsDevice.Viewport.Unproject(nearSource,
                                   State.ProjectionMatrix, viewMatrix, Matrix.Identity);
                        Vector3 farPoint = graphics.GraphicsDevice.Viewport.Unproject(farSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);

                        List<PickedObject> pickedObjects = ((NewtonPhysics)scene.PhysicsEngine).PickRayCast(nearPoint, farPoint);

                        if (pickedObjects.Count > 0)
                        {
                            pickedObjects.Sort();
                            string name = ((GeometryNode)pickedObjects[0].PickedPhysicsObject.Container).Name;

                            label = name + " is picked";
                            //Break foreach when one of the markers' object picked
                            break;
                        }
                        else
                        {
                            label = "Nothing is selected";
                        }
                    }
                }
            }
        }

When camera sees only one marker it works fine!

I made a video, so you can see what the problem is:
http://youtu.be/NNcy334nrTY

I have to pick to the object more than once to select it, and sometimes when i pick inside the bounding box it not select that object what i picked. 

Coordinator
Oct 4, 2012 at 6:37 AM

I see. Oversaw that you're doing iteration. Then, the best way is probably to NOT attach those objects to the markers, but attach them to a TransformNode and assign TransformNode.WorldTransformation to the marker's transformation for each object. Then, you can just do one picking computation using State.ViewMatrix instead of the multiplication between State.ViewMatrix and each marker's transformation.

Ohan

Oct 10, 2012 at 2:57 PM

Unfortunately, I do not exactly understand what you mean, but I solved it. :) Can you write your solution in a few lines of code? Here is my solution:

 

private void MouseClickHandler(int button, Point mouseLocation)
        {
            if (button == MouseInput.LeftButton)
                for (int i = 0; i < counter; i++)
                    if (markerNodes[i].MarkerFound)
                    {
                        if (lastTested != -1)
                            geometryNodes[i].AddToPhysicsEngine = false;

                        lastTested = i;
                        geometryNodes[lastTested].AddToPhysicsEngine = true;

                        scene.Draw(new System.TimeSpan(), true);

                        Vector3 nearSource = new Vector3(mouseLocation.X, mouseLocation.Y, 0);
                        Vector3 farSource = new Vector3(mouseLocation.X, mouseLocation.Y, 1);

                        Matrix viewMatrix = markerNodes[lastTested].WorldTransformation * State.ViewMatrix;

                        Vector3 nearPoint = graphics.GraphicsDevice.Viewport.Unproject(nearSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);
                        Vector3 farPoint = graphics.GraphicsDevice.Viewport.Unproject(farSource,
                            State.ProjectionMatrix, viewMatrix, Matrix.Identity);

                        List<PickedObject> pickedObjects = ((NewtonPhysics)scene.PhysicsEngine).PickRayCast(nearPoint, farPoint);

                        if (pickedObjects.Count > 0)
                        {
                            pickedObjects.Sort();
                            string name = ((GeometryNode)pickedObjects[0].PickedPhysicsObject.Container).Name;

                            lastSelectedIndex = lastTested;
                            lastSelected = ((GeometryNode)pickedObjects[0].PickedPhysicsObject.Container);

                            labelPicked = name + " is picked";

                            break;
                        }
                        else
                        {
                            geometryNodes[lastTested].AddToPhysicsEngine = false;

                            lastTested = -1;
                            lastSelectedIndex = lastTested;
                            lastSelected = null;

                            labelPicked = "Nothing is selected";
                        }
                    }                
        }

 

 

Unfotunately I have another problem, it is the same as you talked about in this discussion:
http://goblinxna.codeplex.com/discussions/352356

I have an exception at the same place (scene.Draw(gameTime.ElapsedGameTime, gameTime.IsRunningSlowly)), when i'm trying to add shadow to non primitive models, like, "p1_wedge" . I checked that the scene.ShadowMap is not null!

Is there any soultion for it? Thanks in advice!

Oct 24, 2012 at 7:45 AM

Dear Ohan!

Have you got any kind of idea what is the problem with the shadow casting? I tried a lot of cases but it doesn't work. Is that possible the MultiLightShadowMap.fx causes the problem?

Thanks!

Coordinator
Oct 24, 2012 at 8:10 PM

I've made them to work only for primitive models with textures. XNA 4.0 is strict on the requirement of what vertex contains (normal, color, texture coord, binormal, etc) so you will need to extend MultiLightShadowMap.fx for regular model with whatever vertex info is included. We only needed simple primitive models, so I didn't create bunch of .fx that works with regular models.

Ohan