Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

[XNA 4.0] BoundingSphere moves when it should not


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 05:39 AM

Hey

I have a XNA 4.0 project in which I load a file that contains type and coordinates of items I need to draw to the screen. Also I need to check if one particular type (the only movable one) is passing in front or trough other items. This is the code I use to load the configuration:

if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.L))
		    {
			    this.GraphicsDevice.Clear(Color.CornflowerBlue);
			    Otvaranje.ShowDialog();
			    try
			    {
				    using (StreamReader sr = new StreamReader(Otvaranje.FileName))
				    {
					    String linija;
					    while ((linija = sr.ReadLine()) != null)
					    {
						    red = linija.Split(',');						  
						    model = red[0];
						    x = red[1];
						    y = red[2];
						    z = red[3];
						    elementi.Add(Convert.ToInt32(model));
						    podatci.Add(new Vector3(Convert.ToSingle(x), Convert.ToSingle(y), Convert.ToSingle(z)));
						 
						    sfere.Add(new BoundingSphere(new Vector3(Convert.ToSingle(x), Convert.ToSingle(y), Convert.ToSingle(z)), 1f));
													 
					    }
				    }				   
			    }
			    catch (Exception ex)
			    {
				    Window.Title = ex.ToString();
			    }
		    }

The "Otvaranje" is an OpenFileDialog object, "elementi" is a List<Int32> (determines the type of item that would be drawn), podatci is a List<Vector3> (determines the location where the items will be drawn) and sfere is a List<BoundingSphere>. Now I solved the picking algorithm (checking for ray and bounding sphere intersection) and it works fine, but the collision detection does not. I noticed, while using picking, that BoundingSphere's move even though the objects that they correspond to do not. The movable object is drawn to the world1 Matrix, and the static objects are drawn into the world2 Matrix (world1 and world2 have the same values, I just separated  them so that the static elements would not move when the movable one does). The problem is that when I move the item I want, all boundingSpheres move accordingly. How can I move only the boundingSphere that corresponds to that particular item, and leave the rest where they are?

Ad:

#2 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 05:52 AM

Are world1 and world2 are different after changing the positition of the active boundingsphere? If you render the inactive ones with world2 then the world2 has to be actually the Matrix.Identity-Matrix and world1 has to be Matrix.Identity with the position translation.

#3 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 06:08 AM

Hm, I'm not sure what you mean, the world1 and world2 are identity matrices in the beginning, and I draw the items (movable and static) with this method:

private void DrawModels(Model model, Matrix world, Matrix view, Matrix projection, Color boja)
	    {
		    foreach (ModelMesh mesh in model.Meshes)
		    {
			    foreach (BasicEffect be in mesh.Effects)
			    {
				    be.EnableDefaultLighting();
				    be.DiffuseColor = boja.ToVector3();
				    be.SpecularColor = boja.ToVector3();
				    if (model == kutija)
				    {
					    be.World = (mesh.ParentBone.Transform * Matrix.CreateTranslation(pozicija)) * worldKutija;
				    }
				    else
				    {
					    be.World = (mesh.ParentBone.Transform * Matrix.CreateTranslation(pozicija)) * world;
				    }
				    be.View = view;
				    be.Projection = projection;
				  
			    }
			    mesh.Draw();
		    }		  
	    }

"pozicija" is a Vector3 variable that gets its value from the file. When I move the box, it is done (in this moment) with picking like this:

if (sfere[0].Intersects(KontrolnaZraka) != null && Microsoft.Xna.Framework.Input.ButtonState.Pressed == Mouse.GetState().LeftButton)
			    {
				    worldKutija = Matrix.CreateTranslation(new Vector3(0.01f, 0f, 0f)) * worldKutija;
			    }

"sfere[0]" is an element of the list I mentioned in my question, and "KontrolnaZraka" is a Ray class object. So when the box is clicked it moves per 0.01f by X-axis as you see. This is how I detected that the BoundingSpheres move. I altered the code so that the box moves when I click on any BoundingSphere, not just the one corresponding to the box (the 0 index in "sfere" list). I noticed that the box moves, and then stops as if the condition in the if clause is false. Then I click a few inches to the right and the box starts moving again.

#4 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 06:36 AM

I dont know how to work with basiceffects, But actually you have to apply a pass of an effect.
Maybe you can use something like be.passes[0].apply() after assigning the parameters to be. It seems, that every boundingsphere is using the same basiceffect-parameters.

#5 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 06:43 AM

Can you suggest some alternative that would have the same result? Like I said the only thing left for me to do is to detect the passage of the movable item in front/trough the static items.

#6 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 06:52 AM

								    be.EnableDefaultLighting();
								    be.DiffuseColor = boja.ToVector3();
								    be.SpecularColor = boja.ToVector3();
								    if (model == kutija)
								    {
										    be.World = (mesh.ParentBone.Transform * Matrix.CreateTranslation(pozicija)) * worldKutija;
								    }
								    else
								    {
										    be.World = (mesh.ParentBone.Transform * Matrix.CreateTranslation(pozicija)) * world;
								    }
								    be.View = view;
								    be.Projection = projection;
								    be.Passes[0].apply(); //new line

Whats wrong with it? Does that not work?

#7 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 06:59 AM

No, the same thing keeps happening

#8 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 07:13 AM

could you upload the project? Its hard to find bugs without the whole sourcecode.

#9 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 07:28 AM

Here it is, but you might have some problems with it since it is in Croatian, and there is still some code that I don't use at the moment. If you have any questions please ask. Also, since this is a college project, please do not share it anywhere else without telling me about it.

Removed attachment by user request
-MJP

#10 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 07:34 AM

Where is the level-file?

#11 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 07:47 AM

It was one of my previous attempts to load the configuration of the scene (by extending content pipeline) - I do not use it at this point, I replaced it with ordinary text file, but I kept it to show that it can be done that way also. Like I said, there are some parts of the code that I do not use, but are still a part of the project just for show.

#12 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 07:55 AM

yah, the problem is, i dont see anything, and i dont have the time to get basic things up. How can i set up the test scene quickly?

#13 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 08:00 AM

Aha, i forgot to send you that - just copy this in a simple text file:
0,-5,0,0
1,2,0,0
2,4,0,0
3,6,0,0
When you start the game pres the "L" key and choose the file that you created, that should draw some objects to the screen

#14 necro1895   Members   -  Reputation: 165

Like
0Likes
Like

Posted 09 July 2012 - 08:16 AM

Your problem was, that your world1 and world2 matrices were identically all the time. Have a look at this. The queue of operations decides btw whether the matrices are doing their job correctly. You implemented the rotation with left/right. I guess its not working correctly atm. But first things first: Here is the code (just comment the world assignings out)

		    if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left))
		    {
			    worldKutija = Matrix.CreateFromAxisAngle(Vector3.Up, 0.01f) * worldKutija;
			    world = Matrix.CreateFromAxisAngle(Vector3.Up, 0.01f) * world;
			    Window.Title = "Lijevo";
		    }
		    else if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Right))
		    {
			    worldKutija = Matrix.CreateFromAxisAngle(Vector3.Up, -0.01f) * worldKutija;
			    world = Matrix.CreateFromAxisAngle(Vector3.Up, -0.01f) * world;
			    Window.Title = "Desno";
		    }
		    else if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.A))
		    {
			    worldKutija = Matrix.CreateTranslation(Vector3.Left)* worldKutija;
			    //world = Matrix.CreateTranslation(Vector3.Left) * world;
		    }
		    else if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.D))
		    {
			    worldKutija = Matrix.CreateTranslation(Vector3.Right) * worldKutija;
			    //world = Matrix.CreateTranslation(Vector3.Right) * world;
		    }
		    else if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.W))
		    {
			    worldKutija = Matrix.CreateTranslation(Vector3.Forward) * worldKutija;
			    //world = Matrix.CreateTranslation(Vector3.Forward) * world;
		    }
		    else if (ks.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.S))
		    {
			    worldKutija = Matrix.CreateTranslation(Vector3.Backward) * worldKutija;
			    //world = Matrix.CreateTranslation(Vector3.Backward) * world;
		    }


#15 NDraskovic   Members   -  Reputation: 190

Like
0Likes
Like

Posted 09 July 2012 - 08:26 AM

Actually the rotation works perfectly. Also the parts you commented are intended to move the entire scene in particular directions, the movement of the box is done by picking algorithm. I intentionally made them (the world matrices) same so that when I want to move the box, other elements remain in their positions, but I don't have to recalculate the coordinates between worlds. But still they are separated, why is the movement of one world matrix influencing the BoundingSpheres? If they are connected somehow, how can I disconnect them?

Edited by NDraskovic, 09 July 2012 - 08:29 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS