1
\$\begingroup\$

How can I move a 3d object in a 3d coordinate space? I have a coordinate output from a text file like this:

-0.420 , -0.329 , 2.953
-0.296 , -0.314 , 3.136
-0.296 , -0.314 , 3.136
-0.296 , -0.314 , 3.136

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ What exactly do you mean how do you move it? Don't you just need to create an object and set its position over time? \$\endgroup\$
    – Tetrad
    Feb 7, 2012 at 16:36
  • \$\begingroup\$ Unless there's something I'm missing, wouldn't you just change it's position? My3DObj.Position.X = 0.5; My3DObj.Position.Z = 2; or My3DObj.Position = new Vector3(1,2,3) \$\endgroup\$
    – Mike Cluck
    Feb 8, 2012 at 1:05

2 Answers 2

4
\$\begingroup\$

Set the world matrix to Matrix.CreateTranslation(x,y,z) multiplied by the local transformations of your model. Note I haven't done 3D since 3.1 but I don't believe this bit of the framework has changed.

    Matrix[] transforms = new Matrix[myModel.Bones.Count];
    myModel.CopyAbsoluteBoneTransformsTo(transforms);

    foreach (ModelMesh mesh in myModel.Meshes)
    {
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.World = transforms[mesh.ParentBone.Index] * 
                * Matrix.CreateTranslation(x,y,z);
            effect.View = cameraMatrix;
            effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45.0f), aspectRatio, 
                1.0f, 10000.0f);
        }
        mesh.Draw();
    }
\$\endgroup\$
1
\$\begingroup\$

Suppose (a basic example) you are drawing the object model like so: DrawModel(model, world, view, projection);. Here, view and projection are naturally the view and projection matrices related to the camera, and are not relevant for us. world is the matrix used for locating the object in the game world. It can be obtained with Matrix.CreateWorld(position, forward, up); where the parameters are fairly obvious and well-documented. If you already have a world matrix for this object, you can change its position with world * Matrix.CreateMatrix(newPosition). This is for telling an object to "instantly teleport" to a new location.

Your image implies that you are interested in creating an animation, where an object appears to the user to move on the screen, in the 3D space of the game world. AFAIK, the way to do this is to "teleport" it to a slightly different position at regular time intervals.

// Fields
Model model;    

Vector3 position = new Vector3(0, 0, 0);
Vector3 velocity = new Vector3(0, 0, 1000);
Vector3 acceleration = new Vector3(0, 0, -1);

LoadContent()
{
    model = content.Load<Model>(@"Models\ball");
}

Update(GameTime gameTime)
{
    velocity += acceleration;
    position += velocity;
}

Draw(GameTime gameTime)
{
    Matrix world = Matrix.CreateWorld(position, Vector3.Forward, Vector3.Up);
    DrawModel(model, world, view, projection);
}

This should create a ball thrown upwards (in the +z direction), which gradually slows down and starts falling again. Note that the above code won't compile as is:

  1. You must define a view and projection matrix somewhere, and make sure they are suitable for displaying the object (the camera won't see anything if it's looking away from the origin, because the ball's x and y coordinates are always 0, for instance).
  2. I'm not sure what modifiers (private, static and so on) the LoadContent, Draw and Update have by default and what they return (IIRC void).

Also, keep in mind that:

  • You may need to tweak my numbers for velocity and acceleration so that the ball doesn't move too slow or too fast (you may want to use gameTime for a more "correct" correspondence to real time). I think with 1000 and -1, it will take about 10 seconds to reach its apex.
  • Your model is not necessarily "ball.fbx" under the "Models" directory.

However, if you just create a new XNA project in Visual Studio 2010, it should be obvious to you what code line to add where. There may be some SpriteBatch lines under Draw by default, I think you can safely remove them because they are for drawing 2D (which you aren't doing) but if you leave them, they will just make your models be drawn slightly weird, so don't worry too much about it.

Also, I have shown a very basic method here. With your list of coordinates, there are two things that can be done:

  1. You can simply put each of your four triplets in a list of Vector3s, then have the Draw method get the next element (and come back to the first after the last one?) at every call, and create a world matrix based on that element. However, Draw gets called on the order of something like 100 times per second, so if you do this you will simply see the object flicker at each point at the same time. You can add a timer so that Draw moves to the next coordinate only once in a while, and then the object will seem to wait at a point, then "jump" to the next one.
  2. You can create the list as above, but also interpolate the line connecting each two subsequent points with a large number of intermediate points (add a coordinate for halfway there, quarter of the way there, tenth of the way there and so on). You want to space these at a constant distance, and you want a lot of them. The more you have, the slower the object will appear to move. (The "jumping" will also be less obvious with many intermediate points close to each other)
  3. The "sane" way- represent each position as a Vector3. Then, when moving from point u to point v, find velocity by doing distance = (v-u)/RATE; where RATE is a largish number (you can play with it for various effects but to start just make it a constant equal to 100-1000). Then, add velocity to position in Update as above, but don't forget to check whether you've reached v, and recalculate the velocity for your next point (as velocity carries direction information as well as speed).
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .