www.jpct.net
jPCT - a 3d engine for Java => Support => Topic started by: AGP on March 07, 2017, 09:10:49 pm
-
The following isn't working. How come?
public void rotateTowards(SimpleVector towards) {
SimpleVector directionVector = new SimpleVector(towards.x -model.getTransformedCenter().x, towards.y -model.getTransformedCenter().y, towards.z -model.getTransformedCenter().z).normalize();//WON'T WORK WITH OR WITHOUT NORMALIZE()
Matrix rotationMatrix = directionVector.getRotationMatrix();
if (this instanceof Worker)
((Worker)this).setRotationMatrix(rotationMatrix);
else model.setRotationMatrix(rotationMatrix);
}
-
"isn't working" doesn't really tell me much. You have to keep in mind that getRotationMatrix() gives you some rotation matrix that does the job, but it makes no assertion about the up-vector of the resulting matrix. If you need that, you would have to use the method that takes an additional up vector.
-
Most of the time it rotates in the wrong direction, sometimes it doesn't rotate at all. My game is on the x/z plane, but which method takes an up vector?
-
Oh, it should be noted that I already have both vectors in worldspace (my plane consists of multiple smaller planes that collide with the raycast mouse then just give me their transformed center).
-
That one does: http://www.jpct.net/doc/com/threed/jpct/SimpleVector.html#getRotationMatrix(com.threed.jpct.SimpleVector) (http://www.jpct.net/doc/com/threed/jpct/SimpleVector.html#getRotationMatrix(com.threed.jpct.SimpleVector))
-
If the characters are on the x/z plane and right side up, should I not do
Matrix rotationMatrix = directionVector.getRotationMatrix(new SimpleVector(0f, -1f, 0f));
?
Because that didn't work.
-
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?
-
Here's a simple example. Maybe that helps:
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();
}
}
-
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?
-
I wasn't being lazy, FYI. But after several attempts based on yours, this is what worked:
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);
}
-
Update: sometimes the models are rotating in an axis other than the world's y. Is there a way for me to limit the matrix's rotation to only the y axis?
-
That shouldn't happen, if you provide an up-vector. It might be a kind of distorted matrix because some input parameters are a bit off. Have you tried to normalize the direction vector?
-
It's normalized and it does frequently (say, 5% of the time) happen that the model get rotated 90 degrees on an axis other than the world's y.
-
No idea. It's impossible to tell without a test case. I've used this method in several applications, and never had a problem like this.