From 49529f9005eb68166ef339f2fdcc2a6cd70afc35 Mon Sep 17 00:00:00 2001 From: Jesse Morgan Date: Mon, 14 Mar 2011 23:55:53 +0000 Subject: Reverting to our code. --- src/common/CollidableObject.java | 813 +++++++++++++++++++-------------------- 1 file changed, 393 insertions(+), 420 deletions(-) (limited to 'src/common') 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 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 collisions = CollisionDetector.calculateCollisions(this, other); + if (collisions.isEmpty()) + return; + */ + //Alden mar4 change + public void resolveCollisions(CollidableObject other, ArrayList 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; - } -} +} -- cgit v1.2.3