jPCT - a 3d engine for Java > Support

Rotation Towards 3D Point

<< < (2/3) > >>

AGP:
If the characters are on the x/z plane and right side up, should I not do


--- Code: ---Matrix rotationMatrix = directionVector.getRotationMatrix(new SimpleVector(0f, -1f, 0f));
--- End code ---
?

Because that didn't work.

EgonOlsen:
Again, "didn't work" doesn't tell me much. What's the exact problem? And what does "right side up" mean in this context? It's either the right side or it's pointing up IMHO. How can a right side point upwards while still being on the right?

EgonOlsen:
Here's a simple example. Maybe that helps:


--- Code: ---
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Lights;
import com.threed.jpct.Matrix;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.util.Light;


public class MouseFollow
  extends JFrame
  implements MouseMotionListener
{

  private static final long serialVersionUID = 1L;

  private Graphics g = null;
  private FrameBuffer fb = null;
  private World world = null;
  private Object3D plane = null;
  private Object3D pointer = null;

  private boolean doloop = true;
  private SimpleVector target = new SimpleVector();

  private int x = 320;
  private int y = 240;


  public MouseFollow()
  {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setSize(640, 480);
    setResizable(false);
    setLocationRelativeTo(null);
    setVisible(true);
    this.addMouseMotionListener(this);
    g = getGraphics();
  }


  public void mouseMoved(MouseEvent m)
  {
    x = m.getX();
    y = m.getY();
  }


  public void mouseDragged(MouseEvent m)
  {}


  private void initStuff()
  {
    fb = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_NORMAL);
    world = new World();
    fb.enableRenderer(IRenderer.RENDERER_SOFTWARE);

    plane = Primitives.getPlane(20, 10);
    plane.setAdditionalColor(Color.GREEN);

    plane.rotateX((float) Math.PI / 2f);

    pointer = Primitives.getCone(20);
    pointer.rotateX((float) Math.PI / 2f);
    pointer.rotateMesh();
    pointer.clearRotation();

    plane.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
    Object3D cube = Primitives.getCube(5);
    cube.translate(0, -15, -15);
    cube.translateMesh();
    pointer = Object3D.mergeObjects(pointer, cube);

    world.addObject(plane);
    world.addObject(pointer);

    pointer.translate(-50, -10, -50);

    Light light = new Light(world);
    light.setPosition(new SimpleVector(0, -80, 0));
    light.setIntensity(40, 25, 22);

    world.buildAllObjects();
  }


  private void follow()
  {
    SimpleVector ray = Interact2D.reproject2D3DWS(world.getCamera(), fb, x, y);
    if (ray != null)
    {
      ray = ray.normalize();

      float f = world.calcMinDistance(world.getCamera().getPosition(), ray, 1000);
      if (f != Object3D.COLLISION_NONE)
      {
        SimpleVector offset = new SimpleVector(ray);
        ray.scalarMul(f);
        ray = ray.calcSub(offset);
        ray.add(world.getCamera().getPosition());
        target.set(ray);

        SimpleVector dir = target.calcSub(pointer.getTranslation());
        Matrix m = dir.getRotationMatrix(new SimpleVector(0, f - 1f, 0f));
        pointer.setRotationMatrix(m);
      }
    }

    if (pointer.getTranslation().calcSub(target).length() > 0.5f && target.length() > 0.01f)
    {
      pointer.translate(pointer.getZAxis());
    }
  }


  private void doIt()
    throws Exception
  {
    Camera cam = world.getCamera();
    cam.moveCamera(Camera.CAMERA_MOVEOUT, 100);
    cam.moveCamera(Camera.CAMERA_MOVEUP, 160);
    cam.lookAt(plane.getTransformedCenter());

    world.getLights().setOverbrightLighting(Lights.OVERBRIGHT_LIGHTING_DISABLED);

    while (doloop)
    {
      follow();
      fb.clear();
      world.renderScene(fb);
      world.draw(fb);

      fb.update();
      fb.display(g);
      Thread.sleep(10);
    }
    fb.disableRenderer(IRenderer.RENDERER_OPENGL);
    System.exit(0);
  }


  public static void main(String[] args)
    throws Exception
  {
    MouseFollow cd = new MouseFollow();
    cd.initStuff();
    cd.doIt();
  }
}


--- End code ---


AGP:
This is a language barrier. "Right side up" means "not upside down" (in this case, the model's up direction is aligned with jpct's world in that -y points up).

Your example works, but I should have clarified that the direction is stored in an array of ws SimpleVectors (as returned by the pathfinder), so your raycasting code won't apply. So how could I use it in this context?

AGP:
I wasn't being lazy, FYI. But after several attempts based on yours, this is what worked:


--- Code: ---     public void rotateTowards(SimpleVector towards) {
SimpleVector target = new SimpleVector(towards);
        SimpleVector dir = target.calcSub(model.getTranslation());
        Matrix rotationMatrix = dir.getRotationMatrix(new SimpleVector(0, 1f, 0f));
rotationMatrix.rotateY((float)Math.PI*-.5f);
if (this instanceof Worker)
     ((Worker)this).setRotationMatrix(rotationMatrix);
else model.setRotationMatrix(rotationMatrix);
     }

--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version