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

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

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;

/**
 * Group node that contains a transform.
 */

class TransformGroupRetained extends GroupRetained implements TargetsInterface
{

    /**
     * The Transform value for the TransformGroup.
     */
    Transform3D transform = new Transform3D();

    /**
     * The inverse of the transform
     */
    Transform3D invTransform = null;

    /**
     * The transpose of the inverse of the transform
     */
    Transform3D normalTransform = null;

    /**
     * The Transform value currently being used internally
     */
    Transform3D currentTransform = new Transform3D();

    /**
     * localVworld values for children of this TG
     */
    Transform3D[][] childLocalToVworld = null;
    int[][] 	    childLocalToVworldIndex = null;

    // working variable for children transforms
    Transform3D[][] childTrans = null;
    int[][] 	    childTransIndex = null;


    /**
     * A bitmask of the types in targets
     */
    int localTargetThreads = 0;

    // combined localTargetThreads and decendants' localTargetThreads
    int targetThreads = 0;

    /**
     * A list of WakeupOnTransformChange conditions for this Transform
     */
    WakeupIndexedList transformChange = null;

// The current list of child transform group nodes or link nodes
// under a transform group
ArrayList childTransformLinks = new ArrayList(1);

    // working area while compile
    boolean needNormalsTransform = false; // true if normals transformation
					  // is needed to push this
					  // transform down to geometry

    // key which identifies a unique path from a
    // locale to this transform group
    HashKey currentKey = new HashKey();

    boolean aboveAViewPlatform = false;

    // maximum transform level of all shared path
    int maxTransformLevel = -1;

    // List of transform level, one per shared path
    int transformLevels[] = null;

    // J3d copy.
    CachedTargets[] j3dCTs = null;

    // User copy.
    CachedTargets[] cachedTargets = null;

    // Contains per path data, XXXX: move to NodeRetained
    TransformGroupData[] perPathData = null;


    /**
     * The constructor
     */
    TransformGroupRetained() {
        this.nodeType = NodeRetained.TRANSFORMGROUP;
    }

  /**
   * Sets the transform component of this TransformGroup to the value of
   * the passed transform.
   * @param t1 the transform to be copied
   */
  void setTransform(Transform3D t1) {
      J3dMessage tchangeMessage = null;
      int i, j;
      Transform3D trans = null;

      if (staticTransform != null) {
	  // this writeable transformGroup has a static transform
	  // merged into this node

      	  trans = new Transform3D(staticTransform.transform);
	  trans.mul(t1);

      	  transform.setWithLock(trans);

      } else {
      	  trans = new Transform3D(t1);
      	  transform.setWithLock(t1);
      }

      if (transformChange != null) {
	  notifyConditions();
      }

      if (source.isLive()) {

	  if (aboveAViewPlatform && !t1.isCongruent()) {
	      throw new BadTransformException(J3dI18N.getString("ViewPlatformRetained0"));
	  }

	  tchangeMessage = new J3dMessage();
	  tchangeMessage.type = J3dMessage.TRANSFORM_CHANGED;
	  tchangeMessage.threads = targetThreads;
	  tchangeMessage.args[1] = this;
	  tchangeMessage.args[2] = trans;

	  tchangeMessage.universe = universe;
	  //System.err.println("TransformGroupRetained --- TRANSFORM_CHANGED " + this);
	  VirtualUniverse.mc.processMessage(tchangeMessage);
      }
      dirtyBoundsCache();
  }

    /**
     * Copies the transform component of this TransformGroup into
     * the passed transform object.
     * @param t1 the transform object to be copied into
     */
    void getTransform(Transform3D t1) {
	transform.getWithLock(t1);

        // if staticTransform exists for this node, need to
        // redetermine the original user specified transform

        if (staticTransform != null) {
            Transform3D invTransform = staticTransform.getInvTransform();
            t1.mul(invTransform, t1);
        }
    }


    // get the inverse of the transform -- note: this method only
    // supports static transform

    Transform3D getInvTransform() {
        if (invTransform == null) {
            invTransform = new Transform3D(transform);
            invTransform.invert();
        }
	return invTransform;
    }


    // get the inverse of the transpose -- note: this method only
    // supports static transform, the translation component will
    // not transform
    Transform3D getNormalTransform() {
	if (normalTransform == null) {
            normalTransform = new Transform3D(transform);
	    normalTransform.invert();
	    normalTransform.transpose();
        }
	return normalTransform;
    }

    // synchronized with TransformStructure
    @Override
    synchronized void setNodeData(SetLiveState s) {
	int i;

        super.setNodeData(s);

        childTrans = new Transform3D[s.currentTransforms.length][2];
        childTransIndex = new int[s.currentTransforms.length][2];

        for (i=0; i< s.currentTransforms.length; i++) {
            childTrans[i][0] = new Transform3D();

            childTrans[i][0].mul(s.currentTransforms[i]
                                   [s.currentTransformsIndex[i]
                                   [CURRENT_LOCAL_TO_VWORLD]], currentTransform);
            childTrans[i][1] = new Transform3D(childTrans[i][0]);
            childTransIndex[i][0] = 0;
            childTransIndex[i][1] = 0;

        }

        if (!s.inSharedGroup) {
            s.transformLevels[0] += 1;
            maxTransformLevel = s.transformLevels[0];
        } else {
            for (i=0; i maxTransformLevel) {
                    maxTransformLevel = s.transformLevels[i];
                }
            }
        }

	if (!inSharedGroup) {
	    if (childLocalToVworld == null) {
		// If the node is a transformGroup then need to keep
		// the child transforms as well
		childLocalToVworld = new Transform3D[1][];
		childLocalToVworldIndex = new int[1][];
		transformLevels = new int[1];
		// Use by TransformStructure
                cachedTargets = new CachedTargets[1];
                perPathData = new TransformGroupData[1];
	    }
	    childLocalToVworld[0] = childTrans[0];
	    childLocalToVworldIndex[0] = childTransIndex[0];
            transformLevels[0] = s.transformLevels[0];

	    setAuxData(s, 0, 0);
	} else {

	    // For inSharedGroup case.
	    int j, len;

	    if (childLocalToVworld == null) {
	        childLocalToVworld = new Transform3D[s.keys.length][];
	        childLocalToVworldIndex = new int[s.keys.length][];
                transformLevels = new int[s.keys.length];
                cachedTargets = new CachedTargets[s.keys.length];
                perPathData = new TransformGroupData[s.keys.length];
	        len=0;
	    } else {

	        len = localToVworld.length - s.keys.length;

	        int newLen = localToVworld.length;

	        Transform3D newChildTList[][] = new Transform3D[newLen][];
	        int newChildIndexList[][] = new int[newLen][];
	        int newTransformLevels[] = new int[newLen];
                CachedTargets newTargets[] = new CachedTargets[newLen];
                TransformGroupData newPerPathData[] = new TransformGroupData[newLen];

	        System.arraycopy(childLocalToVworld, 0,
			     newChildTList, 0, childLocalToVworld.length);
	        System.arraycopy(childLocalToVworldIndex, 0,
			     newChildIndexList, 0, childLocalToVworldIndex.length);
	        System.arraycopy(transformLevels, 0,
			     newTransformLevels, 0, transformLevels.length);

                System.arraycopy(cachedTargets, 0,
                             newTargets, 0, cachedTargets.length);

                System.arraycopy(perPathData, 0,
                             newPerPathData, 0, perPathData.length);

	        childLocalToVworld = newChildTList;
	        childLocalToVworldIndex = newChildIndexList;
	        transformLevels = newTransformLevels;
                cachedTargets = newTargets;
		perPathData = newPerPathData;
	    }

	    int hkIndex;
	    int hkIndexPlus1, blkSize;

	    for(i=len, j=0; i= i) { // Append to last.
		    childLocalToVworld[i] = childTrans[j];
		    childLocalToVworldIndex[i] = childTransIndex[j];
		    transformLevels[i] = s.transformLevels[j];
	        } else {
		    hkIndexPlus1 = hkIndex + 1;
		    blkSize = i - hkIndex;

		    System.arraycopy(childLocalToVworld, hkIndex,
				 childLocalToVworld, hkIndexPlus1, blkSize);

		    System.arraycopy(childLocalToVworldIndex, hkIndex,
				 childLocalToVworldIndex, hkIndexPlus1, blkSize);

		    System.arraycopy(transformLevels, hkIndex,
				 transformLevels, hkIndexPlus1, blkSize);

                    System.arraycopy(cachedTargets, hkIndex,
                                 cachedTargets, hkIndexPlus1, blkSize);

                    System.arraycopy(perPathData, hkIndex,
                                 perPathData, hkIndexPlus1, blkSize);

		    childLocalToVworld[hkIndex] = childTrans[j];
		    childLocalToVworldIndex[hkIndex] = childTransIndex[j];
		    transformLevels[hkIndex] = s.transformLevels[j];
	        }

	        setAuxData(s, j, hkIndex);
	    }
	}
        if (s.childTransformLinks != null) {
            // do not duplicate shared nodes
            synchronized(s.childTransformLinks) {
                if(!inSharedGroup || !s.childTransformLinks.contains(this)) {
                    s.childTransformLinks.add(this);
                }
            }
        }

	s.localToVworld = childLocalToVworld;
	s.localToVworldIndex = childLocalToVworldIndex;
        s.currentTransforms = childTrans;
        s.currentTransformsIndex = childTransIndex;

        s.childTransformLinks = childTransformLinks;
        s.parentTransformLink = this;
    }

    @Override
    void setAuxData(SetLiveState s, int index, int hkIndex) {
        super.setAuxData(s, index, hkIndex);
        perPathData[hkIndex] = new TransformGroupData();
	perPathData[hkIndex].switchState = s.switchStates.get(hkIndex);
    }


    // Add a WakeupOnTransformChange to the list
    void removeCondition(WakeupOnTransformChange wakeup) {
	synchronized (transformChange) {
	    transformChange.remove(wakeup);
	}
    }

    // Add a WakeupOnTransformChange to the list
    void addCondition(WakeupOnTransformChange wakeup) {
	synchronized (transformChange) {
	    transformChange.add(wakeup);
	}
    }

    void notifyConditions() {
	synchronized (transformChange) {
	    WakeupOnTransformChange list[] = (WakeupOnTransformChange [])
		transformChange.toArray(false);
	    for (int i=transformChange.size()-1; i >=0; i--) {
		list[i].setTriggered();
	    }
	}
    }

    @Override
    boolean isStatic() {
	if (!super.isStatic() ||
	    source.getCapability(TransformGroup.ALLOW_TRANSFORM_READ) ||
	    source.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE)) {
	    return false;
	} else {
	    return true;
	}
    }

    @Override
    void mergeTransform(TransformGroupRetained xform) {
	super.mergeTransform(xform);
	transform.mul(xform.transform, transform);
    }

    @Override
    void traverse(boolean sameLevel, int level) {

	System.err.println();
	for (int i = 0; i < level; i++) {
	     System.err.print(".");
	}
	System.err.print(this);

	if (isStatic()) {
	    System.err.print(" (s)");
	} else {
	    System.err.print(" (w)");
	}
	System.err.println();
	System.err.println(transform.toString());
	super.traverse(true, level);
    }

    @Override
    void compile(CompileState compState) {

	// save and reset the keepTG and needNormalsTransform flags

	boolean saveKeepTG = compState.keepTG;
	compState.keepTG = false;

	boolean saveNeedNormalsTransform = compState.needNormalsTransform;
        compState.needNormalsTransform = false;

	super.compile(compState);

	if (compState.keepTG) {
	    // keep this transform group, don't merge it

	    mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
	}

	if (J3dDebug.devPhase && J3dDebug.debug) {
	    compState.numTransformGroups++;
	    if (isStatic())
		compState.numStaticTransformGroups++;
	    if (mergeFlag == SceneGraphObjectRetained.MERGE)
		compState.numMergedTransformGroups++;
        }

	if (mergeFlag == SceneGraphObjectRetained.DONT_MERGE) {
	    // a non-mergeable TG will trigger a merge of its subtree

	    compState.staticTransform = null;
	    compState.parentGroup = null;
	    super.merge(compState);

	} else {
	    // flag this TG as to be merged later on
	    mergeFlag = SceneGraphObjectRetained.MERGE;
	}

	// restore compile state
	compState.keepTG = saveKeepTG;
	this.needNormalsTransform = compState.needNormalsTransform;
        compState.needNormalsTransform = saveNeedNormalsTransform;
    }

    @Override
    void merge(CompileState compState) {

	TransformGroupRetained saveStaticTransform;

	// merge the transforms
	if (compState.staticTransform != null) {
	    staticTransform = compState.staticTransform;
	    mergeTransform(compState.staticTransform);
	}

	if (mergeFlag == SceneGraphObjectRetained.MERGE) {

	    // before we push down the static transform, check
	    // to see if the transform will be pushed down to shapes
	    // with geometry_with_normals and if so, check if
            // the normal transform has uniform scale or not. If
	    // it doesn't, don't push it down.

	    if (this.needNormalsTransform) {
		Transform3D normalXform = this.getNormalTransform();
		if (!normalXform.isCongruent()) {
		    mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
		}
	    }
	}

	if (mergeFlag == SceneGraphObjectRetained.MERGE) {
	    saveStaticTransform = compState.staticTransform;
	    compState.staticTransform = this;

	    // go to the merge method of the group node to start
	    // pushing down the static transform until it hits
	    // a leaf or a subtree which is already merged.
	    super.merge(compState);

	    // reset the compile state
	    compState.staticTransform = saveStaticTransform;

	} else {
	    compState.parentGroup.compiledChildrenList.add(this);
	    parent = compState.parentGroup;
	}

	mergeFlag = SceneGraphObjectRetained.MERGE_DONE;
    }

    /**
     * This setlive simply concatinates it's transform onto all the ones
     * passed in.
     */
    @Override
    void setLive(SetLiveState s) {
      int i,j;
      Transform3D trans = null;
      Targets[] newTargets = null;
      Targets[] savedTransformTargets = null;
      int oldTraverseFlags = 0;
      int len;
      Object obj;

      // XXXX - optimization for targetThreads computation, require
      // cleanup in GroupRetained.doSetLive()
      //int savedTargetThreads = 0;
      //savedTargetThreads = s.transformTargetThreads;
      //s.transformTargetThreads = 0;

      oldTraverseFlags = s.traverseFlags;

      savedTransformTargets = s.transformTargets;

      int numPaths = (s.inSharedGroup)? s.keys.length : 1;
      newTargets = new Targets[numPaths];
      for(i=0; i savedChildTransformLinks = s.childTransformLinks;
      GroupRetained savedParentTransformLink = s.parentTransformLink;
      Transform3D[][] oldCurrentList = s.currentTransforms;
      int[][] oldCurrentIndexList = s.currentTransformsIndex;


      super.doSetLive(s);


      if (! inSharedGroup) {
          if (s.transformTargets[0] != null) {
              cachedTargets[0] = s.transformTargets[0].snapShotInit();
          }
          if (s.switchTargets != null &&
                        s.switchTargets[0] != null) {
              s.switchTargets[0].addNode(this, Targets.GRP_TARGETS);
	  }
      } else {
          int hkIndex;
          for(i=0; i obj;
                    if (parentTransformLink
                        instanceof TransformGroupRetained) {
                        obj = ((TransformGroupRetained)
                            parentTransformLink).childTransformLinks;
                    } else {
                        obj = ((SharedGroupRetained)
                            parentTransformLink).childTransformLinks;
                    }
                    synchronized(obj) {
                        obj.remove(this);
                    }
                }
	        aboveAViewPlatform = false;
	    }
	    else {
		int i, index, len;
		// Remove the localToVworld key
		int newLen = localToVworld.length - s.keys.length;

		Transform3D[][] newChildTList = new Transform3D[newLen][];
		int[][] newChildIndexList = new int[newLen][];
		int[] newTransformLevels = new int[newLen];
		ArrayList[] newChildPTG = new ArrayList[newLen];
		CachedTargets[] newTargets = new CachedTargets[newLen];
                TransformGroupData[] newPerPathData = new TransformGroupData[newLen];

		int[] tempIndex = new int[s.keys.length];
		int curStart =0, newStart =0;
		boolean found = false;
		for(i=0;i= 0) {
			found = true;

			if(index == curStart) {
			    curStart++;
			}
			else {
			    len = index - curStart;
			    System.arraycopy(childLocalToVworld, curStart, newChildTList,
					     newStart, len);
			    System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList,
					     newStart, len);
			    System.arraycopy(transformLevels, curStart, newTransformLevels,
					     newStart, len);
			    System.arraycopy(cachedTargets, curStart, newTargets, newStart, len);
                            System.arraycopy(perPathData, curStart,
                                                newPerPathData, newStart, len);

			    curStart = index+1;
			    newStart = newStart + len;
			}
		    }
		    else {
			found = false;
			MasterControl.getCoreLogger().severe("TG.removeNodeData-Can't find matching hashKey.");
		    }
		}

		if((found == true) && (curStart < localToVworld.length)) {
		    len = localToVworld.length - curStart;
		    System.arraycopy(childLocalToVworld, curStart, newChildTList,
				     newStart, len);
		    System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList,
				     newStart, len);
		    System.arraycopy(transformLevels, curStart, newTransformLevels,
				     newStart, len);
		    System.arraycopy(cachedTargets, curStart, newTargets, newStart, len);
                    System.arraycopy(perPathData, curStart,
                                                newPerPathData, newStart, len);
		}

		childLocalToVworld = newChildTList;
		childLocalToVworldIndex = newChildIndexList;
		transformLevels = newTransformLevels;
		cachedTargets = newTargets;
                perPathData = newPerPathData;
	    }
            super.removeNodeData(s);
	    // Set it back to its parent localToVworld data.
	    // This is b/c the parent has changed it localToVworld data arrays.
	    s.localToVworld = childLocalToVworld;
	    s.localToVworldIndex = childLocalToVworldIndex;
	}
    }

    @Override
    void clearLive(SetLiveState s) {

        Targets[] savedTransformTargets = null;

        savedTransformTargets = s.transformTargets;
	// no need to gather targets from tg in clear live
        s.transformTargets = null;

	super.clearLive(s);

        // restore setLiveState from it's local variables.
        // removeNodeData has altered these variables.
        s.localToVworld = localToVworld;
        s.localToVworldIndex = localToVworldIndex;
        s.transformTargets = savedTransformTargets;

	synchronized (this) { // synchronized with TransformStructure
	if (inSharedGroup) {
            if (transformLevels != null) {
                maxTransformLevel = transformLevels[0];
                for (int i=1; i maxTransformLevel) {
                       maxTransformLevel = transformLevels[i];
                   }
               }
            } else {
		maxTransformLevel = -1;
	    }

            if (s.switchTargets != null) {
                for (int i=0; i=0; i--) {
			NodeRetained child = children.get(i);
		if(child != null)
		    child.computeCombineBounds(boundingObject);
	    }

            if (VirtualUniverse.mc.cacheAutoComputedBounds) {
                cachedBounds = (Bounds) boundingObject.clone();
            }
	}
	else {
	    // Should this be lock too ? ( MT safe  ? )
	    synchronized(localBounds) {
		boundingObject.set(localBounds);
	    }
	}

        // Should this be lock too ? ( MT safe  ? )
	// Thoughts :
	// Make a temp copy with lock :  transform.getWithLock(trans);, but this will cause gc ...
	synchronized(transform) {
	    boundingObject.transform(transform);
	}
	bounds.combine(boundingObject);

    }

    void processChildLocalToVworld(ArrayList dirtyTransformGroups,
                                                ArrayList keySet,
						UpdateTargets targets,
						ArrayList blUsers) {

	synchronized(this) { // sync with setLive/clearLive

	    if (inSharedGroup) {
		if (localToVworldKeys != null) {
		    for(int j=0; j dirtyTransformGroups,
				  ArrayList keySet,
				  UpdateTargets targets,
				  ArrayList blUsers) {

	int i, j;
	Transform3D lToVw, childLToVw;
	TransformGroupRetained tg;
	LinkRetained ln;
	CachedTargets ct;

	synchronized(this) { // sync with setLive/clearLive

	    if (localToVworld != null) {
		perPathData[index].markedDirty = false;
		// update immediate child's localToVworld

		if (perPathData[index].switchState.currentSwitchOn ) {
		    lToVw = getCurrentLocalToVworld(index);
		    childLToVw = getUpdateChildLocalToVworld(index);
		    childLToVw.mul(lToVw, currentTransform);
		    dirtyTransformGroups.add(this);
		    keySet.add(key);
                    ct = j3dCTs[index];
                    if (ct != null) {
                        targets.addCachedTargets(ct);
                        if (ct.targetArr[Targets.BLN_TARGETS] != null) {
                            gatherBlUsers(blUsers,
					ct.targetArr[Targets.BLN_TARGETS]);
                        }
                    }
		} else {
		    perPathData[index].switchDirty = true;
		    //System.err.println("tg.updateChild skip");
		}



		// update child's localToVworld of its children
		// transformLink may contain link nodes
		synchronized(childTransformLinks) {
		    for (i=0; i dirtyTransformGroups,
                                  ArrayList keySet,
				  UpdateTargets targets,
				  ArrayList blUsers) {
	int i, j;
	Transform3D lToVw, childLToVw;
	TransformGroupRetained tg;
        LinkRetained ln;
	CachedTargets ct;

	synchronized(this) { // sync with setLive/clearLive

	    if (localToVworld != null) {
		perPathData[0].markedDirty = false;
		// update immediate child's localToVworld

		if (perPathData[0].switchState.currentSwitchOn ) {
		    lToVw = getCurrentLocalToVworld(0);
		    childLToVw = getUpdateChildLocalToVworld(0);
		    childLToVw.mul(lToVw, currentTransform);
		    dirtyTransformGroups.add(this);
                    ct = j3dCTs[0];
		    if (ct != null) {
		        targets.addCachedTargets(ct);
		        if (ct.targetArr[Targets.BLN_TARGETS] != null) {
                            gatherBlUsers(blUsers,
					ct.targetArr[Targets.BLN_TARGETS]);
		        }
		    }
		} else {
		    perPathData[0].switchDirty = true;
		    //System.err.println("tg.updateChild skip");
		}


		// update child's localToVworld of its children
		// transformLink contains top level transform group nodes
		// and link nodes
		synchronized(childTransformLinks) {
		    for (i=0; i= 0) {
		return childLocalToVworld[i]
		    [childLocalToVworldIndex[i][NodeRetained.CURRENT_LOCAL_TO_VWORLD]];
	    }
	}
        return new Transform3D();
    }


    /**
     * Get the last child localToVworld transform for a node
     */
    Transform3D getLastChildLocalToVworld(HashKey key) {

        if (!inSharedGroup) {
            return childLocalToVworld[0][childLocalToVworldIndex[0][NodeRetained.LAST_LOCAL_TO_VWORLD]];
        } else {
	    int i = key.equals(localToVworldKeys, 0, localToVworldKeys.length);
	    if(i>= 0) {
		return childLocalToVworld[i]
		    [childLocalToVworldIndex[i][NodeRetained.LAST_LOCAL_TO_VWORLD]];
            }
        }
        return new Transform3D();
    }

    // ****************************
    // TargetsInterface methods
    // ****************************

    @Override
    public int getTargetThreads(int type) {
        // type is ignored here, only need for SharedGroup
        if (type == TargetsInterface.TRANSFORM_TARGETS) {
	    return targetThreads;
	} else {
	    System.err.println("getTargetsThreads: wrong arguments");
	    return -1;
	}
    }

    @Override
    public CachedTargets getCachedTargets(int type, int index, int child) {
        // type is ignored here, only need for SharedGroup
        // child is ignored here
        if (type == TargetsInterface.TRANSFORM_TARGETS) {
	    return cachedTargets[index];
	} else {
	    System.err.println("getCachedTargets: wrong arguments");
	    return null;
	}
    }

    @Override
    TargetsInterface getClosestTargetsInterface(int type) {
        return (type == TargetsInterface.TRANSFORM_TARGETS)?
                (TargetsInterface)this:
                (TargetsInterface)parentSwitchLink;
    }

    // re-evalute localTargetThreads using newCachedTargets and
    // re-evaluate targetThreads
    @Override
    public void computeTargetThreads(int type,
				CachedTargets[] newCachedTargets) {

        // type is ignored here, only need for SharedGroup
        if (type == TargetsInterface.TRANSFORM_TARGETS) {
            localTargetThreads = J3dThread.UPDATE_TRANSFORM;

	    for(int i=0; i getTargetsData(int type, int index) {
	// not used
	return null;
}

    @Override
    void childCheckSetLive(NodeRetained child, int childIndex,
                                SetLiveState s, NodeRetained linkNode) {
        s.currentTransforms = childLocalToVworld;
        s.currentTransformsIndex = childLocalToVworldIndex;
        s.parentTransformLink = this;
        s.childTransformLinks = childTransformLinks;
        s.localToVworld = s.currentTransforms;
        s.localToVworldIndex = s.currentTransformsIndex;

        child.setLive(s);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy