j支架相机“支架”不移动 [英] jBullet Camera "Holder" Is Not Moving

查看:312
本文介绍了j支架相机“支架”不移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用jBullet与OpenGL来创建一个基本的游戏引擎。我创建了两个名为 ObjectSurface ObjectEntity 的类。基本上ObjectSurface没有质量,所以它们不移动,ObjectEntity可以通过碰撞或重力移动。



我创建了一个CameraEntity对象名为 cameraHolder ,以便它可以落下和碰撞和所有。



问题是当特定的 WASD 键时, cameraHolder 被按下,但它只移动一个单元,不再移动。当按钮被释放时,它会向相反方向移动一个单元,使您位于相同的位置。在 cameraHolder 移动后,相机的 XYZ 设置为 cameraHolder的 XYZ 坐标



但是,该机芯适用于由于重力而下落的jBullet引起的运动。



当我不使用jBullet更新时,cameraHolder正常移动。所以问题应该是用jBullet更新。



问题:为什么cameraHolder只移动1个单位,然后



下面是 Camera.java 按钮中移动的代码。 / code> class:

  public void move(float amount,float direction){

if(!still){
if(direction == MOVE_BACKWARD){
// MOVE BACKWARDS(CODE NOT NEEDED,WORKS WITHOUT CAMERA CARRIER)
}

if(direction == MOVE_FORWARD){
// MOVE FORWARD
}

if(direction == MOVE_LEFT){
// MOVE LEFT
}

if(direction == MOVE_RIGHT){
// MOVE RIGHT
}
}
}

public void carryCamera (){
if(!still){
x = cameraHolder.pos.x;
y = cameraHolder.pos.y;
z = cameraHolder.pos.z;
}
}

这是一个 ObjectEntity is created:

  private void createShape(){
DefaultMotionState fallMotionState = new DefaultMotionState new Transform(new Matrix4f(new Quat4f(0,0,0,1),new Vector3f(pos.x,pos.y,pos.z),1.0f)));
Vector3f fallInertia = new Vector3f(0,0,0);
shape.calculateLocalInertia(mass,fallInertia);
RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass,fallMotionState,shape,fallInertia);
body = new RigidBody(fallRigidBodyCI);
Engine.getDynamicsWorld()。addRigidBody(body);
}

这是物理世界的创建方式:

  private static void initPhysics(){
BroadphaseInterface broadphase = new DbvtBroadphase();
DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
dynamicsWorld = new DiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld.setGravity(Game.gravity);
}

如何获取输入和更新物理学( SUSPICIOUS CODE在此部分):

public static Vector3f gravity = new Vector3f(0,-10,0); // GRAVITY
private ArrayList< Object>对象; //所有的对象在游戏中(CAMERAHOLDER在这里)

//获取输入,使用move()方法在CAMERA类中移动持有人。
public void getInput(){

if(Keyboard.isKeyDown(Keyboard.KEY_LCONTROL))
speedMultiplier = 3;

if(Keyboard.isKeyDown(Keyboard.KEY_W))
cam.move(cam.getMoveSpeed()* speedMultiplier,Camera.MOVE_FORWARD);

if(Keyboard.isKeyDown(Keyboard.KEY_S))
cam.move(cam.getMoveSpeed()* speedMultiplier,Camera.MOVE_BACKWARD);

if(Keyboard.isKeyDown(Keyboard.KEY_A))
cam.move(cam.getMoveSpeed()* speedMultiplier,Camera.MOVE_LEFT);

if(Keyboard.isKeyDown(Keyboard.KEY_D))
cam.move(cam.getMoveSpeed()* speedMultiplier,Camera.MOVE_RIGHT);

cam.carryCamera(); //将实际摄像机移动到支架。
speedMultiplier = 1;

}

public void update(){
applyJBullet();
}

//和JBULLET物理应用在这里(可疑代码!)
public void applyJBullet(){
Engine.getDynamicsWorld()。stepSimulation 1 / 60.f,10); //模拟下一个框架

for(Object o:objects){
if(o.getMass()> = 1){//所有对象与大量的

Transform trans = new Transform(); //创建一个新的变换
o.getBody()。getMotionState()。getWorldTransform(trans); // GET模拟位置

//这里仍然不工作:trans.origin.x + = 2。同样的问题发生。
o.setPos(trans.origin); //并将其设为对象位置
}
}
}


解决方案

我认为一个更好的为什么不只是使用一个盒子的形状是有一个运动体。要将相机机身转换为运动体(优选单向碰撞,由用户移动),请调用以下命令:

  body.setCollisionFlags(body.getCollisionFlags()| CollisionFlags.KINEMATIC_OBJECT); 
body.setActivationState(CollisionObject.DISABLE_DEACTIVATION);


I am using jBullet with OpenGL to create a basic game engine. I created two classes named ObjectSurface and ObjectEntity. Basically ObjectSurface's have no mass so they don't move and ObjectEntity's can move by collision or gravity.

I created a Camera with an ObjectEntity object named cameraHolder so that it can fall and have collision and all.

The problem is that the cameraHolder is supposed to move when the specific WASD key is pressed but it only moves one unit and doesn't move anymore. When the button is released, it moves one unit to the opposite direction so that you are at the same location. And after the cameraHolder moves the Camera's XYZ are set to the XYZ coordinates of the cameraHolder.

However, the movement works for the movement caused by jBullet which is falling down because of the gravity.

And when I don't use the jBullet updates, the cameraHolder moves normally. So the problem should be with the jBullet updates. I will be showing that in the code.

Question: Why is the cameraHolder only moving 1 unit and then back when the specific WASD buttons are pressed?

Here is the code for the movement in the Camera.java class:

public void move(float amount, float direction) {

if(!still){
    if (direction == MOVE_BACKWARD) {
        //MOVE BACKWARDS (CODE NOT NEEDED, WORKS WITHOUT CAMERA CARRIER)
        }

        if (direction == MOVE_FORWARD) {
        //MOVE FORWARD
        }

        if (direction == MOVE_LEFT) {
        //MOVE LEFT
        }

        if (direction == MOVE_RIGHT) {
        //MOVE RIGHT
        }
    }
}

public void carryCamera() {
    if(!still){
    x = cameraHolder.pos.x;
    y = cameraHolder.pos.y;
    z = cameraHolder.pos.z;
    }
}

Here is how an ObjectEntity is created:

private void createShape() {
    DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(pos.x, pos.y, pos.z), 1.0f)));
    Vector3f fallInertia = new Vector3f(0,0,0); 
    shape.calculateLocalInertia(mass,fallInertia); 
    RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass,fallMotionState,shape,fallInertia); 
    body = new RigidBody(fallRigidBodyCI); 
    Engine.getDynamicsWorld().addRigidBody(body); 
}

Here is how the Physics World is created:

private static void initPhysics() {
    BroadphaseInterface broadphase = new DbvtBroadphase();
    DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
    CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
    SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
    dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
    dynamicsWorld.setGravity(Game.gravity);
}

How the input is gotten and physics are updated (SUSPICIOUS CODE IS IN THIS PART):

public static Vector3f gravity = new Vector3f(0, -10, 0); //GRAVITY
private ArrayList<Object> objects; //ALL THE OBJECTS IN THE GAME (CAMERAHOLDER IS IN HERE)

        //GETTING INPUT, USING move() METHOD IN CAMERA CLASS TO MOVE HOLDER.
public void getInput() {

    if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL))
        speedMultiplier = 3;

    if (Keyboard.isKeyDown(Keyboard.KEY_W))
        cam.move(cam.getMoveSpeed() * speedMultiplier, Camera.MOVE_FORWARD);

    if (Keyboard.isKeyDown(Keyboard.KEY_S))
        cam.move(cam.getMoveSpeed() * speedMultiplier, Camera.MOVE_BACKWARD);

    if (Keyboard.isKeyDown(Keyboard.KEY_A))
        cam.move(cam.getMoveSpeed() * speedMultiplier, Camera.MOVE_LEFT);

    if (Keyboard.isKeyDown(Keyboard.KEY_D))
        cam.move(cam.getMoveSpeed() * speedMultiplier, Camera.MOVE_RIGHT);

    cam.carryCamera(); //MOVES THE ACTUAL CAMERA TO THE HOLDER.
    speedMultiplier = 1;

}

public void update() {
    applyJBullet();
}

        //AND JBULLET PHYSICS ARE APPLIED HERE (SUSPICIOUS CODE!!!)
public void applyJBullet(){
Engine.getDynamicsWorld().stepSimulation(1/60.f, 10); //SIMULATES NEXT FRAME

    for (Object o : objects) { 
        if(o.getMass() >= 1){ //ALL THE OBJECTS WITH MASS ARE FOUND

    Transform trans = new Transform();   //CREATING A NEW TRANSFORM
    o.getBody().getMotionState().getWorldTransform(trans); //GET THE SIMULATED LOCATION

//It still doesn't work when I do: "trans.origin.x+=2" here. The same problem occurs.
    o.setPos(trans.origin); //AND SET IT AS THE OBJECTS POSITION
        }   
    }
}

解决方案

I think a better why than just using a box shape is to have a kinematic body. To turn the camera body into a 'kinematic body' (preferable one-way collision, moved by user), call the following:

body.setCollisionFlags(body.ge­tCollisionFlags() | CollisionFlags.KINEMATIC_OBJEC­T);
body.setActivationState(Collis­ionObject.DISABLE_DEACTIVATION­);

这篇关于j支架相机“支架”不移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆