aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/Text3DRetained.java
diff options
context:
space:
mode:
authorJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
committerJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
commitdbc98deea1884e44da2c74d6ea807253cdefa693 (patch)
tree29c3ee7dea82d7dd773d81f33f645dde67e43a17 /src/javax/media/j3d/Text3DRetained.java
parent2c99f1329dc55bd496bce91b9aba956ecba3c67e (diff)
Relocate package prefix to org.jogamp.java3d
Diffstat (limited to 'src/javax/media/j3d/Text3DRetained.java')
-rw-r--r--src/javax/media/j3d/Text3DRetained.java999
1 files changed, 0 insertions, 999 deletions
diff --git a/src/javax/media/j3d/Text3DRetained.java b/src/javax/media/j3d/Text3DRetained.java
deleted file mode 100644
index ed21941..0000000
--- a/src/javax/media/j3d/Text3DRetained.java
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Copyright 1998-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.awt.font.GlyphVector;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-
-import javax.vecmath.Point3d;
-import javax.vecmath.Point3f;
-import javax.vecmath.Vector3f;
-
-/**
- * Implements Text3D class.
- */
-class Text3DRetained extends GeometryRetained {
- /**
- * Packaged scope variables needed for implementation
- */
- Font3D font3D = null;
- String string = null;
- Point3f position = new Point3f(0.0f, 0.0f, 0.0f);
- int alignment = Text3D.ALIGN_FIRST, path = Text3D.PATH_RIGHT;
- float charSpacing = 0.0f;
- int numChars = 0;
- static final int targetThreads = (J3dThread.UPDATE_TRANSFORM |
- J3dThread.UPDATE_GEOMETRY |
- J3dThread.UPDATE_RENDER);
- /**
- * The temporary transforms for this Text3D
- */
- Transform3D[] charTransforms = new Transform3D[0];
-
- /**
- * A cached list of geometry arrays for the current settings
- */
- GeometryArrayRetained[] geometryList = new GeometryArrayRetained[0];
- GlyphVector[] glyphVecs = new GlyphVector[0];
-
- /**
- * Bounding box data for this text string.
- */
- Point3d lower = new Point3d();
- Point3d upper = new Point3d();
-
-
- /**
- * An Array list used for messages
- */
- ArrayList newGeometryAtomList = new ArrayList();
- ArrayList oldGeometryAtomList = new ArrayList();
-
-
- /**
- * temporary model view matrix for immediate mode only
- */
- Transform3D vpcToEc;
- Transform3D drawTransform;
-
-
- Text3DRetained(){
- this.geoType = GEO_TYPE_TEXT3D;
- }
-
-
- @Override
- synchronized void computeBoundingBox() {
- Point3d l = new Point3d();
- Point3d u = new Point3d();
- Vector3f location = new Vector3f(this.position);
- int i, k=0, numTotal=0;
- double width = 0, height = 0;
- Rectangle2D bounds;
-
- //Reset bounds data
- l.set(location);
- u.set(location);
-
- if (numChars != 0) {
- // Set loop counters based on path type
- if (path == Text3D.PATH_RIGHT || path == Text3D.PATH_UP) {
- k = 0;
- numTotal = numChars + 1;
- } else if (path == Text3D.PATH_LEFT || path == Text3D.PATH_DOWN) {
- k = 1;
- numTotal = numChars;
- // Reset bounds to bounding box if first character
- bounds = glyphVecs[0].getVisualBounds();
- u.x += bounds.getWidth();
- u.y += bounds.getHeight();
- }
-
- for (i=1; i<numTotal; i++, k++) {
- width = glyphVecs[k].getLogicalBounds().getWidth();
- bounds = glyphVecs[k].getVisualBounds();
- // 'switch' could be outside loop with little hacking,
- width += charSpacing;
- height = bounds.getHeight();
-
- switch (this.path) {
- case Text3D.PATH_RIGHT:
- u.x += (width);
- if (u.y < (height + location.y)) {
- u.y = location.y + height;
- }
- break;
- case Text3D.PATH_LEFT:
- l.x -= (width);
- if (u.y < ( height + location.y)) {
- u.y = location.y + height;
- }
- break;
- case Text3D.PATH_UP:
- u.y += height;
- if (u.x < (bounds.getWidth() + location.x)) {
- u.x = location.x + bounds.getWidth();
- }
- break;
- case Text3D.PATH_DOWN:
- l.y -= height;
- if (u.x < (bounds.getWidth() + location.x)) {
- u.x = location.x + bounds.getWidth();
- }
- break;
- }
- }
-
- // Handle string alignment. ALIGN_FIRST is handled by default
- if (alignment != Text3D.ALIGN_FIRST) {
- double cx = (u.x - l.x);
- double cy = (u.y - l.y);
-
- if (alignment == Text3D.ALIGN_CENTER) {
- cx *= .5;
- cy *= .5;
- }
- switch (path) {
- case Text3D.PATH_RIGHT:
- l.x -= cx;
- u.x -= cx;
- break;
- case Text3D.PATH_LEFT:
- l.x += cx;
- u.x += cx;
- break;
- case Text3D.PATH_UP:
- l.y -= cy;
- u.y -= cy;
- break;
- case Text3D.PATH_DOWN:
- l.y += cy;
- u.y += cy;
- break;
-
- }
- }
- }
-
- l.z = 0.0f;
- if ((font3D == null) || (font3D.fontExtrusion == null)) {
- u.z = l.z;
- } else {
- u.z = l.z + font3D.fontExtrusion.length;
- }
- }
-
- @Override
- void update() {}
-
-
- /**
- * Returns the Font3D objects used by this Text3D NodeComponent object.
- *
- * @return the Font3D object of this Text3D node - null if no Font3D
- * has been associated with this node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final Font3D getFont3D() {
- return this.font3D;
- }
-
- /**
- * Sets the Font3D object used by this Text3D NodeComponent object.
- *
- * @param font3d the Font3D object to associate with this Text3D node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final void setFont3D(Font3D font3d) {
- geomLock.getLock();
- this.font3D = font3d;
- updateCharacterData();
- geomLock.unLock();
- sendDataChangedMessage();
- }
-
- /**
- * Copies the character string used in the construction of the
- * Text3D node into the supplied parameter.
- *
- * @return a copy of the String object in this Text3D node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final String getString() {
- return this.string;
- }
-
- /**
- * Copies the character string from the supplied parameter into Tex3D
- * node.
- *
- * @param string the String object to recieve the Text3D node's string.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final void setString(String string) {
- geomLock.getLock();
- this.string = string;
- if (string == null) {
- numChars = 0;
- } else {
- numChars = string.length();
- }
- updateCharacterData();
- geomLock.unLock();
- sendDataChangedMessage();
- }
-
- /**
- * Copies the node's <code>position</code> field into the supplied
- * parameter. The <code>position</code> is used to determine the
- * initial placement of the Text3D string. The position, combined with
- * the path and alignment control how the text is displayed.
- *
- * @param position the point to position the text.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- *
- * @see #getAlignment
- * @see #getPath
- */
- final void getPosition(Point3f position) {
- position.set(this.position);
- }
-
- /**
- * Sets the node's <code>position</code> field to the supplied
- * parameter. The <code>position</code> is used to determine the
- * initial placement of the Text3D string. The position, combined with
- * the path and alignment control how the text is displayed.
- *
- * @param position the point to position the text.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- *
- * @see #getAlignment
- * @see #getPath
- */
- final void setPosition(Point3f position) {
- geomLock.getLock();
- this.position.set(position);
- updateTransformData();
- geomLock.unLock();
- sendTransformChangedMessage();
- }
-
- /**
- * Retrieves the text alignment policy for this Text3D NodeComponent
- * object. The <code>alignment</code> is used to specify how
- * glyphs in the string are placed in relation to the
- * <code>position</code> field. Valid values for this field
- * are:
- * <UL>
- * <LI> ALIGN_CENTER - the center of the string is placed on the
- * <code>position</code> point.
- * <LI> ALIGN_FIRST - the first character of the string is placed on
- * the <code>position</code> point.
- * <LI> ALIGN_LAST - the last character of the string is placed on the
- * <code>position</code> point.
- * </UL>
- * The default value of this field is <code>ALIGN_FIRST</code>.
- *
- * @return the current alingment policy for this node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- *
- * @see #getPosition
- */
- final int getAlignment() {
- return alignment;
- }
-
- /**
- * Sets the text alignment policy for this Text3D NodeComponent
- * object. The <code>alignment</code> is used to specify how
- * glyphs in the string are placed in relation to the
- * <code>position</code> field. Valid values for this field
- * are:
- * <UL>
- * <LI> ALIGN_CENTER - the center of the string is placed on the
- * <code>position</code> point.
- * <LI> ALIGN_FIRST - the first character of the string is placed on
- * the <code>position</code> point.
- * <LI> ALIGN_LAST - the last character of the string is placed on the
- * <code>position</code> point.
- * </UL>
- * The default value of this field is <code>ALIGN_FIRST</code>.
- *
- * @return the current alingment policy for this node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- *
- * @see #getPosition
- */
- final void setAlignment(int alignment) {
- geomLock.getLock();
- this.alignment = alignment;
- updateTransformData();
- geomLock.unLock();
- sendTransformChangedMessage();
- }
-
- /**
- * Retrieves the node's <code>path</code> field. This field
- * is used to specify how succeeding
- * glyphs in the string are placed in relation to the previous glyph.
- * Valid values for this field are:
- * <UL>
- * <LI> PATH_LEFT: - succeeding glyphs are placed to the left of the
- * current glyph.
- * <LI> PATH_RIGHT: - succeeding glyphs are placed to the right of the
- * current glyph.
- * <LI> PATH_UP: - succeeding glyphs are placed above the current glyph.
- * <LI> PATH_DOWN: - succeeding glyphs are placed below the current glyph.
- * </UL>
- * The default value of this field is <code>PATH_RIGHT</code>.
- *
- * @return the current alingment policy for this node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final int getPath() {
- return this.path;
- }
-
- /**
- * Sets the node's <code>path</code> field. This field
- * is used to specify how succeeding
- * glyphs in the string are placed in relation to the previous glyph.
- * Valid values for this field are:
- * <UL>
- * <LI> PATH_LEFT - succeeding glyphs are placed to the left of the
- * current glyph.
- * <LI> PATH_RIGHT - succeeding glyphs are placed to the right of the
- * current glyph.
- * <LI> PATH_UP - succeeding glyphs are placed above the current glyph.
- * <LI> PATH_DOWN - succeeding glyphs are placed below the current glyph.
- * </UL>
- * The default value of this field is <code>PATH_RIGHT</code>.
- *
- * @param path the value to set the path to.
- *
- * @return the current alingment policy for this node.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final void setPath(int path) {
- this.path = path;
- updateTransformData();
- sendTransformChangedMessage();
- }
-
- /**
- * Retrieves the 3D bounding box that encloses this Text3D object.
- *
- * @param bounds the object to copy the bounding information to.
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- *
- * @see BoundingBox
- */
- final void getBoundingBox(BoundingBox bounds) {
- synchronized (this) {
- bounds.setLower(lower);
- bounds.setUpper(upper);
- }
- }
-
- /**
- * Retrieves the character spacing used to construct the Text3D string.
- * This spacing is in addition to the regular spacing between glyphs as
- * defined in the Font object. 1.0 in this space is measured as the
- * width of the largest glyph in the 2D Font. The default value is
- * 0.0.
- *
- * @return the current character spacing value
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final float getCharacterSpacing() {
- return charSpacing;
- }
-
- /**
- * Sets the character spacing used hwne constructing the Text3D string.
- * This spacing is in addition to the regular spacing between glyphs as
- * defined in the Font object. 1.0 in this space is measured as the
- * width of the largest glyph in the 2D Font. The default value is
- * 0.0.
- *
- * @param characterSpacing the new character spacing value
- *
- * @exception CapabilityNotSetException if appropriate capability is
- * not set and this object is part of live or compiled scene graph
- */
- final void setCharacterSpacing(float characterSpacing) {
- geomLock.getLock();
- this.charSpacing = characterSpacing;
- updateTransformData();
- geomLock.unLock();
- sendTransformChangedMessage();
- }
-
-
- final void sendDataChangedMessage() {
- J3dMessage[] m;
- int i, j, k, kk, numMessages;
- int gSize;
- ArrayList gaList;
- GeometryAtom[] newGeometryAtoms;
- ArrayList tiArrList = new ArrayList();
- ArrayList newCtArrArrList = new ArrayList();
-
- synchronized(liveStateLock) {
- if (source.isLive()) {
- synchronized (universeList) {
- numMessages = universeList.size();
- m = new J3dMessage[numMessages];
- for (i=0; i<numMessages; i++) {
- m[i] = new J3dMessage();
- m[i].type = J3dMessage.TEXT3D_DATA_CHANGED;
- m[i].threads = targetThreads;
- ArrayList<Shape3DRetained> shapeList = userLists.get(i);
- newGeometryAtomList.clear();
- oldGeometryAtomList.clear();
-
- for (j=0; j<shapeList.size(); j++) {
- Shape3DRetained s = shapeList.get(j);
- if (s.boundsAutoCompute) {
- // update combine bounds of mirrorShape3Ds. So we need to
- // use its bounds and not localBounds.
- // bounds is actually a reference to
- // mirrorShape3D.source.localBounds.
- // XXXX : Should only need to update distinct localBounds.
- s.getCombineBounds((BoundingBox)s.bounds);
- }
-
- gSize = s.geometryList.size();
-
- GeometryAtom oldGA = Shape3DRetained.getGeomAtom(s);
- GeometryAtom newGA = new GeometryAtom();
-
- int geometryCnt = 0;
- for(k = 0; k<gSize; k++) {
- GeometryRetained geomRetained = s.geometryList.get(k);
- if(geomRetained != null) {
- Text3DRetained tempT3d = (Text3DRetained)geomRetained;
- geometryCnt += tempT3d.numChars;
- }
- else {
- // Slightly wasteful, but not quite worth to optimize yet.
- geometryCnt++;
- }
- }
-
- newGA.geometryArray = new GeometryRetained[geometryCnt];
- newGA.lastLocalTransformArray = new Transform3D[geometryCnt];
- // Reset geometryCnt;
- geometryCnt = 0;
-
- newGA.locale = s.locale;
- newGA.visible = s.visible;
- newGA.source = s;
- int gaCnt=0;
- GeometryRetained geometry = null;
- for(; gaCnt<gSize; gaCnt++) {
- geometry = s.geometryList.get(gaCnt);
- if(geometry != null) {
- newGA.geoType = geometry.geoType;
- newGA.alphaEditable = s.isAlphaEditable(geometry);
- break;
- }
- }
-
- for(; gaCnt<gSize; gaCnt++) {
- geometry = s.geometryList.get(gaCnt);
- if(geometry == null) {
- newGA.geometryArray[gaCnt] = null;
- }
- else {
- Text3DRetained t = (Text3DRetained)geometry;
- GeometryRetained geo;
- for (k=0; k<t.numChars; k++, geometryCnt++) {
- geo = t.geometryList[k];
- if (geo != null) {
- newGA.geometryArray[geometryCnt] = geo;
- newGA.lastLocalTransformArray[geometryCnt] =
- t.charTransforms[k];
-
- } else {
- newGA.geometryArray[geometryCnt] = null;
- newGA.lastLocalTransformArray[geometryCnt] = null;
- }
-
- }
-
- }
- }
-
- oldGeometryAtomList.add(oldGA);
- newGeometryAtomList.add(newGA);
- Shape3DRetained.setGeomAtom(s, newGA);
- }
-
- Object[] oldGAArray = oldGeometryAtomList.toArray();
- Object[] newGAArray = newGeometryAtomList.toArray();
- ArrayList uniqueList = getUniqueSource(shapeList);
- int numSrc = uniqueList.size();
- int numMS3D;
- Shape3DRetained ms, src;
-
- for (j=0; j<numSrc; j++) {
- CachedTargets[] newCtArr = null;
- src = (Shape3DRetained)uniqueList.get(j);
- numMS3D = src.mirrorShape3D.size();
-
- TargetsInterface ti = ((GroupRetained)src.
- parent).getClosestTargetsInterface(
- TargetsInterface.TRANSFORM_TARGETS);
-
- if (ti != null) {
- CachedTargets ct;
- newCtArr = new CachedTargets[numMS3D];
-
- for (k=0; k<numMS3D; k++) {
- ms = src.mirrorShape3D.get(k);
-
- GeometryAtom ga =
- Shape3DRetained.getGeomAtom(ms);
- for(kk=0; kk<newGAArray.length; kk++) {
- if(ga == newGAArray[kk]) {
- break;
- }
- }
-
- if(kk==newGAArray.length) {
- System.err.println("Text3DRetained : Problem !!! Can't find matching geomAtom");
- }
-
- ct = ti.getCachedTargets(TargetsInterface.
- TRANSFORM_TARGETS, k, -1);
- if (ct != null) {
- newCtArr[k] = new CachedTargets();
- newCtArr[k].copy(ct);
- newCtArr[k].replace((NnuId)oldGAArray[kk],
- (NnuId)newGAArray[kk],
- Targets.GEO_TARGETS);
- } else {
- newCtArr[k] = null;
- }
-
- }
-
- ti.resetCachedTargets(
- TargetsInterface.TRANSFORM_TARGETS, newCtArr, -1);
-
- tiArrList.add(ti);
- newCtArrArrList.add(newCtArr);
-
- }
-
- }
-
- m[i].args[0] = oldGAArray;
- m[i].args[1] = newGAArray;
- m[i].universe = universeList.get(i);
-
- if(tiArrList.size() > 0) {
- m[i].args[2] = tiArrList.toArray();
- m[i].args[3] = newCtArrArrList.toArray();
- }
-
- tiArrList.clear();
- newCtArrArrList.clear();
-
- }
- VirtualUniverse.mc.processMessage(m);
- }
-
- }
- }
- }
-
-
- final void sendTransformChangedMessage() {
- J3dMessage[] m;
- int i, j, numMessages, sCnt;
- ArrayList gaList = new ArrayList();
- GeometryRetained geomR;
- synchronized(liveStateLock) {
- if (source.isLive()) {
- synchronized (universeList) {
- numMessages = universeList.size();
- m = new J3dMessage[numMessages];
- for (i=0; i<numMessages; i++) {
- m[i] = new J3dMessage();
- m[i].type = J3dMessage.TEXT3D_TRANSFORM_CHANGED;
- m[i].threads = targetThreads;
- ArrayList<Shape3DRetained> shapeList = userLists.get(i);
- // gaList = new GeometryAtom[shapeList.size() * numChars];
- for (j = 0; j < shapeList.size(); j++) {
- Shape3DRetained s = shapeList.get(j);
-
- // Find the right geometry.
- for(sCnt=0; sCnt<s.geometryList.size(); sCnt++) {
- geomR = s.geometryList.get(sCnt);
- if(geomR == this) {
- break;
- }
- }
-
- if(sCnt < s.geometryList.size())
- gaList.add(Shape3DRetained.getGeomAtom(s));
-
- }
- m[i].args[0] = gaList.toArray();
- m[i].args[1] = charTransforms;
- m[i].universe = universeList.get(i);
- }
- VirtualUniverse.mc.processMessage(m);
- }
- }
- }
- }
-
- /**
- * Update internal reprsentation of tranform matrices and geometry.
- * This method will be called whenever string or font3D change.
- */
- final void updateCharacterData() {
- char c[] = new char[1];
-
- if (geometryList.length != numChars) {
- geometryList = new GeometryArrayRetained[numChars];
- glyphVecs = new GlyphVector[numChars];
- }
-
- if (font3D != null) {
- for (int i=0; i<numChars; i++) {
- c[0] = string.charAt(i);
- glyphVecs[i] = font3D.font.createGlyphVector(font3D.frc, c);
- geometryList[i] = font3D.triangulateGlyphs(glyphVecs[i], c[0]);
- }
- }
-
- updateTransformData();
- }
-
- /**
- * Update per character transform based on Text3D location,
- * per character size and path.
- *
- * WARNING: Caller of this method must make sure SceneGraph is live,
- * else exceptions may be thrown.
- */
- final void updateTransformData(){
- int i, k=0, numTotal=0;
- double width = 0, height = 0;
- Vector3f location = new Vector3f(this.position);
- Rectangle2D bounds;
-
- //Reset bounds data
- lower.set(location);
- upper.set(location);
-
- charTransforms = new Transform3D[numChars];
- for (i=0; i<numChars; i++) {
- charTransforms[i] = new Transform3D();
- }
-
- if (numChars != 0) {
- charTransforms[0].set(location);
-
- // Set loop counters based on path type
- if (path == Text3D.PATH_RIGHT || path == Text3D.PATH_UP) {
- k = 0;
- numTotal = numChars + 1;
- } else if (path == Text3D.PATH_LEFT || path == Text3D.PATH_DOWN) {
- k = 1;
- numTotal = numChars;
- // Reset bounds to bounding box if first character
- bounds = glyphVecs[0].getVisualBounds();
- upper.x += bounds.getWidth();
- upper.y += bounds.getHeight();
- }
-
- for (i=1; i<numTotal; i++, k++) {
- width = glyphVecs[k].getLogicalBounds().getWidth();
- bounds = glyphVecs[k].getVisualBounds();
- // 'switch' could be outside loop with little hacking,
- width += charSpacing;
- height = bounds.getHeight();
-
- switch (this.path) {
- case Text3D.PATH_RIGHT:
- location.x += width;
- upper.x += (width);
- if (upper.y < (height + location.y)) {
- upper.y = location.y + height;
- }
- break;
- case Text3D.PATH_LEFT:
- location.x -= width;
- lower.x -= (width);
- if (upper.y < ( height + location.y)) {
- upper.y = location.y + height;
- }
- break;
- case Text3D.PATH_UP:
- location.y += height;
- upper.y += height;
- if (upper.x < (bounds.getWidth() + location.x)) {
- upper.x = location.x + bounds.getWidth();
- }
- break;
- case Text3D.PATH_DOWN:
- location.y -= height;
- lower.y -= height;
- if (upper.x < (bounds.getWidth() + location.x)) {
- upper.x = location.x + bounds.getWidth();
- }
- break;
- }
- if (i < numChars) {
- charTransforms[i].set(location);
- }
- }
-
- // Handle string alignment. ALIGN_FIRST is handled by default
- if (alignment != Text3D.ALIGN_FIRST) {
- double cx = (upper.x - lower.x);
- double cy = (upper.y - lower.y);
-
- if (alignment == Text3D.ALIGN_CENTER) {
- cx *= .5;
- cy *= .5;
- }
- switch (path) {
- case Text3D.PATH_RIGHT:
- for (i=0;i < numChars;i++) {
- charTransforms[i].mat[3] -= cx;
- }
- lower.x -= cx;
- upper.x -= cx;
- break;
- case Text3D.PATH_LEFT:
- for (i=0;i < numChars;i++) {
- charTransforms[i].mat[3] += cx;
- }
- lower.x += cx;
- upper.x += cx;
- break;
-
- case Text3D.PATH_UP:
- for (i=0;i < numChars;i++) {
- charTransforms[i].mat[7] -=cy;
- }
- lower.y -= cy;
- upper.y -= cy;
- break;
- case Text3D.PATH_DOWN:
- for (i=0;i < numChars;i++) {
- charTransforms[i].mat[7] +=cy;
- }
- lower.y += cy;
- upper.y += cy;
- break;
-
- }
- }
- }
-
- lower.z = 0.0f;
- if ((font3D == null) || (font3D.fontExtrusion == null)) {
- upper.z = lower.z;
- } else {
- upper.z = lower.z + font3D.fontExtrusion.length;
- }
-
- // update geoBounds
- getBoundingBox(geoBounds);
- }
-
-
- /**
- * This method is called when the SceneGraph becomes live. All characters
- * used by this.string are tesselated in this method, to avoid wait during
- * traversal and rendering.
- */
- @Override
- void setLive(boolean inBackgroundGroup, int refCount) {
- // Tesselate all character data and update character transforms
- updateCharacterData();
- super.doSetLive(inBackgroundGroup, refCount);
- super.markAsLive();
- }
-
- // TODO -- Need to rethink. Might have to consider charTransform[] in returns pickInfo.
- @Override
- boolean intersect(PickShape pickShape, PickInfo pickInfo, int flags, Point3d iPnt,
- GeometryRetained geom, int geomIndex) {
- Transform3D tempT3D = new Transform3D();
- GeometryArrayRetained geo = null;
- int sIndex = -1;
- PickShape newPS;
- double minDist = Double.MAX_VALUE;
- double distance =0.0;
- Point3d closestIPnt = new Point3d();
-
- for (int i=0; i < numChars; i++) {
- geo= geometryList[i];
- if (geo != null) {
- tempT3D.invert(charTransforms[i]);
- newPS = pickShape.transform(tempT3D);
- if (geo.intersect(newPS, pickInfo, flags, iPnt, geom, geomIndex)) {
- if (flags == 0) {
- return true;
- }
- distance = newPS.distance(iPnt);
- if (distance < minDist) {
- sIndex = i;
- minDist = distance;
- closestIPnt.set(iPnt);
- }
- }
- }
- }
-
- if (sIndex >= 0) {
- // We need to transform iPnt to the vworld to compute the actual distance.
- // In this method we'll transform iPnt by its char. offset. Shape3D will
- // do the localToVworld transform.
- iPnt.set(closestIPnt);
- charTransforms[sIndex].transform(iPnt);
- return true;
- }
- return false;
- }
-
- @Override
- boolean intersect(Point3d[] pnts) {
- Transform3D tempT3D = new Transform3D();
- GeometryArrayRetained ga;
- boolean isIntersect = false;
- Point3d transPnts[] = new Point3d[pnts.length];
- for (int j=pnts.length-1; j >= 0; j--) {
- transPnts[j] = new Point3d();
- }
-
- for (int i=numChars-1; i >= 0; i--) {
- ga = geometryList[i];
- if ( ga != null) {
- tempT3D.invert(charTransforms[i]);
- for (int j=pnts.length-1; j >= 0; j--) {
- tempT3D.transform(pnts[j], transPnts[j]);
- }
- if (ga.intersect(transPnts)) {
- isIntersect = true;
- break;
- }
- }
- }
- return isIntersect;
- }
-
-
- @Override
- boolean intersect(Transform3D thisToOtherVworld, GeometryRetained geom) {
- GeometryArrayRetained ga;
-
- for (int i=numChars-1; i >=0; i--) {
- ga = geometryList[i];
- if ((ga != null) && ga.intersect(thisToOtherVworld, geom)) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- boolean intersect(Bounds targetBound) {
- GeometryArrayRetained ga;
-
- for (int i=numChars-1; i >=0; i--) {
- ga = geometryList[i];
- if ((ga != null) && ga.intersect(targetBound)) {
- return true;
- }
- }
-
- return false;
-
- }
-
- void setModelViewMatrix(Transform3D vpcToEc, Transform3D drawTransform) {
- this.vpcToEc = vpcToEc;
- this.drawTransform = drawTransform;
- }
-
-
- @Override
- void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
- boolean updateAlpha, float alpha,
- int screen,
- boolean ignoreVertexColors) {
-
- Transform3D trans = new Transform3D();
-
- for (int i = 0; i < geometryList.length; i++) {
- trans.set(drawTransform);
- trans.mul(charTransforms[i]);
- cv.setModelViewMatrix(cv.ctx, vpcToEc.mat, trans);
- geometryList[i].execute(cv, ra, isNonUniformScale, updateAlpha, alpha,
- screen, ignoreVertexColors);
- }
- }
-
- @Override
- int getClassType() {
- return TEXT3D_TYPE;
- }
-
-
- ArrayList getUniqueSource(ArrayList shapeList) {
- ArrayList uniqueList = new ArrayList();
- int size = shapeList.size();
- Object src;
- int i, index;
-
- for (i=0; i<size; i++) {
- src = ((Shape3DRetained)shapeList.get(i)).sourceNode;
- index = uniqueList.indexOf(src);
- if (index == -1) {
- uniqueList.add(src);
- }
- }
- return uniqueList;
- }
-}
-