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

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

The newest version!
/*
 * Copyright 1999-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.Arrays;
import java.util.HashSet;
import java.util.Iterator;

/**
 * A transform update is a object that manages TransformGroups
 */

class TransformStructure extends J3dStructure implements ObjectUpdate {

    /**
     * A set of TransformGroups and associated Transform3Ds to traverse
     */
    private HashSet transformSet = new HashSet();

    private ArrayList objectList = new ArrayList();

    /**
     * arraylist of the bounding leaf users affected by the transform
     */
    private ArrayList blUsers = new ArrayList();

    // to gather transform targets
    private UpdateTargets targets = new UpdateTargets();

    /**
     * An arrayList of nodes that need collisionBounds updates
     */
    private ArrayList collisionObjectList = new ArrayList();

// List of dirty TransformGroups
private ArrayList dirtyTransformGroups = new ArrayList();

    // Associated Keys with the dirtyNodeGroup
    private ArrayList keySet = new ArrayList();

    // the active list contains changed TransformGroup minus those that
    // have been switched-off, plus those that have been changed but
    // just switched-on
    private ArrayList activeTraverseList =
            new ArrayList();

    // contains TG that have been previously changed but just switched-on
    private ArrayList switchDirtyTgList = new ArrayList(1);

    private boolean lazyUpdate = false;

    // ArrayList of switches that have changed, use for lastSwitchOn updates
    private ArrayList switchChangedList = new ArrayList();

    // true if already in MasterControl's update object list
    private boolean inUpdateObjectList = false;

    /**
     * This constructor does nothing
     */
    TransformStructure(VirtualUniverse u) {
	super(u, J3dThread.UPDATE_TRANSFORM);
    }

    @Override
    void processMessages(long referenceTime) {
	J3dMessage[] messages = getMessages(referenceTime);
	int nMsg = getNumMessage();
	J3dMessage m;
	int i;

	if (nMsg <= 0) {
	    return;
	}

	targets.clearNodes();
	objectList.clear();
	blUsers.clear();
	inUpdateObjectList = false;

	synchronized (universe.sceneGraphLock) {
	    // first compact the TRANSFORM_CHANGED messages by going
	    // backwards through the messages
	    for (i = (nMsg-1); i >= 0; i--) {
		m = messages[i];
		if (m.type == J3dMessage.TRANSFORM_CHANGED) {
		    // Add the TG and associated transform. Since this is a
                    // set, duplicates will be culled.
                    transformSet.add(new TransformData((TransformGroupRetained)m.args[1], (Transform3D)m.args[2]));
		}
	    }

	    for (i=0; i 0) {
		processGeometryAtomVwcBounds();
	    }
	    processVwcBounds();
	}

        // Issue 434: clear references to objects that have been processed
        objectList.clear();

	Arrays.fill(messages, 0, nMsg, null);
    }

    void processCurrentLocalToVworld() {
	int i, j, tSize, sSize;
	TransformGroupRetained tg;
	BranchGroupRetained bgr;
	Transform3D t;
        TransformGroupData data;

	lazyUpdate = false;

        tSize = transformSet.size();
        sSize = switchDirtyTgList.size();
        if (tSize <= 0 && sSize <= 0) {
            return;
        }

        // process TG with setTransform changes
	// update Transform3D, switchDirty and lToVwDrity flags
	if (tSize > 0) {
            Iterator it = transformSet.iterator();
            while(it.hasNext()) {
                TransformData lData = it.next();
                tg = lData.getTransformGroupRetained();
                tg.currentTransform.set(lData.getTransform3D());

                synchronized(tg) { // synchronized with tg.set/clearLive
                if(tg.perPathData != null) {
                  if (! tg.inSharedGroup) {
                    data = tg.perPathData[0];
                    if (! data.switchState.inSwitch) {
                        // always add to activetraverseList if not in switch
                        activeTraverseList.add(tg);
                        data.markedDirty = true;
                        data.switchDirty = false;
                    } else {
                        // if in switch, add to activetraverseList only if it is
                        // currently switched on, otherwise, mark it as
                        // switchDirty
                        if (data.switchState.currentSwitchOn) {
                            activeTraverseList.add(tg);
                            data.switchDirty = false;
                            data.markedDirty = true;
                        } else {
                            data.switchDirty = true;
                            data.markedDirty = false;
                        }
                    }
                  } else {
                    int npaths = tg.perPathData.length;
                    boolean added = false;

                    for (int k=0; k 0) {
            activeTraverseList.addAll(switchDirtyTgList);
            switchDirtyTgList.clear();
	    lazyUpdate = true;
        }

        // activeTraverseList contains switched-on tg as well
        tSize = activeTraverseList.size();
        TransformGroupRetained[] tgs = activeTraverseList.toArray(new TransformGroupRetained[tSize]);

        // process active TGs
        if (tSize > 0) {

            sortTransformGroups(tSize, tgs);

            // update lToVw and gather targets
            for (i=0; i0 &&
		 (tgs[j-1].maxTransformLevel > tgs[j].maxTransformLevel); j--) {
                TransformGroupRetained tmptg = tgs[j];
                tgs[j] = tgs[j-1];
                tgs[j-1] = tmptg;
            }
        }
    }

    private void quicksort( int l, int r, TransformGroupRetained[] tgs ) {
        int i = l;
        int j = r;
        double k = tgs[(l+r) / 2].maxTransformLevel;
        do {
            while (tgs[i].maxTransformLevel 0) {
            SwitchState switchState;

            for (int i = 0; i < size; i++) {
                switchState  = (SwitchState)switchChangedList.get(i);
                switchState.updateLastSwitchOn();
            }
            switchChangedList.clear();
        }
    }


    void processLastLocalToVworld() {
	int i, j, k;
	HashKey key;


	int dTGSize = dirtyTransformGroups.size();
	if (J3dDebug.devPhase && J3dDebug.debug) {
	    J3dDebug.doDebug(J3dDebug.transformStructure, J3dDebug.LEVEL_5,
                        "processLastLocalToVworld(): dTGSize= " + dTGSize + "\n");
	}

	for (i=0, k=0; i < dTGSize; i++) {
		TransformGroupRetained tg  = dirtyTransformGroups.get(i);
	    // Check if the transformGroup is still alive

	    // XXXX: This is a hack, should be fixed after EA
	    // Null pointer checking should be removed!
	    // should call trans = tg.getCurrentChildLocalToVworld(key);
	    synchronized(tg) {
		if (tg.childLocalToVworld != null) {
		    if (tg.inSharedGroup) {
			key = (HashKey) keySet.get(k++);
			for (j=0; j 0) {
	    // update SwitchState's CurrentSwitchOn flag
            SwitchState switchState;
            for (int j=0; j




© 2015 - 2024 Weber Informatics LLC | Privacy Policy