javax.media.j3d.GeometryRetained Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java3d-core Show documentation
Show all versions of java3d-core Show documentation
Java3D Core And Java3D Util Libraries
The newest version!
/*
* Copyright 1996-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 javax.vecmath.Point3d;
abstract class GeometryRetained extends NodeComponentRetained {
static final int GEO_TYPE_NONE = -1;
static final int GEO_TYPE_QUAD_SET = 1;
static final int GEO_TYPE_TRI_SET = 2;
static final int GEO_TYPE_POINT_SET = 3;
static final int GEO_TYPE_LINE_SET = 4;
static final int GEO_TYPE_TRI_STRIP_SET = 5;
static final int GEO_TYPE_TRI_FAN_SET = 6;
static final int GEO_TYPE_LINE_STRIP_SET = 7;
static final int GEO_TYPE_INDEXED_QUAD_SET = 8;
static final int GEO_TYPE_INDEXED_TRI_SET = 9;
static final int GEO_TYPE_INDEXED_POINT_SET = 10;
static final int GEO_TYPE_INDEXED_LINE_SET = 11;
static final int GEO_TYPE_INDEXED_TRI_STRIP_SET = 12;
static final int GEO_TYPE_INDEXED_TRI_FAN_SET = 13;
static final int GEO_TYPE_INDEXED_LINE_STRIP_SET = 14;
static final int GEO_TYPE_RASTER = 15;
static final int GEO_TYPE_TEXT3D = 16;
static final int GEO_TYPE_COMPRESSED = 17;
static final int GEO_TYPE_TOTAL = 17;
static final int GEO_TYPE_GEOMETRYARRAY = 14;
BoundingBox geoBounds = new BoundingBox();
// Indicates whether bounds need to be computed.
// Checked when a user does addUser/removeUser and count goes from 0 to one
// but geometry has not changed and there is no need to recompute
boolean boundsDirty = true; // Changed while holding the geoBounds lock
int computeGeoBounds = 0; // Changed while holding the geoBounds lock
// The "type" of this object
int geoType = GEO_TYPE_NONE;
// The id used by the native code when building this object
int nativeId = -1;
// A mask that indicates that something has changed in this object
int isDirty = 0xffff;
// Geometry Lock (used only by GeometryArrayRetained and RasterRetained)
GeometryLock geomLock = new GeometryLock();
// Lock used for synchronization of live state
Object liveStateLock = new Object();
abstract void update();
// A reference to the mirror copy of the geometry
GeometryRetained mirrorGeometry = null;
// indicates whether the geometry in editable
boolean isEditable = true;
// A list of Universes that this Geometry is referenced from
ArrayList universeList = new ArrayList();
// A list of ArrayLists which contain all the Shape3DRetained objects
// refering to this geometry. Each list corresponds to the universe
// above.
ArrayList> userLists = new ArrayList>();
// true if color not specified with alpha channel
boolean noAlpha = false;
static final double EPSILON = 1.0e-6;
Point3d centroid = new Point3d();
boolean recompCentroid = true;
// The cached value is evaluated by renderBin and used in determining
// whether to put it in display list or not
int cachedChangedFrequent = 0;
static final int POINT_TYPE = 1;
static final int LINE_TYPE = 2;
static final int TRIANGLE_TYPE = 3;
static final int QUAD_TYPE = 4;
static final int RASTER_TYPE = 5;
static final int TEXT3D_TYPE = 6;
static final int COMPRESS_TYPE = 7;
boolean isEquivalenceClass( GeometryRetained geometry ) {
int t1 = getClassType();
int t2 = geometry.getClassType();
if (t1 == QUAD_TYPE) {
t1 = TRIANGLE_TYPE;
}
if (t2 == QUAD_TYPE) {
t2 = TRIANGLE_TYPE;
}
return (t1 == t2);
}
void incrComputeGeoBounds() {
synchronized(geoBounds) {
computeGeoBounds++;
// When it goes from zero to one, compute it ..
if (computeGeoBounds == 1 && source.isLive()) {
computeBoundingBox();
}
}
}
void decrComputeGeoBounds() {
synchronized(geoBounds) {
computeGeoBounds--;
}
}
// This adds a Shape3DRetained to the list of users of this geometry
void addUser(Shape3DRetained s) {
if (s.sourceNode.boundsAutoCompute) {
incrComputeGeoBounds();
}
// If static, no need to maintain a userlist
if (this instanceof GeometryArrayRetained) {
if (((GeometryArrayRetained)this).isWriteStatic()) {
return;
}
}
synchronized (universeList) {
if (universeList.contains(s.universe)) {
int index = universeList.indexOf(s.universe);
userLists.get(index).add(s);
} else {
universeList.add(s.universe);
ArrayList shapeList = new ArrayList();
shapeList.add(s);
userLists.add(shapeList);
}
}
}
// This adds a Shape3DRetained to the list of users of this geometry
void removeUser(Shape3DRetained s) {
if (s.sourceNode.boundsAutoCompute) {
decrComputeGeoBounds();
}
if (this instanceof GeometryArrayRetained) {
if (((GeometryArrayRetained)this).isWriteStatic()) {
return;
}
}
synchronized (universeList) {
int index = universeList.indexOf(s.universe);
ArrayList shapeList = userLists.get(index);
shapeList.remove(s);
if (shapeList.size() == 0) {
userLists.remove(index);
universeList.remove(index);
}
}
}
public void updateObject() {
this.update();
}
abstract void computeBoundingBox();
@Override
void setLive(boolean inBackgroundGroup, int refCount) {
doSetLive(inBackgroundGroup,refCount);
super.markAsLive();
}
/**
* This setLive routine calls the superclass's method when reference
* count is 1
*/
@Override
void doSetLive(boolean inBackgroundGroup, int refCount) {
super.doSetLive(inBackgroundGroup, refCount);
this.update();
this.computeBoundingBox();
}
abstract void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
int screen, boolean ignoreVertexColors);
/**
* This method should return an int indicating the format of the vertices,
* if any, stored in the geometry. Instances that can return a valid value
* should override this method, otherwise it will be assumed that no
* valid vertex components exist.
* @return format of vertices in the GeometryRetained as specified by
* GeometryArray, if appropriate to this instance.
*/
int getVertexFormat() {
return 0 ;
}
// Issue 199 -- Chien
abstract boolean intersect(PickShape pickShape, PickInfo pickInfo, int flags, Point3d iPnt,
GeometryRetained geom, int geomIndex);
// Old stuff -- Chien
//abstract boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt);
abstract boolean intersect(Bounds targetBound);
abstract boolean intersect(Point3d[] pnts);
abstract boolean intersect(Transform3D thisToOtherVworld, GeometryRetained geom);
void storeInterestData(PickInfo pickInfo, int flags, GeometryRetained geom, int geomIndex,
int[] vtxIndexArr, Point3d iPnt, double dist) {
PickInfo.IntersectionInfo iInfo = null;
if((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
PickInfo.IntersectionInfo iInfoArr[] = pickInfo.getIntersectionInfos();
if((iInfoArr == null) || (iInfoArr.length == 0)) {
iInfo = pickInfo.createIntersectionInfo();
pickInfo.insertIntersectionInfo(iInfo);
}
else {
assert(iInfoArr.length == 1);
iInfo = iInfoArr[0];
}
}
else if((flags & PickInfo.ALL_GEOM_INFO) != 0) {
iInfo = pickInfo.createIntersectionInfo();
pickInfo.insertIntersectionInfo(iInfo);
}
else {
assert(false);
}
// This only set the reference to geometry.source.
iInfo.setGeometry((Geometry) geom.source);
// The rest are by copy.
iInfo.setGeometryIndex(geomIndex);
iInfo.setDistance(dist);
iInfo.setIntersectionPoint(iPnt);
iInfo.setVertexIndices(vtxIndexArr);
}
boolean intersect(Transform3D thisLocalToVworld,
Transform3D otherLocalToVworld, GeometryRetained geom) {
Transform3D t3d = new Transform3D();
t3d.invert(otherLocalToVworld);
t3d.mul(thisLocalToVworld);
return intersect(t3d, geom);
}
boolean intersect(Transform3D thisLocalToVworld, Bounds targetBound) {
Bounds transBound = (Bounds) targetBound.clone();
Transform3D t3d = new Transform3D();
t3d.invert(thisLocalToVworld);
transBound.transform(t3d);
return intersect(transBound);
}
// Return a flag indicating whether or not this Geometry object can be in
// a display list.
//
// XXXX: Note that for IndexedGeometryArray objects, the original
// vertex format is used in making this determination, even when it has
// been unindexified. This should be fixed by using the vertex format of
// the mirror geometry if there is one.
boolean canBeInDisplayList(boolean alphaEditable) {
// Check global flag to see whether we can build display lists
if (!VirtualUniverse.mc.isDisplayList) {
return false;
}
// Can't build display lists if geometry is frequently writable
//
// Issue 181 : to fix performance regression from 1.3.2, we will allow
// editable geometry if the optimizeForSpace property is set false and
// the cachedChangedFrequent flag is set; note this will basically
// restore the 1.3.2 behavior, which isn't completely correct.
// Eventually, we should fix the bug that is causing the
// cachedChangedFrequent bit to be wrong; we can then remove the
// erroneous dependency on optimizeForSpace.
if (this.isEditable) {
if (cachedChangedFrequent != 0) {
return false;
}
// TODO: remove the following when cachedChangedFrequent is fixed
// to correctly reflect the state
if (!VirtualUniverse.mc.buildDisplayListIfPossible) {
return false;
}
}
if (this instanceof GeometryArrayRetained) {
int vFormat = ((GeometryArrayRetained)this).vertexFormat;
// If geometry has vertex attributes, check whether
// vertex attributes are allowed in display lists
if (((vFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
!VirtualUniverse.mc.vertexAttrsInDisplayList) {
return false;
}
// Can't build display lists if alpha is editable and
// geometry array has colors
if (alphaEditable && ((vFormat & GeometryArray.COLOR) != 0)) {
return false;
}
// Only build DL for by-ref geometry when system property is set.
// Exclude NIO buffers and use-coord-index-only
if ((vFormat & GeometryArray.BY_REFERENCE) != 0) {
if (!VirtualUniverse.mc.buildDisplayListIfPossible) {
return false;
}
// XXXX: we could change this to allow display lists for
// non-interleaved NIO buffers, but we would first need to
// update the now-obsolete buildGAForBuffer method to handle
// vertex attrs
if ((vFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
return false;
}
if ((vFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
return false;
}
}
return true;
} else {
// Can't build display lists for other kind of geometry
// NOTE: This method is not called for any type of Geometry
// other than GeometryArray, so we shouldn't even get here.
return false;
}
}
void computeCentroid() {
geoBounds.getCenter(this.centroid);
}
abstract int getClassType();
}