Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package javax.media.j3d;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import javax.vecmath.Point3d;
/**
* A leaf node that holds a merged shapes in compile mode
*/
class Shape3DCompileRetained extends Shape3DRetained {
int numShapes = 0;
// Each element in the arraylist is an array of geometries for a
// particular merged shape
ArrayList> geometryInfo = null;
Object[] srcList = null;
Shape3DCompileRetained(Shape3DRetained[] shapes, int nShapes, int compileFlags) {
int i, j;
// Merged list, only merged if geometry is mergeable
ArrayList[] mergedList = new ArrayList[GeometryRetained.GEO_TYPE_GEOMETRYARRAY + 1];
// Sorted list of separate geometry by geoType
ArrayList[] separateList = new ArrayList[GeometryRetained.GEO_TYPE_GEOMETRYARRAY + 1];
// Assign the num of shapes
numShapes = nShapes;
srcList = new Object[nShapes];
if (nShapes > 0) {
boundsAutoCompute = shapes[0].boundsAutoCompute;
source = shapes[0].source;
}
// Remove the null that was added by Shape3DRetained constructor
geometryList.remove(0);
// Assign the fields for this compile shape
boundsAutoCompute = shapes[0].boundsAutoCompute;
isPickable = shapes[0].isPickable;
isCollidable = shapes[0].isCollidable;
appearanceOverrideEnable = shapes[0].appearanceOverrideEnable;
appearance = shapes[0].appearance;
collisionBound = shapes[0].collisionBound;
localBounds = shapes[0].localBounds;
if ((compileFlags & CompileState.GEOMETRY_READ) != 0)
geometryInfo = new ArrayList>();
for (i = 0; i < nShapes; i++) {
Shape3DRetained shape = shapes[i];
((Shape3D)shape.source).id = i;
shape.source.retained = this;
srcList[i] = shape.source;
// If the transform has been pushd down
// to the shape, don't merge its geometry with other shapes
// geometry
// Put it in a separate list sorted by geo_type
// Have to handle shape.isPickable
for (j = 0; j < shape.geometryList.size(); j++) {
GeometryArrayRetained geo = (GeometryArrayRetained)shape.geometryList.get(j);
if (geo == null)
continue;
if (shape.willRemainOpaque(geo.geoType) && geo.isMergeable()) {
if (mergedList[geo.geoType] == null) {
mergedList[geo.geoType] = new ArrayList();
}
mergedList[geo.geoType].add(geo);
}
else {
// Keep a sorted list based on geoType;
if (separateList[geo.geoType] == null) {
separateList[geo.geoType] = new ArrayList();
}
// add it to the geometryList separately
separateList[geo.geoType].add(geo);
}
}
// Point to the geometryList's source, so the
// retained side will be garbage collected
if ((compileFlags & CompileState.GEOMETRY_READ) != 0) {
ArrayList sList = new ArrayList();
for (j = 0; j < shape.geometryList.size(); j++) {
GeometryRetained g = shape.geometryList.get(j);
if (g != null)
sList.add((Geometry)g.source);
else
sList.add(null);
}
geometryInfo.add(sList);
}
}
// Now, merged the mergelist and separate list based on geoType,
// this enables dlist optmization
for (i = 1; i <= GeometryRetained.GEO_TYPE_GEOMETRYARRAY; i++) {
switch (i) {
case GeometryArrayRetained.GEO_TYPE_QUAD_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new QuadArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_TRI_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new TriangleArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_POINT_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new PointArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_LINE_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new LineArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_TRI_STRIP_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new TriangleStripArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_TRI_FAN_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new TriangleFanArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_LINE_STRIP_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new LineStripArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_QUAD_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new IndexedQuadArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new IndexedTriangleArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_POINT_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new IndexedPointArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_LINE_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i], new IndexedLineArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i],
new IndexedTriangleStripArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i],
new IndexedTriangleFanArrayRetained());
addSeparateList(separateList[i]);
break;
case GeometryArrayRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
if (mergedList[i] != null)
addMergedList(mergedList[i],
new IndexedLineStripArrayRetained());
addSeparateList(separateList[i]);
break;
}
}
}
private void addMergedList(ArrayList glist,
GeometryArrayRetained cgeo) {
cgeo.setCompiled(glist);
geometryList.add(cgeo);
cgeo.setSource(((SceneGraphObjectRetained) glist.get(0)).source);
}
private void addSeparateList(ArrayList glist) {
if (glist == null)
return;
for (int k = 0; k < glist.size(); k++) {
geometryList.add(glist.get(k));
}
}
@Override
Bounds getCollisionBounds(int childIndex) {
return collisionBound;
}
@Override
int numGeometries(int childIndex) {
return geometryInfo.get(childIndex).size();
}
@Override
Geometry getGeometry(int i, int childIndex) {
return geometryInfo.get(childIndex).get(i);
}
@Override
Enumeration getAllGeometries(int childIndex) {
ArrayList geoInfo = geometryInfo.get(childIndex);
Vector geomList = new Vector();
for (int i = 0; i < geoInfo.size(); i++) {
geomList.add(geoInfo.get(i));
}
return geomList.elements();
}
Bounds getBounds(int childIndex) {
if (!boundsAutoCompute)
return super.getBounds();
ArrayList glist = geometryInfo.get(childIndex);
if (glist == null)
return null;
BoundingBox bbox = new BoundingBox((Bounds)null);
for (int i = 0; i < glist.size(); i++) {
Geometry g = glist.get(i);
if (g == null)
continue;
GeometryRetained geometry = (GeometryRetained)g.retained;
if (geometry.geoType == GeometryRetained.GEO_TYPE_NONE)
continue;
geometry.computeBoundingBox();
synchronized (geometry.geoBounds) {
bbox.combine(geometry.geoBounds);
}
}
return bbox;
}
/**
* Check if the geometry component of this shape node under path
* intersects with the pickRay.
* @return true if intersected else false. If return is true, dist
* contains the closest
* distance of intersection.
* @exception IllegalArgumentException if path is
* invalid.
*/
@Override
boolean intersect(SceneGraphPath path,
PickShape pickShape, double[] dist) {
int flags;
PickInfo pickInfo = new PickInfo();
Transform3D localToVworld = path.getTransform();
if (localToVworld == null) {
throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3"));
}
pickInfo.setLocalToVWorldRef( localToVworld);
Shape3D shape = (Shape3D) path.getObject();
// Get the geometries for this shape only, since the compiled
// geomtryList contains several shapes
ArrayList glist = geometryInfo.get(shape.id);
// System.err.println("Shape3DCompileRetained.intersect() : ");
if (dist == null) {
// System.err.println(" no dist request ....");
return intersect(pickInfo, pickShape, 0, glist);
}
flags = PickInfo.CLOSEST_DISTANCE;
if (intersect(pickInfo, pickShape, flags, glist)) {
dist[0] = pickInfo.getClosestDistance();
return true;
}
return false;
}
boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags,
ArrayList geometryList) {
Transform3D localToVworld = pickInfo.getLocalToVWorldRef();
Transform3D t3d = new Transform3D();
t3d.invert(localToVworld);
PickShape newPS = pickShape.transform(t3d);
int geomListSize = geometryList.size();
GeometryRetained geometry;
if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0) &&
((flags & PickInfo.CLOSEST_DISTANCE) == 0) &&
((flags & PickInfo.CLOSEST_GEOM_INFO) == 0) &&
((flags & PickInfo.ALL_GEOM_INFO) == 0)) {
for (int i=0; i < geomListSize; i++) {
geometry = (GeometryRetained) geometryList.get(i).retained;
if (geometry != null) {
if (geometry.mirrorGeometry != null) {
geometry = geometry.mirrorGeometry;
}
// Need to modify this method
// if (geometry.intersect(newPS, null, null)) {
if (geometry.intersect(newPS, null, 0, null, null, 0)) {
return true;
}
}
}
}
else {
double distance;
double minDist = Double.POSITIVE_INFINITY;
Point3d closestIPnt = new Point3d();
Point3d iPnt = new Point3d();
Point3d iPntVW = new Point3d();
for (int i=0; i < geomListSize; i++) {
geometry = (GeometryRetained) geometryList.get(i).retained;
if (geometry != null) {
if (geometry.mirrorGeometry != null) {
geometry = geometry.mirrorGeometry;
}
if (geometry.intersect(newPS, pickInfo, flags, iPnt, geometry, i)) {
iPntVW.set(iPnt);
localToVworld.transform(iPntVW);
distance = pickShape.distance(iPntVW);
if (minDist > distance) {
minDist = distance;
closestIPnt.set(iPnt);
}
}
}
}
if (minDist < Double.POSITIVE_INFINITY) {
if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) {
pickInfo.setClosestDistance(minDist);
}
if((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) {
pickInfo.setClosestIntersectionPoint(closestIPnt);
}
return true;
}
}
return false;
}
}