All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.media.j3d.Text3DRetained Maven / Gradle / Ivy

/*
 * 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; iposition field into the supplied
     * parameter.  The position 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 position field to the supplied
     * parameter.  The position 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 alignment is used to specify how
     * glyphs in the string are placed in relation to the
     * position field.  Valid values for this field
     * are:
     * 
    *
  • ALIGN_CENTER - the center of the string is placed on the * position point. *
  • ALIGN_FIRST - the first character of the string is placed on * the position point. *
  • ALIGN_LAST - the last character of the string is placed on the * position point. *
* The default value of this field is ALIGN_FIRST. * * @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 alignment is used to specify how * glyphs in the string are placed in relation to the * position field. Valid values for this field * are: *
    *
  • ALIGN_CENTER - the center of the string is placed on the * position point. *
  • ALIGN_FIRST - the first character of the string is placed on * the position point. *
  • ALIGN_LAST - the last character of the string is placed on the * position point. *
* The default value of this field is ALIGN_FIRST. * * @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 path 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: *
    *
  • PATH_LEFT: - succeeding glyphs are placed to the left of the * current glyph. *
  • PATH_RIGHT: - succeeding glyphs are placed to the right of the * current glyph. *
  • PATH_UP: - succeeding glyphs are placed above the current glyph. *
  • PATH_DOWN: - succeeding glyphs are placed below the current glyph. *
* The default value of this field is PATH_RIGHT. * * @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 path 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: *
    *
  • PATH_LEFT - succeeding glyphs are placed to the left of the * current glyph. *
  • PATH_RIGHT - succeeding glyphs are placed to the right of the * current glyph. *
  • PATH_UP - succeeding glyphs are placed above the current glyph. *
  • PATH_DOWN - succeeding glyphs are placed below the current glyph. *
* The default value of this field is PATH_RIGHT. * * @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 shapeList = userLists.get(i); newGeometryAtomList.clear(); oldGeometryAtomList.clear(); for (j=0; j 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 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= 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy