dommstyle.txt
来自「Simple DOOM style navigation of a 3D sce」· 文本 代码 · 共 1,957 行 · 第 1/4 页
TXT
1,957 行
private void moveLeft() {
doMove(new Vector3d(-getMovementRate(), 0.0, 0.0));
}
private void moveRight() {
doMove(new Vector3d(getMovementRate(), 0.0, 0.0));
}
private void moveUp() {
doMove(new Vector3d(0.0, getMovementRate(), 0.0));
}
private void moveDown() {
doMove(new Vector3d(0.0, -getMovementRate(), 0.0));
}
protected void rotRight() {
doRotateY(getRotateRightAmount());
}
protected void rotUp() {
doRotateX(getRotateUpAmount());
}
protected void rotLeft() {
doRotateY(getRotateLeftAmount());
}
protected void rotDown() {
doRotateX(getRotateDownAmount());
}
protected void rollLeft() {
doRotateZ(getRollLeftAmount());
}
protected void rollRight() {
doRotateZ(getRollRightAmount());
}
protected void updateTransform() {
transformGroup.setTransform(transform3D);
}
protected void doRotateY(double radians) {
transformGroup.getTransform(transform3D);
Transform3D toMove = new Transform3D();
toMove.rotY(radians);
transform3D.mul(toMove);
updateTransform();
}
protected void doRotateX(double radians) {
transformGroup.getTransform(transform3D);
Transform3D toMove = new Transform3D();
toMove.rotX(radians);
transform3D.mul(toMove);
updateTransform();
}
protected void doRotateZ(double radians) {
transformGroup.getTransform(transform3D);
Transform3D toMove = new Transform3D();
toMove.rotZ(radians);
transform3D.mul(toMove);
updateTransform();
}
protected void doMove(Vector3d theMove) {
transformGroup.getTransform(transform3D);
Transform3D toMove = new Transform3D();
toMove.setTranslation(theMove);
transform3D.mul(toMove);
updateTransform();
}
protected double getMovementRate() {
return moveRate * speed;
}
protected double getRollLeftAmount() {
return rotateZAmount * speed;
}
protected double getRollRightAmount() {
return -rotateZAmount * speed;
}
protected double getRotateUpAmount() {
return rotateYAmount * speed;
}
protected double getRotateDownAmount() {
return -rotateYAmount * speed;
}
protected double getRotateLeftAmount() {
return rotateYAmount * speed;
}
protected double getRotateRightAmount() {
return -rotateYAmount * speed;
}
public void setRotateXAmount(double radians) {
rotateXAmount = radians;
}
public void setRotateYAmount(double radians) {
rotateYAmount = radians;
}
public void setRotateZAmount(double radians) {
rotateZAmount = radians;
}
public void setMovementRate(double meters) {
moveRate = meters; // Travel rate in meters/frame
}
public void setForwardKey(int key) {
forwardKey = key;
}
public void setBackKey(int key) {
backKey = key;
}
public void setLeftKey(int key) {
leftKey = key;
}
}
//creates a 2x2x2 cuboid with its base at y=0
class Cuboid extends ComplexObject {
public Cuboid(Component comp, Group g, int nFlags) {
super(comp, g, nFlags);
}
protected Group createGeometryGroup(Appearance app, Vector3d position,
Vector3d scale, String szTextureFile, String szSoundFile) {
int nFlags = GeometryArray.COORDINATES | GeometryArray.NORMALS;
if ((m_nFlags & TEXTURE) == TEXTURE)
nFlags |= GeometryArray.TEXTURE_COORDINATE_2;
QuadArray quadArray = new QuadArray(24, nFlags);
quadArray.setCoordinates(0, verts, 0, 24);
for (int n = 0; n < 24; n++)
quadArray.setNormal(n, normals[n / 4]);
if ((m_nFlags & TEXTURE) == TEXTURE) {
quadArray.setTextureCoordinates(0, 0, tcoords, 0, 24);
setTexture(app, szTextureFile);
}
Shape3D shape = new Shape3D(quadArray, app);
BranchGroup bg = new BranchGroup();
bg.addChild(shape);
return bg;
}
private static final float[] verts = {
// front face
1.0f, 0.0f, 1.0f, 1.0f, 2.0f, 1.0f, -1.0f, 2.0f, 1.0f, -1.0f, 0.0f,
1.0f,
// back face
-1.0f, 0.0f, -1.0f, -1.0f, 2.0f, -1.0f, 1.0f, 2.0f, -1.0f, 1.0f,
0.0f, -1.0f,
// right face
1.0f, 0.0f, -1.0f, 1.0f, 2.0f, -1.0f, 1.0f, 2.0f, 1.0f, 1.0f, 0.0f,
1.0f,
// left face
-1.0f, 0.0f, 1.0f, -1.0f, 2.0f, 1.0f, -1.0f, 2.0f, -1.0f, -1.0f,
0.0f, -1.0f,
// top face
1.0f, 2.0f, 1.0f, 1.0f, 2.0f, -1.0f, -1.0f, 2.0f, -1.0f, -1.0f,
2.0f, 1.0f,
// bottom face
-1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f,
0.0f, 1.0f, };
private static final float[] tcoords = {
// front
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// back
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
//right
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// left
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// top
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// bottom
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
private static final Vector3f[] normals = { new Vector3f(0.0f, 0.0f, 1.0f), // front
// face
new Vector3f(0.0f, 0.0f, -1.0f), // back face
new Vector3f(1.0f, 0.0f, 0.0f), // right face
new Vector3f(-1.0f, 0.0f, 0.0f), // left face
new Vector3f(0.0f, 1.0f, 0.0f), // top face
new Vector3f(0.0f, -1.0f, 0.0f), // bottom face
};
}
//*****************************************************************************
/**
* Utils
*
* @author Daniel Selman
* @version 1.0
*/
//*****************************************************************************
class Utils {
// convert an angular rotation about an axis to a Quaternion
static Quat4f createQuaternionFromAxisAndAngle(Vector3d axis, double angle) {
double sin_a = Math.sin(angle / 2);
double cos_a = Math.cos(angle / 2);
// use a vector so we can call normalize
Vector4f q = new Vector4f();
q.x = (float) (axis.x * sin_a);
q.y = (float) (axis.y * sin_a);
q.z = (float) (axis.z * sin_a);
q.w = (float) cos_a;
// It is necessary to normalise the quaternion
// in case any values are very close to zero.
q.normalize();
// convert to a Quat4f and return
return new Quat4f(q);
}
// convert three rotations about the Euler axes to a Quaternion
static Quat4f createQuaternionFromEuler(double angleX, double angleY,
double angleZ) {
// simply call createQuaternionFromAxisAndAngle
// for each axis and multiply the results
Quat4f qx = createQuaternionFromAxisAndAngle(new Vector3d(1, 0, 0),
angleX);
Quat4f qy = createQuaternionFromAxisAndAngle(new Vector3d(0, 1, 0),
angleY);
Quat4f qz = createQuaternionFromAxisAndAngle(new Vector3d(0, 0, 1),
angleZ);
// qx = qx * qy
qx.mul(qy);
// qx = qx * qz
qx.mul(qz);
return qx;
}
static public double getRandomNumber(double basis, double random) {
return basis + ((float) Math.random() * random * 2f) - (random);
}
static public double getRandomNumber(double basis, double random,
double scale) {
double value = basis + ((float) Math.random() * random * 2f) - (random);
return value * scale;
}
static public StringBuffer readFile(URL urlFile) {
/* allocate a temporary buffer to store the input file*/
StringBuffer szBufferData = new StringBuffer();
Vector keyFramesVector = new Vector();
try {
InputStream inputStream = urlFile.openStream();
int nChar = 0;
// read the entire file into the StringBuffer
while (true) {
nChar = inputStream.read();
/* if we have not hit the end of file
add the character to the StringBuffer
*/
if (nChar != -1)
szBufferData.append((char) nChar);
else
// EOF
break;
}
inputStream.close();
} catch (Exception e) {
System.err.println(e.toString());
return null;
}
return szBufferData;
}
static public RotPosScaleTCBSplinePathInterpolator createSplinePathInterpolator(
Alpha alpha, TransformGroup tg, Transform3D axis, URL urlKeyframes) {
TCBKeyFrame[] keyFrames = readKeyFrames(urlKeyframes);
if (keyFrames != null)
return new RotPosScaleTCBSplinePathInterpolator(alpha, tg, axis,
keyFrames);
return null;
}
static public TCBKeyFrame[] readKeyFrames(URL urlKeyframes) {
StringBuffer szBufferData = readFile(urlKeyframes);
if (szBufferData == null)
return null;
Vector keyFramesVector = new Vector();
// create a tokenizer to tokenize the input file at whitespace
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
szBufferData.toString());
// each keyframe is defined as follows
// - knot (0 >= k <= 1)
// - position (x,y,z)
// - rotation (rx,ry,rz)
// - scale (x,y,z)
// - tension (-1 >= t <= 1)
// - continuity (-1 >= c <= 1)
// - bias (-1 >= b <= 1)
// - linear (int - 0 or 1)
while (true) {
try {
float knot = Float.parseFloat(tokenizer.nextToken());
float posX = Float.parseFloat(tokenizer.nextToken());
float posY = Float.parseFloat(tokenizer.nextToken());
float posZ = Float.parseFloat(tokenizer.nextToken());
float rotX = Float.parseFloat(tokenizer.nextToken());
float rotY = Float.parseFloat(tokenizer.nextToken());
float rotZ = Float.parseFloat(tokenizer.nextToken());
float scaleX = Float.parseFloat(tokenizer.nextToken());
float scaleY = Float.parseFloat(tokenizer.nextToken());
float scaleZ = Float.parseFloat(tokenizer.nextToken());
float tension = Float.parseFloat(tokenizer.nextToken());
float continuity = Float.parseFloat(tokenizer.nextToken());
float bias = Float.parseFloat(tokenizer.nextToken());
int linear = Integer.parseInt(tokenizer.nextToken());
TCBKeyFrame keyframe = new TCBKeyFrame(knot, linear,
new Point3f(posX, posY, posZ),
createQuaternionFromEuler(rotX, rotY, rotZ),
new Point3f(scaleX, scaleY, scaleZ), tension,
continuity, bias);
keyFramesVector.add(keyframe);
} catch (Exception e) {
break;
}
}
// create the return structure and populate
TCBKeyFrame[] keysReturn = new TCBKeyFrame[keyFramesVector.size()];
for (int n = 0; n < keysReturn.length; n++)
keysReturn[n] = (TCBKeyFrame) keyFramesVector.get(n);
// return the array
return keysReturn;
}
}
class Land extends ComplexObject {
public static final float WIDTH = 1.0f;
public static final float LENGTH = 1.0f;
public static final float HEIGHT = 0.0f;
public Land(Component comp, Group g, int nFlags) {
super(comp, g, nFlags);
}
protected Group createGeometryGroup(Appearance app, Vector3d position,
Vector3d scale, String szTextureFile, String szSoundFile) {
int nFlags = GeometryArray.COORDINATES | GeometryArray.NORMALS;
if ((m_nFlags & TEXTURE) == TEXTURE)
nFlags |= GeometryArray.TEXTURE_COORDINATE_2;
QuadArray quadArray = new QuadArray(4, nFlags);
float[] coordArray = { -WIDTH, HEIGHT, LENGTH, WIDTH, HEIGHT, LENGTH,
WIDTH, HEIGHT, -LENGTH, -WIDTH, HEIGHT, -LENGTH };
quadArray.setCoordinates(0, coordArray, 0, coordArray.length / 3);
for (int n = 0; n < coordArray.length / 3; n++)
quadArray.setNormal(n, new Vector3f(0, 1, 0));
if ((m_nFlags & TEXTURE) == TEXTURE) {
float[] texArray = { 0, 0, 1, 0, 1, 1, 0, 1 };
quadArray.setTextureCoordinates(0, 0, texArray, 0,
coordArray.length / 3);
setTexture(app, szTextureFile);
}
BranchGroup bg = new BranchGroup();
Shape3D shape = new Shape3D(quadArray, app);
bg.addChild(shape);
return bg;
}
}
/**
* This class is a simple behavior that invokes the KeyNavigator to modify the
* view platform transform.
*/
class CollisionBehavior extends Behavior {
private WakeupOnCollisionEntry wakeupOne = null;
private WakeupOnCollisionExit wakeupTwo = null;
private WakeupCriterion[] wakeupArray = new WakeupCriterion[2];
private WakeupCondition wakeupCondition = null;
private ComplexObject m_Owner = null;
public CollisionBehavior(Node node, ComplexObject owner) {
wakeupOne = new WakeupOnCollisionEntry(node,
WakeupOnCollisionEntry.USE_GEOMETRY);
wakeupTwo = new WakeupOnCollisionExit(node,
WakeupOnCollisionExit.USE_GEOMETRY);
wakeupArray[0] = wakeupOne;
wakeupArray[1] = wakeupTwo;
wakeupCondition = new WakeupOr(wakeupArray);
m_Owner = owner;
}
/**
* Override Behavior's initialize method to setup wakeup criteria.
*/
public void initialize() {
// Establish initial wakeup criteria
wakeupOn(wakeupCondition);
}
/**
* Override Behavior's stimulus method to handle the event.
*/
public void processStimulus(Enumeration criteria) {
WakeupCriterion genericEvt;
while (criteria.hasMoreElements()) {
genericEvt = (WakeupCriterion) criteria.nextElement();
if (genericEvt instanceof WakeupOnCollisionEntry) {
m_Owner.onCollide(true);
} else if (genericEvt instanceof WakeupOnCollisionExit) {
m_Owner.onCollide(false);
}
}
// Set wakeup criteria for next time
wakeupOn(wakeupCondition);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?