summaryrefslogtreecommitdiff
path: root/src/common/CollidableObject.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/CollidableObject.java')
-rw-r--r--src/common/CollidableObject.java813
1 files changed, 393 insertions, 420 deletions
diff --git a/src/common/CollidableObject.java b/src/common/CollidableObject.java
index b048cd9..0549335 100644
--- a/src/common/CollidableObject.java
+++ b/src/common/CollidableObject.java
@@ -1,40 +1,19 @@
-package common;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-
-import javax.media.j3d.Appearance;
-import javax.media.j3d.Bounds;
-import javax.media.j3d.BranchGroup;
-import javax.media.j3d.ColoringAttributes;
-import javax.media.j3d.Geometry;
-import javax.media.j3d.GeometryArray;
-import javax.media.j3d.Group;
-import javax.media.j3d.IndexedTriangleArray;
-import javax.media.j3d.Material;
-import javax.media.j3d.Node;
-import javax.media.j3d.PolygonAttributes;
-import javax.media.j3d.Shape3D;
-import javax.media.j3d.Transform3D;
-import javax.media.j3d.TransformGroup;
-import javax.media.j3d.TransparencyAttributes;
-import javax.vecmath.Color3f;
-import javax.vecmath.Matrix3f;
-import javax.vecmath.Matrix4f;
-import javax.vecmath.Point3f;
-import javax.vecmath.Quat4f;
-import javax.vecmath.Vector3f;
-
-import com.sun.j3d.utils.geometry.GeometryInfo;
-import com.sun.j3d.utils.geometry.Primitive;
-
-@SuppressWarnings("restriction")
-public abstract class CollidableObject implements Serializable {
- private static final long serialVersionUID = 3667108226485766929L;
+package common;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+import com.sun.j3d.utils.geometry.GeometryInfo;
+import com.sun.j3d.utils.geometry.Primitive;
+
+@SuppressWarnings("restriction")
+public abstract class CollidableObject implements Serializable {
+ private static final long serialVersionUID = 3667108226485766929L;
protected float inverseMass;
// The center of mass in the local coordinate system
protected Vector3f centerOfMass;
@@ -43,11 +22,13 @@ public abstract class CollidableObject implements Serializable {
protected Vector3f forceAccumulator;
protected Quat4f orientation;
protected Vector3f angularVelocity;
+ protected Vector3f previousRotationalVelocity;
protected Vector3f torqueAccumulator;
protected Matrix3f inverseInertiaTensor;
protected float coefficientOfRestitution;
protected float penetrationCorrection;
protected float dynamicFriction;
+ protected float rotationalFriction;
transient protected BranchGroup BG;
transient protected TransformGroup TG;
transient protected Node node;
@@ -56,34 +37,36 @@ public abstract class CollidableObject implements Serializable {
transient private Bounds boundsCache;
// The inverse inertia tensor in world coordinates
transient private Matrix3f inverseInertiaTensorCache;
-
- /**
- * Copy Constructor
- * @param The CollidableObject to copy.
- */
- protected CollidableObject(CollidableObject o) {
- inverseMass = o.inverseMass;
- centerOfMass = o.centerOfMass;
- position = o.position;
- previousPosition = o.previousPosition;
- velocity = o.velocity;
- previousVelocity = o.previousVelocity;
- forceAccumulator = o.forceAccumulator;
- orientation = o.orientation;
- angularVelocity = o.angularVelocity;
- torqueAccumulator = o.torqueAccumulator;
- inverseInertiaTensor = o.inverseInertiaTensor;
- coefficientOfRestitution = o.coefficientOfRestitution;
- penetrationCorrection = o.penetrationCorrection;
- dynamicFriction = o.dynamicFriction;
- BG = o.BG;
- TG = o.TG;
- node = o.node;
- vertexCache = o.vertexCache;
- triangleCache = o.triangleCache;
- boundsCache = o.boundsCache;
- inverseInertiaTensorCache = o.inverseInertiaTensorCache;
- }
+
+ /**
+ * Copy Constructor
+ * @param The CollidableObject to copy.
+ */
+ protected CollidableObject(CollidableObject o) {
+ inverseMass = o.inverseMass;
+ centerOfMass = o.centerOfMass;
+ position = o.position;
+ previousPosition = o.previousPosition;
+ velocity = o.velocity;
+ previousVelocity = o.previousVelocity;
+ forceAccumulator = o.forceAccumulator;
+ orientation = o.orientation;
+ angularVelocity = o.angularVelocity;
+ previousRotationalVelocity = o.previousRotationalVelocity;
+ torqueAccumulator = o.torqueAccumulator;
+ inverseInertiaTensor = o.inverseInertiaTensor;
+ coefficientOfRestitution = o.coefficientOfRestitution;
+ penetrationCorrection = o.penetrationCorrection;
+ dynamicFriction = o.dynamicFriction;
+ rotationalFriction = o.rotationalFriction;
+ BG = o.BG;
+ TG = o.TG;
+ node = o.node;
+ vertexCache = o.vertexCache;
+ triangleCache = o.triangleCache;
+ boundsCache = o.boundsCache;
+ inverseInertiaTensorCache = o.inverseInertiaTensorCache;
+ }
public CollidableObject() {
this(1);
@@ -101,15 +84,15 @@ public abstract class CollidableObject implements Serializable {
forceAccumulator = new Vector3f();
orientation = new Quat4f(0, 0, 0, 1);
angularVelocity = new Vector3f();
+ previousRotationalVelocity = new Vector3f();
torqueAccumulator = new Vector3f();
inverseInertiaTensor = new Matrix3f();
- coefficientOfRestitution = 0.85f;
+ coefficientOfRestitution = 0.75f;
penetrationCorrection = 1.05f;
- dynamicFriction = 0.04f;
+ dynamicFriction = 0.02f;
+ rotationalFriction = 0.05f;
TG = new TransformGroup();
TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
- TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
- TG.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
BG = new BranchGroup();
BG.setCapability(BranchGroup.ALLOW_DETACH);
BG.addChild(TG);
@@ -128,17 +111,8 @@ public abstract class CollidableObject implements Serializable {
public void detach() {
BG.detach();
}
-
- //ADDED
- private void updatePositionAndOrientation() {
- Transform3D tmpTransform = new Transform3D();
- TG.getTransform(tmpTransform);
- tmpTransform.get(orientation, position);
- }
- //ADDED
public void updateState(float duration) {
- updatePositionAndOrientation(); //ADDED
previousPosition.set(position);
previousVelocity.set(velocity);
// The force vector now becomes the acceleration vector.
@@ -212,51 +186,58 @@ public abstract class CollidableObject implements Serializable {
triangleCache = null;
boundsCache = null;
inverseInertiaTensorCache = null;
- }
-
- public void resolveCollisions(CollidableObject other) {
- resolveCollisions(other, CollisionDetector.calculateCollisions(this, other));
}
- public void resolveCollisions(CollidableObject other, ArrayList<CollisionInfo> collisions) {
- if (collisions.isEmpty())
- return;
-
- CollisionInfo finalCollision = null;
- float max = Float.NEGATIVE_INFINITY;
- int count = 0;
- for (CollisionInfo collision : collisions) {
- Vector3f thisRelativeContactPosition = new Vector3f();
- thisRelativeContactPosition.scaleAdd(-1, position, collision.contactPoint);
- thisRelativeContactPosition.scaleAdd(-1, centerOfMass, thisRelativeContactPosition);
- Vector3f thisContactVelocity = new Vector3f();
- thisContactVelocity.cross(angularVelocity, thisRelativeContactPosition);
- thisContactVelocity.add(previousVelocity);
- Vector3f otherRelativeContactPosition = new Vector3f();
- otherRelativeContactPosition.scaleAdd(-1, other.position, collision.contactPoint);
- otherRelativeContactPosition.scaleAdd(-1, other.centerOfMass, otherRelativeContactPosition);
- Vector3f otherContactVelocity = new Vector3f();
- otherContactVelocity.cross(other.angularVelocity, otherRelativeContactPosition);
- otherContactVelocity.add(other.previousVelocity);
- float speed = collision.contactNormal.dot(thisContactVelocity) - collision.contactNormal.dot(otherContactVelocity);
- if (speed > 0)
- if (speed > max + CollisionDetector.EPSILON) {
- finalCollision = collision;
- max = speed;
- count = 1;
- } else if (speed >= max - CollisionDetector.EPSILON) {
- finalCollision.contactPoint.add(collision.contactPoint);
- finalCollision.penetration += collision.penetration;
- count++;
- }
- }
- if (finalCollision != null) {
- finalCollision.contactPoint.scale(1f / count);
- finalCollision.penetration /= count;
- resolveCollision(other, finalCollision);
- updateTransformGroup();
- other.updateTransformGroup();
- }
+ //Alden mar4 change
+ public void resolveCollisions(CollidableObject other) {
+ resolveCollisions(other, CollisionDetector.calculateCollisions(this, other));
+ }
+
+ /*public void resolveCollisions(CollidableObject other) {
+ ArrayList<CollisionInfo> collisions = CollisionDetector.calculateCollisions(this, other);
+ if (collisions.isEmpty())
+ return;
+ */
+ //Alden mar4 change
+ public void resolveCollisions(CollidableObject other, ArrayList<CollisionInfo> collisions) {
+ if (collisions.isEmpty())
+ return;
+
+ CollisionInfo finalCollision = null;
+ float max = Float.NEGATIVE_INFINITY;
+ int count = 0;
+ for (CollisionInfo collision : collisions) {
+ Vector3f thisRelativeContactPosition = new Vector3f();
+ thisRelativeContactPosition.scaleAdd(-1, position, collision.contactPoint);
+ thisRelativeContactPosition.scaleAdd(-1, centerOfMass, thisRelativeContactPosition);
+ Vector3f thisContactVelocity = new Vector3f();
+ thisContactVelocity.cross(angularVelocity, thisRelativeContactPosition);
+ thisContactVelocity.add(previousVelocity);
+ Vector3f otherRelativeContactPosition = new Vector3f();
+ otherRelativeContactPosition.scaleAdd(-1, other.position, collision.contactPoint);
+ otherRelativeContactPosition.scaleAdd(-1, other.centerOfMass, otherRelativeContactPosition);
+ Vector3f otherContactVelocity = new Vector3f();
+ otherContactVelocity.cross(other.angularVelocity, otherRelativeContactPosition);
+ otherContactVelocity.add(other.previousVelocity);
+ float speed = collision.contactNormal.dot(thisContactVelocity) - collision.contactNormal.dot(otherContactVelocity);
+ if (speed > 0)
+ if (speed > max + CollisionDetector.EPSILON) {
+ finalCollision = collision;
+ max = speed;
+ count = 1;
+ } else if (speed >= max - CollisionDetector.EPSILON) {
+ finalCollision.contactPoint.add(collision.contactPoint);
+ finalCollision.penetration += collision.penetration;
+ count++;
+ }
+ }
+ if (finalCollision != null) {
+ finalCollision.contactPoint.scale(1f / count);
+ finalCollision.penetration /= count;
+ resolveCollision(other, finalCollision);
+ updateTransformGroup();
+ other.updateTransformGroup();
+ }
}
public void resolveCollision(CollidableObject other, CollisionInfo ci) {
@@ -266,13 +247,15 @@ public abstract class CollidableObject implements Serializable {
Vector3f thisRelativeContactPosition = new Vector3f();
thisRelativeContactPosition.scaleAdd(-1, position, ci.contactPoint);
thisRelativeContactPosition.scaleAdd(-1, centerOfMass, thisRelativeContactPosition);
- Vector3f thisContactVelocity = new Vector3f();
- thisContactVelocity.cross(angularVelocity, thisRelativeContactPosition);
- thisContactVelocity.add(previousVelocity);
Vector3f otherRelativeContactPosition = new Vector3f();
otherRelativeContactPosition.scaleAdd(-1, other.position, ci.contactPoint);
otherRelativeContactPosition.scaleAdd(-1, other.centerOfMass, otherRelativeContactPosition);
+
+ Vector3f thisContactVelocity = new Vector3f();
+ thisContactVelocity.cross(angularVelocity, thisRelativeContactPosition);
+ thisContactVelocity.add(previousVelocity);
+
Vector3f otherContactVelocity = new Vector3f();
otherContactVelocity.cross(other.angularVelocity, otherRelativeContactPosition);
otherContactVelocity.add(other.previousVelocity);
@@ -284,6 +267,27 @@ public abstract class CollidableObject implements Serializable {
if (totalInverseMass == 0)
return;
+ /* Dynamic Friction */
+ if (dynamicFriction > 0) {
+ Vector3f acceleration = new Vector3f();
+ Vector3f perpVelocity = new Vector3f();
+ float contactSpeed = ci.contactNormal.dot(velocity) - ci.contactNormal.dot(other.velocity);
+
+ perpVelocity.scaleAdd(-contactSpeed, ci.contactNormal, previousVelocity);
+ if (perpVelocity.length() > 0) {
+ perpVelocity.normalize();
+ acceleration.scaleAdd(-1, previousVelocity, velocity);
+ velocity.scaleAdd(dynamicFriction * acceleration.dot(ci.contactNormal), perpVelocity, velocity);
+ }
+
+ perpVelocity.scaleAdd(contactSpeed, ci.contactNormal, other.previousVelocity);
+ if (perpVelocity.length() > 0) {
+ perpVelocity.normalize();
+ acceleration.scaleAdd(-1, other.previousVelocity, other.velocity);
+ other.velocity.scaleAdd(dynamicFriction * acceleration.dot(ci.contactNormal), perpVelocity, other.velocity);
+ }
+ }
+
Vector3f thisMovementUnit = new Vector3f();
thisMovementUnit.cross(thisRelativeContactPosition, ci.contactNormal);
getInverseInertiaTensor().transform(thisMovementUnit);
@@ -300,18 +304,12 @@ public abstract class CollidableObject implements Serializable {
Vector3f impulse = new Vector3f(ci.contactNormal);
impulse.scale(deltaClosingSpeed / totalInverseMass);
-
- //Added
- Vector3f frictionalImpulse = new Vector3f();
- frictionalImpulse.scale(dynamicFriction); //not considering the time of impact
- //end-added
-
+
velocity.scaleAdd(inverseMass, impulse, velocity);
Vector3f tmp = new Vector3f();
tmp.cross(thisRelativeContactPosition, impulse);
getInverseInertiaTensor().transform(tmp);
angularVelocity.add(tmp);
-
position.scaleAdd(-ci.penetration * penetrationCorrection * inverseMass / totalInverseMass, ci.contactNormal, position);
thisMovementUnit.scale(-ci.penetration * penetrationCorrection / totalInverseMass);
UnQuat4f tmp2 = new UnQuat4f(thisMovementUnit.x, thisMovementUnit.y, thisMovementUnit.z, 0);
@@ -322,10 +320,6 @@ public abstract class CollidableObject implements Serializable {
impulse.negate();
other.velocity.scaleAdd(other.inverseMass, impulse, other.velocity);
- //Added
- other.velocity.scaleAdd(other.inverseMass, frictionalImpulse, other.velocity);
- impulse.add(frictionalImpulse);
- //End-added
tmp.cross(otherRelativeContactPosition, impulse);
other.getInverseInertiaTensor().transform(tmp);
other.angularVelocity.add(tmp);
@@ -336,291 +330,270 @@ public abstract class CollidableObject implements Serializable {
tmp2.mul(other.orientation);
other.orientation.add(tmp2);
other.orientation.normalize();
+
+ if (rotationalFriction > 0) {
+ /* Rotational Friction */
+ Vector3f w = new Vector3f();
+
+ /*float radius = thisRelativeContactPosition.length();
+ w.cross(angularVelocity, ci.contactNormal);
+ velocity.scaleAdd(-1, previousRotationalVelocity, velocity);
+ previousRotationalVelocity.scale(radius, w);
+ velocity.scaleAdd(radius, w, velocity);
+ w.cross(previousRotationalVelocity, ci.contactNormal);
+ angularVelocity.scaleAdd(-0.5f * w.dot(angularVelocity), w, angularVelocity);
+
+ radius = otherRelativeContactPosition.length();
+ w.cross(other.angularVelocity, ci.contactNormal);
+ other.velocity.scaleAdd(-1, other.previousRotationalVelocity, other.velocity);
+ other.previousRotationalVelocity.scale(radius, w);
+ other.velocity.scaleAdd(radius , w, other.velocity);
+ w.cross(other.previousRotationalVelocity, ci.contactNormal);
+ other.angularVelocity.scaleAdd(-0.5f * w.dot(other.angularVelocity), w, other.angularVelocity);
+ */
+
+ angularVelocity.scaleAdd(-rotationalFriction * ci.contactNormal.dot(angularVelocity), ci.contactNormal, angularVelocity);
+ other.angularVelocity.scaleAdd(-rotationalFriction * ci.contactNormal.dot(other.angularVelocity), ci.contactNormal, other.angularVelocity);
+
+ }
}
- /*
- private float getMomentofInertia(Matrix3f inverseInertiaTensor2, Vector3f torque) {
- Vector3f tmp = new Vector3f(torque);
- tmp.scale(1/torque.length());
- inverseInertiaTensor2.transform(tmp);
- float inertia = tmp.dot(tmp);
- return inertia;
+
+ private static final int NODE_TYPE_BRANCH = 1;
+ private static final int NODE_TYPE_TRANSFORM = 2;
+ private static final int NODE_TYPE_PRIMITIVE = 3;
+ private static final int NODE_TYPE_SHAPE = 4;
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ writeObject(out, node);
+ }
+
+ private static void writeObject(ObjectOutputStream out, Node node) throws IOException {
+ if (node instanceof BranchGroup) {
+ out.writeInt(NODE_TYPE_BRANCH);
+ out.writeInt(((BranchGroup) node).numChildren());
+ for (int i = 0; i < ((BranchGroup) node).numChildren(); i++) {
+ Node childNode = ((BranchGroup) node).getChild(i);
+ writeObject(out, childNode);
+ }
+ } else if (node instanceof TransformGroup) {
+ out.writeInt(NODE_TYPE_TRANSFORM);
+ Transform3D tgT = new Transform3D();
+ Matrix4f matrix = new Matrix4f();
+ ((TransformGroup) node).getTransform(tgT);
+ tgT.get(matrix);
+ out.writeObject(matrix);
+ out.writeInt(((TransformGroup) node).numChildren());
+ for (int i = 0; i < ((TransformGroup) node).numChildren(); i++) {
+ Node childNode = ((TransformGroup) node).getChild(i);
+ writeObject(out, childNode);
+ }
+ } else if (node instanceof Primitive) {
+ out.writeInt(NODE_TYPE_PRIMITIVE);
+ Primitive prim = (Primitive)node;
+ int index = 0;
+ Shape3D shape;
+ out.writeInt(prim.numChildren());
+ while ((shape = prim.getShape(index++)) != null) {
+ Appearance appearance = shape.getAppearance();
+ if (appearance != null) {
+ out.writeBoolean(true);
+ writeObject(out, appearance);
+ } else
+ out.writeBoolean(false);
+ out.writeInt(shape.numGeometries());
+ for (int i = 0; i < shape.numGeometries(); i++)
+ writeObject(out, shape.getGeometry(i));
+ }
+
+ } else if (node instanceof Shape3D) {
+ out.writeInt(NODE_TYPE_SHAPE);
+ Shape3D shape = (Shape3D) node;
+ Appearance appearance = shape.getAppearance();
+ if (appearance != null) {
+ out.writeBoolean(true);
+ writeObject(out, appearance);
+ } else
+ out.writeBoolean(false);
+ out.writeInt(shape.numGeometries());
+ for (int i = 0; i < shape.numGeometries(); i++)
+ writeObject(out, shape.getGeometry(i));
+
+ } else
+ throw new IllegalArgumentException("Illegal node type for serialization");
+ }
+
+ private static void writeObject(ObjectOutputStream out, Geometry geometry) throws IOException {
+ GeometryInfo gi = new GeometryInfo((GeometryArray)geometry);
+ gi.convertToIndexedTriangles();
+ geometry = gi.getIndexedGeometryArray();
+ IndexedTriangleArray trueGeometry = (IndexedTriangleArray)geometry;
+
+ int format = trueGeometry.getVertexFormat() & (IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS);
+ out.writeInt(format);
+ Point3f vertices[] = new Point3f[trueGeometry.getValidVertexCount()];
+ for (int i = 0; i < vertices.length; i++) {
+ vertices[i] = new Point3f();
+ trueGeometry.getCoordinate(i, vertices[i]);
+ }
+ out.writeObject(vertices);
+ int indices[] = new int[trueGeometry.getValidIndexCount()];
+ trueGeometry.getCoordinateIndices(0, indices);
+ out.writeObject(indices);
+
+ if ((format & IndexedTriangleArray.NORMALS) != 0) {
+ Vector3f normals[] = new Vector3f[trueGeometry.getValidVertexCount()];
+ for (int i = 0; i < normals.length; i++) {
+ normals[i] = new Vector3f();
+ trueGeometry.getNormal(i, normals[i]);
+ }
+ out.writeObject(normals);
+ indices = new int[trueGeometry.getValidIndexCount()];
+ trueGeometry.getNormalIndices(0, indices);
+ out.writeObject(indices);
+ }
+ }
+
+ private static void writeObject(ObjectOutputStream out, Appearance appearance) throws IOException {
+ Material material = appearance.getMaterial();
+ if (material != null) {
+ out.writeBoolean(true);
+ Color3f color = new Color3f();
+ material.getAmbientColor(color);
+ out.writeObject(color);
+ color = new Color3f();
+ material.getDiffuseColor(color);
+ out.writeObject(color);
+ color = new Color3f();
+ material.getSpecularColor(color);
+ out.writeObject(color);
+ color = new Color3f();
+ material.getEmissiveColor(color);
+ out.writeObject(color);
+ out.writeFloat(material.getShininess());
+ out.writeInt(material.getColorTarget());
+ } else
+ out.writeBoolean(false);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ TG = new TransformGroup();
+ TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ TG.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ BG = new BranchGroup();
+ BG.setCapability(BranchGroup.ALLOW_DETACH);
+ BG.addChild(TG);
+ setShape(readNode(in));
+ }
+
+ private static Node readNode(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ int type = in.readInt();
+ switch (type) {
+ case NODE_TYPE_BRANCH:
+ BranchGroup bgroup = new BranchGroup();
+ int numTGChildren = in.readInt();
+ for (int i = 0; i < numTGChildren; i++) {
+ bgroup.addChild(readNode(in));
+ }
+ bgroup.setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
+ bgroup.setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
+ bgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ bgroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ return bgroup;
+ case NODE_TYPE_TRANSFORM:
+ TransformGroup tgroup = new TransformGroup();
+ Matrix4f matrix = (Matrix4f) in.readObject();
+ Transform3D tgT = new Transform3D(matrix);
+ tgroup.setTransform(tgT);
+ int numChildren = in.readInt();
+ for (int i = 0; i < numChildren; i++) {
+ tgroup.addChild(readNode(in));
+ }
+ tgroup.setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
+ tgroup.setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
+ tgroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ tgroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ return tgroup;
+ case NODE_TYPE_PRIMITIVE:
+ BranchGroup bg = new BranchGroup();
+ int shapes = in.readInt();
+ for (int i = 0; i < shapes; i++) {
+ Shape3D shape = new Shape3D();
+ shape.removeAllGeometries();
+ if (in.readBoolean())
+ shape.setAppearance(readAppearance(in));
+ int geometries = in.readInt();
+ for (int j = 0; j < geometries; j++)
+ shape.addGeometry(readGeometry(in));
+ bg.addChild(shape);
+ }
+ bg.setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
+ bg.setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
+ bg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ bg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ return bg;
+ case NODE_TYPE_SHAPE:
+ BranchGroup shapeBG = new BranchGroup();
+ Shape3D shape = new Shape3D();
+ shape.removeAllGeometries();
+ boolean hasAppearance = in.readBoolean();
+ Appearance shapeApp = new Appearance();
+ if (hasAppearance) {
+ shapeApp = readAppearance(in);
+ }
+ int geometries = in.readInt();
+ for (int i = 0; i < geometries; i++)
+ shape.addGeometry(readGeometry(in));
+ if (hasAppearance) {
+ shape.setAppearance(shapeApp);
+ }
+ shapeBG.addChild(shape);
+
+ shapeBG.setCapability(javax.media.j3d.Node.ALLOW_BOUNDS_READ);
+ shapeBG.setCapability(javax.media.j3d.Node.ALLOW_LOCAL_TO_VWORLD_READ);
+ shapeBG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ shapeBG.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ return shapeBG;
+ default:
+ throw new IllegalArgumentException("Illegal node type for serialization");
+ }
+ }
+
+ private static GeometryArray readGeometry(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ int format = in.readInt();
+ Point3f vertices[] = (Point3f[])in.readObject();
+ int indices[] = (int[])in.readObject();
+ IndexedTriangleArray geometry = new IndexedTriangleArray(vertices.length, format, indices.length);
+ geometry.setCoordinates(0, vertices);
+ geometry.setCoordinateIndices(0, indices);
+
+ if ((format & IndexedTriangleArray.NORMALS) != 0) {
+ Vector3f normals[] = (Vector3f[])in.readObject();
+ indices = (int[])in.readObject();
+ geometry.setNormals(0, normals);
+ geometry.setNormalIndices(0, indices);
+ }
+
+ return geometry;
+ }
+
+ private static Appearance readAppearance(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ Appearance appearance = new Appearance();
+ if (in.readBoolean()) {
+ Material material = new Material();
+ material.setAmbientColor((Color3f)in.readObject());
+ Color3f color = (Color3f)in.readObject();
+ material.setDiffuseColor(color);
+ material.setSpecularColor((Color3f)in.readObject());
+ material.setEmissiveColor((Color3f)in.readObject());
+ material.setShininess(in.readFloat());
+ material.setColorTarget(in.readInt());
+ appearance.setMaterial(material);
+ appearance.setColoringAttributes(new ColoringAttributes(color,
+ ColoringAttributes.FASTEST));
+ }
+ return appearance;
}
- */
-
- private static final int NODE_TYPE_BRANCH = 1;
- private static final int NODE_TYPE_TRANSFORM = 2;
- private static final int NODE_TYPE_PRIMITIVE = 3;
- private static final int NODE_TYPE_SHAPE = 4;
-
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- writeObject(out, node);
- }
-
- private static void writeObject(ObjectOutputStream out, Node node) throws IOException {
- if (node instanceof BranchGroup) {
- out.writeInt(NODE_TYPE_BRANCH);
- BranchGroup bg = (BranchGroup)node;
- out.writeInt(bg.numChildren());
- for (int i = 0; i < bg.numChildren(); i++) {
- writeObject(out, bg.getChild(i));
- }
- } else if (node instanceof TransformGroup) {
- out.writeInt(NODE_TYPE_TRANSFORM);
- TransformGroup tg = (TransformGroup)node;
- Transform3D transform = new Transform3D();
- tg.getTransform(transform);
- Matrix4f matrix4f = new Matrix4f();
- transform.get(matrix4f);
-
- out.writeObject(matrix4f);
- out.writeInt(tg.numChildren());
- for (int i = 0; i < tg.numChildren(); i++) {
- writeObject(out, tg.getChild(i));
- }
- } else if (node instanceof Primitive) {
- out.writeInt(NODE_TYPE_PRIMITIVE);
- Primitive prim = (Primitive)node;
- int index = 0;
- Shape3D shape;
- out.writeInt(prim.numChildren());
- while ((shape = prim.getShape(index++)) != null) {
- Appearance appearance = shape.getAppearance();
- if (appearance != null) {
- out.writeBoolean(true);
- writeObject(out, appearance);
- } else
- out.writeBoolean(false);
- out.writeInt(shape.numGeometries());
- for (int i = 0; i < shape.numGeometries(); i++)
- writeObject(out, shape.getGeometry(i));
- }
- } else if (node instanceof Shape3D) {
- out.writeInt(NODE_TYPE_SHAPE);
- // Shape3D extends a Leaf class and it has no children.
- // It contains a list of one or more Geometry component
- // objects and a single Appearance component object.
- Shape3D shape3D = (Shape3D)node;
- Appearance appearance = shape3D.getAppearance();
- if (appearance != null) {
- out.writeBoolean(true);
- writeObject(out, appearance);
- } else
- out.writeBoolean(false);
- out.writeInt(shape3D.numGeometries());
- for (int i = 0; i < shape3D.numGeometries(); i++)
- writeObject(out, shape3D.getGeometry(i));
- } else
- throw new IllegalArgumentException("Illegal node type for serialization");
- }
-
- private static void writeObject(ObjectOutputStream out, Geometry geometry) throws IOException {
- GeometryInfo gi = new GeometryInfo((GeometryArray)geometry);
- gi.convertToIndexedTriangles();
- geometry = gi.getIndexedGeometryArray();
- IndexedTriangleArray trueGeometry = (IndexedTriangleArray)geometry;
-
- int format = trueGeometry.getVertexFormat() & (IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS);
- out.writeInt(format);
- Point3f vertices[] = new Point3f[trueGeometry.getValidVertexCount()];
- for (int i = 0; i < vertices.length; i++) {
- vertices[i] = new Point3f();
- trueGeometry.getCoordinate(i, vertices[i]);
- }
- out.writeObject(vertices);
- int indices[] = new int[trueGeometry.getValidIndexCount()];
- trueGeometry.getCoordinateIndices(0, indices);
- out.writeObject(indices);
-
- if ((format & IndexedTriangleArray.NORMALS) != 0) {
- Vector3f normals[] = new Vector3f[trueGeometry.getValidVertexCount()];
- for (int i = 0; i < normals.length; i++) {
- normals[i] = new Vector3f();
- trueGeometry.getNormal(i, normals[i]);
- }
- out.writeObject(normals);
- indices = new int[trueGeometry.getValidIndexCount()];
- trueGeometry.getNormalIndices(0, indices);
- out.writeObject(indices);
- }
- }
-
- private static void writeObject(ObjectOutputStream out, Appearance appearance) throws IOException {
- // Write Coloring Attributes
- ColoringAttributes cAttrs = appearance.getColoringAttributes();
- if (cAttrs != null) {
- out.writeBoolean(true);
- Color3f color = new Color3f();
- cAttrs.getColor(color);
- out.writeObject(color);
- out.writeInt(cAttrs.getShadeModel());
- } else
- out.writeBoolean(false);
-
- // Write Polygon Attributes
- PolygonAttributes pAttrs = appearance.getPolygonAttributes();
- if (pAttrs != null) {
- out.writeBoolean(true);
- out.writeInt(pAttrs.getPolygonMode());
- out.writeInt(pAttrs.getCullFace());
- out.writeBoolean(pAttrs.getBackFaceNormalFlip());
- out.writeFloat(pAttrs.getPolygonOffset());
- out.writeFloat(pAttrs.getPolygonOffsetFactor());
- } else
- out.writeBoolean(false);
-
- // Write Transparency Attributes
- TransparencyAttributes tAttrs = appearance.getTransparencyAttributes();
- if (tAttrs != null) {
- out.writeBoolean(true);
- out.writeInt(tAttrs.getTransparencyMode());
- out.writeFloat(tAttrs.getTransparency());
- out.writeInt(tAttrs.getSrcBlendFunction());
- out.writeInt(tAttrs.getDstBlendFunction());
- } else
- out.writeBoolean(false);
-
- // Write Material Attributes
- Material material = appearance.getMaterial();
- if (material != null) {
- out.writeBoolean(true);
- Color3f color = new Color3f();
- material.getAmbientColor(color);
- out.writeObject(color);
- color = new Color3f();
- material.getDiffuseColor(color);
- out.writeObject(color);
- color = new Color3f();
- material.getSpecularColor(color);
- out.writeObject(color);
- color = new Color3f();
- material.getEmissiveColor(color);
- out.writeObject(color);
- out.writeFloat(material.getShininess());
- out.writeInt(material.getColorTarget());
- } else
- out.writeBoolean(false);
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- TG = new TransformGroup();
- TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
- TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
- TG.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
- BG = new BranchGroup();
- BG.setCapability(BranchGroup.ALLOW_DETACH);
- BG.addChild(TG);
- setShape(readNode(in));
- }
-
- private static Node readNode(ObjectInputStream in) throws IOException, ClassNotFoundException {
- int type = in.readInt();
- switch (type) {
- case NODE_TYPE_BRANCH:
- BranchGroup branch = new BranchGroup();
-
- int numChildrenBranch = in.readInt();
- for (int i = 0; i < numChildrenBranch; i++) {
- branch.addChild(readNode(in));
- }
- return branch;
- case NODE_TYPE_TRANSFORM:
- TransformGroup tg = new TransformGroup();
- Transform3D transform = new Transform3D();
- transform.set((Matrix4f)in.readObject());
- tg.setTransform(transform);
-
- int numChildren = in.readInt();
- for (int i = 0; i < numChildren; i++) {
- tg.addChild(readNode(in));
- }
- return tg;
- case NODE_TYPE_PRIMITIVE:
- BranchGroup bg = new BranchGroup();
- int shapes = in.readInt();
- for (int i = 0; i < shapes; i++) {
- Shape3D shape = new Shape3D();
- shape.removeAllGeometries();
- if (in.readBoolean())
- shape.setAppearance(readAppearance(in));
- int geometries = in.readInt();
- for (int j = 0; j < geometries; j++)
- shape.addGeometry(readGeometry(in));
- bg.addChild(shape);
- }
- return bg;
- case NODE_TYPE_SHAPE:
- Shape3D shape = new Shape3D();
- shape.removeAllGeometries();
- if (in.readBoolean())
- shape.setAppearance(readAppearance(in));
- int geometries = in.readInt();
- for (int j = 0; j < geometries; j++)
- shape.addGeometry(readGeometry(in));
- return shape;
- default:
- throw new IllegalArgumentException("Illegal node type for serialization");
- }
- }
-
- private static GeometryArray readGeometry(ObjectInputStream in) throws IOException, ClassNotFoundException {
- int format = in.readInt();
- Point3f vertices[] = (Point3f[])in.readObject();
- int indices[] = (int[])in.readObject();
- IndexedTriangleArray geometry = new IndexedTriangleArray(vertices.length, format, indices.length);
- geometry.setCoordinates(0, vertices);
- geometry.setCoordinateIndices(0, indices);
-
- if ((format & IndexedTriangleArray.NORMALS) != 0) {
- Vector3f normals[] = (Vector3f[])in.readObject();
- indices = (int[])in.readObject();
- geometry.setNormals(0, normals);
- geometry.setNormalIndices(0, indices);
- }
-
- return geometry;
- }
-
- private static Appearance readAppearance(ObjectInputStream in) throws IOException, ClassNotFoundException {
- Appearance appearance = new Appearance();
- // Read Coloring Attributes
- if (in.readBoolean()) {
- ColoringAttributes cAttrs = new ColoringAttributes();
- cAttrs.setColor((Color3f)in.readObject());
- cAttrs.setShadeModel(in.readInt());
- appearance.setColoringAttributes(cAttrs);
- }
- // Read Polygon Attributes
- if (in.readBoolean()) {
- PolygonAttributes pAttrs = new PolygonAttributes();
- pAttrs.setPolygonMode(in.readInt());
- pAttrs.setCullFace(in.readInt());
- pAttrs.setBackFaceNormalFlip(in.readBoolean());
- pAttrs.setPolygonOffset(in.readFloat());
- pAttrs.setPolygonOffsetFactor(in.readFloat());
- appearance.setPolygonAttributes(pAttrs);
- }
- // Read Transparency Attributes
- if (in.readBoolean()) {
- TransparencyAttributes tAttrs = new TransparencyAttributes();
- tAttrs.setTransparencyMode(in.readInt());
- tAttrs.setTransparency(in.readFloat());
- tAttrs.setSrcBlendFunction(in.readInt());
- tAttrs.setDstBlendFunction(in.readInt());
- appearance.setTransparencyAttributes(tAttrs);
- }
- // Read Material
- if (in.readBoolean()) {
- Material material = new Material();
- material.setAmbientColor((Color3f)in.readObject());
- material.setDiffuseColor((Color3f)in.readObject());
- material.setSpecularColor((Color3f)in.readObject());
- material.setEmissiveColor((Color3f)in.readObject());
- material.setShininess(in.readFloat());
- material.setColorTarget(in.readInt());
- appearance.setMaterial(material);
- }
- return appearance;
- }
-}
+}