我正在使用jbullet和lwjgl开发java游戏。我目前在使我的相机跟随车辆时遇到了麻烦。这是我的代码。它跟随汽车直到它旋转。这是代码。可以有人告诉我,我做错了什么?!
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FRONT_AND_BACK;
import static org.lwjgl.opengl.GL11.GL_LINE;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glPolygonMode;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glTranslated;
import static org.lwjgl.opengl.GL11.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;
import model.Vehicle;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import utility.LWJGLTimer;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import utility.TerrainLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
import com.bulletphysics.collision.dispatch.CollisionConfiguration;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.CollisionWorld;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.collision.shapes.StaticPlaneShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
public class PlanoFight {
private static LookAtCamera camera;
Vector3f position = new Vector3f(0, 0, 0);
private DynamicsWorld dynamicsWorld = null;
public PlanoFight() {
setUpDisplay();
setUpCamera();
setUpDisplayLists();
setUpPhysics();
initializeGL();
startGameLoop();
}
private void setUpDisplayLists() {
}
Vehicle vehicle;
private void startGameLoop() {
LWJGLTimer timer = new LWJGLTimer();
double delta = 0;
timer.initialize();
while (!Display.isCloseRequested()) {
timer.update();
delta = timer.getElapsedTime();
dynamicsWorld.stepSimulation(1f / 60f, 10);
checkInput();
update(delta);
render();
Display.update();
Display.sync(60);
}
cleanup();
Display.destroy();
System.exit(0);
}
private void cleanup() {
}
private void initializeGL() {
}
private void setUpDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(0);
}
}
private void update(double delta) {
vehicle.update();
}
private void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
vehicle.updateCamera(camera);
camera.setMatrices();
vehicle.render();
}
public static void main(String ar[]) {
new PlanoFight();
}
private static void setUpCamera() {
camera = new LookAtCamera(67, 100f, 0.1f, (float) (Display.getWidth() / Display.getHeight()));
camera.setPosition(new Vector3f(0,5,0));
}
private void checkInput() {
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
vehicle.deacelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
vehicle.accelerate();
} else if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
vehicle.steerLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
vehicle.steerRight();
}
}
private void setUpPhysics() {
BroadphaseInterface bInterface = new DbvtBroadphase();
CollisionConfiguration configuration = new DefaultCollisionConfiguration();
CollisionDispatcher dispather = new CollisionDispatcher(configuration);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
dynamicsWorld = new DiscreteDynamicsWorld(dispather, bInterface, solver, configuration);
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
vehicle=new Vehicle(dynamicsWorld);
}
}
package model;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glMultMatrix;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import static org.lwjgl.opengl.GL11.glRotated;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertex3f;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import javax.vecmath.Vector3f;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.glu.Cylinder;
import utility.LookAtCamera;
import utility.Model;
import utility.OBJLoader;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.CompoundShape;
import com.bulletphysics.collision.shapes.TriangleIndexVertexArray;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.ConstraintSolver;
import com.bulletphysics.dynamics.vehicle.DefaultVehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.RaycastVehicle;
import com.bulletphysics.dynamics.vehicle.VehicleRaycaster;
import com.bulletphysics.dynamics.vehicle.VehicleTuning;
import com.bulletphysics.dynamics.vehicle.WheelInfo;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.util.ObjectArrayList;
public class Vehicle {
private static final int rightIndex = 0;
private static final int upIndex = 1;
private static final int forwardIndex = 2;
private static final Vector3f wheelDirectionCS0 = new Vector3f(0, -1, 0);
private static final Vector3f wheelAxleCS = new Vector3f(-1, 0, 0);
private static float gEngineForce = 0.f;
private static float gBreakingForce = 0.f;
private static float maxEngineForce = 1000.f;// this should be
// engine/velocity dependent
private static float maxBreakingForce = 100.f;
private static float gVehicleSteering = 0.f;
private static float steeringIncrement = 0.04f;
private static float steeringClamp = 0.3f;
private static float wheelRadius = 0.5f;
private static float wheelWidth = 0.4f;
private static float wheelFriction = 1000;// 1e30f;
private static float suspensionStiffness = 20.f;
private static float suspensionDamping = 2.3f;
private static float suspensionCompression = 4.4f;
private static float rollInfluence = 0.1f;// 1.0f;
private static final float suspensionRestLength = 0.6f;
private static final int CUBE_HALF_EXTENTS = 1;
public RigidBody carChassis;
public ObjectArrayList<CollisionShape> collisionShapes = new ObjectArrayList<CollisionShape>();
public BroadphaseInterface overlappingPairCache;
public CollisionDispatcher dispatcher;
public ConstraintSolver constraintSolver;
public DefaultCollisionConfiguration collisionConfiguration;
public TriangleIndexVertexArray indexVertexArrays;
public ByteBuffer vertices;
public VehicleTuning tuning = new VehicleTuning();
public VehicleRaycaster vehicleRayCaster;
public RaycastVehicle vehicle;
public float cameraHeight;
public float minCameraDistance;
public float maxCameraDistance;
private DynamicsWorld dynamicsWorld;
private Cylinder cylinder;
private int carChassisHandle;
Vector3f direction;
public Vehicle(DynamicsWorld world) {
this.dynamicsWorld = world;
carChassis = null;
cameraHeight = 4f;
minCameraDistance = 3f;
maxCameraDistance = 10f;
indexVertexArrays = null;
vertices = null;
vehicle = null;
cylinder = new Cylinder();
direction = new Vector3f(0, 0, -1);
initPhysics();
try {
Model model = OBJLoader.loadModel(new File("res/chassis.obj"));
carChassisHandle = OBJLoader.createDisplayList(model);
} catch (IOException e) {
e.printStackTrace();
}
}
public void initPhysics() {
CollisionShape groundShape = new BoxShape(new Vector3f(50, 3, 50));
collisionShapes.add(groundShape);
Transform tr = new Transform();
tr.setIdentity();
tr.origin.set(0, -4.5f, 0);
localCreateRigidBody(0, tr, groundShape);
CollisionShape chassisShape = new BoxShape(new Vector3f(1.0f, 0.5f, 2.0f));
collisionShapes.add(chassisShape);
CompoundShape compound = new CompoundShape();
collisionShapes.add(compound);
Transform localTrans = new Transform();
localTrans.setIdentity();
localTrans.origin.set(0, 1, 0);
compound.addChildShape(localTrans, chassisShape);
tr.origin.set(0, 0, 0);
carChassis = localCreateRigidBody(800, tr, compound);
Transform t = new Transform();
carChassis.getWorldTransform(t);
Vector3f forward = new Vector3f();
t.basis.getRow(0, forward);
System.out.println("0 " + forward);
t.basis.getRow(1, forward);
System.out.println("1 " + forward);
t.basis.getRow(2, forward);
System.out.println("2 " + forward);
clientResetScene();
// create vehicle
{
vehicleRayCaster = new DefaultVehicleRaycaster(dynamicsWorld);
vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster);
// never deactivate the vehicle
carChassis.setActivationState(CollisionObject.DISABLE_DEACTIVATION);
dynamicsWorld.addVehicle(vehicle);
float connectionHeight = 1.2f;
boolean isFrontWheel = true;
vehicle.setCoordinateSystem(rightIndex, upIndex, forwardIndex);
Vector3f connectionPointCS0 = new Vector3f(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2f * CUBE_HALF_EXTENTS - wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
isFrontWheel = false;
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
connectionPointCS0.set(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2f * CUBE_HALF_EXTENTS + wheelRadius);
vehicle.addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);
for (int i = 0; i < vehicle.getNumWheels(); i++) {
WheelInfo wheel = vehicle.getWheelInfo(i);
wheel.suspensionStiffness = suspensionStiffness;
wheel.wheelsDampingRelaxation = suspensionDamping;
wheel.wheelsDampingCompression = suspensionCompression;
wheel.frictionSlip = wheelFriction;
wheel.rollInfluence = rollInfluence;
}
}
}
public void render() {
float matrix[] = new float[16];
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3f(100, -4.5f, 100);
glVertex3f(100, -4.5f, -100);
glVertex3f(-100, -4.5f, -100);
glVertex3f(-100, -4.5f, 100);
glEnd();
FloatBuffer buffer;
Transform chassisTr = new Transform();
carChassis.getMotionState().getWorldTransform(chassisTr);
CollisionShape chassisShape = carChassis.getCollisionShape();
if (chassisShape instanceof CompoundShape) {
CollisionShape childShape = ((CompoundShape) chassisShape).getChildShape(0);
if (childShape instanceof BoxShape) {
Vector3f size = new Vector3f();
((BoxShape) childShape).getHalfExtentsWithoutMargin(size);
System.out.println(size.x + " " + size.y + " " + size.z);
System.out.println(chassisTr.origin.x + " " + chassisTr.origin.y + " " + chassisTr.origin.z);
}
}
chassisTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(0, 1, 0);
glPushMatrix();
glMultMatrix(buffer);
glTranslatef(0, 1f, 0);
glCallList(carChassisHandle);
glPopMatrix();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
Transform wheelTr = vehicle.getWheelInfo(i).worldTransform;
wheelTr.getOpenGLMatrix(matrix);
buffer = BufferUtils.createFloatBuffer(16 * 4);
buffer.clear();
buffer.put(matrix);
buffer.flip();
glColor3f(1, 0, 0);
glPushMatrix();
glMultMatrix(buffer);
glRotated(90, 0, 1, 0);
cylinder.draw(wheelRadius, wheelRadius, wheelWidth, 10, 10);
glPopMatrix();
}
}
public void update() {
int wheelIndex = 2;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 3;
vehicle.applyEngineForce(gEngineForce, wheelIndex);
vehicle.setBrake(gBreakingForce, wheelIndex);
wheelIndex = 0;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
wheelIndex = 1;
vehicle.setSteeringValue(gVehicleSteering, wheelIndex);
}
public void clientResetScene() {
gVehicleSteering = 0f;
Transform tr = new Transform();
tr.setIdentity();
carChassis.setCenterOfMassTransform(tr);
carChassis.setLinearVelocity(new Vector3f(0, 0, 0));
carChassis.setAngularVelocity(new Vector3f(0, 0, 0));
dynamicsWorld.getBroadphase().getOverlappingPairCache().cleanProxyFromPairs(carChassis.getBroadphaseHandle(), dynamicsWorld.getDispatcher());
if (vehicle != null) {
vehicle.resetSuspension();
for (int i = 0; i < vehicle.getNumWheels(); i++) {
vehicle.updateWheelTransform(i, true);
}
}
}
public void steerLeft() {
System.out.println("steer left");
gVehicleSteering += steeringIncrement;
if (gVehicleSteering > steeringIncrement) {
gVehicleSteering = steeringClamp;
}
}
public void steerRight() {
gVehicleSteering -= steeringIncrement;
if (gVehicleSteering < -steeringClamp)
gVehicleSteering = -steeringClamp;
}
public void accelerate() {
gEngineForce = maxEngineForce;
gBreakingForce = 0.0f;
}
public void deacelerate() {
gBreakingForce = maxBreakingForce;
gEngineForce = 0.0f;
}
public void updateCamera(LookAtCamera camera) {
Transform chassisWorldTrans = new Transform();
carChassis.getMotionState().getWorldTransform(chassisWorldTrans);
Transform characterWorldTrans = chassisWorldTrans;
Vector3f up = new Vector3f();
characterWorldTrans.basis.getRow(1, up);
Vector3f backward = new Vector3f();
characterWorldTrans.basis.getRow(2, backward);
backward.scale(-1);
up.normalize();
backward.normalize();
camera.lookAtVector.set(characterWorldTrans.origin);
Vector3f cameraPosition = new Vector3f(camera.lookAtVector.x,camera.lookAtVector.y,camera.lookAtVector.z);
up.scale(4);
cameraPosition.add(up);
backward.scale(8);
cameraPosition.add(backward);
// System.out.println("lookat" + camera.lookAtVector);
// System.out.println("position " + cameraPosition + " angle " + cameraPosition.angle(camera.lookAtVector));
// System.out.println(" " + backward + " " + up);
camera.position.set(cameraPosition);
}
public RigidBody localCreateRigidBody(float mass, Transform startTransform, CollisionShape shape) {
boolean isDynamic = (mass != 0f);
Vector3f localInertia = new Vector3f(0f, 0f, 0f);
if (isDynamic) {
shape.calculateLocalInertia(mass, localInertia);
}
DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
RigidBody body = new RigidBody(cInfo);
dynamicsWorld.addRigidBody(body);
return body;
}
public void printVector(Vector3f origin) {
System.out.println(origin.x + " " + origin.y + " " + origin.z);
}
}