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

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

/*
 * 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 java.util.Arrays;
import java.util.BitSet;

/**
 *  The switch node controls which one of its children will be rendered.
 */

class SwitchRetained extends GroupRetained implements TargetsInterface
{
    static final int GEO_NODES		= 0x0001;
    static final int ENV_NODES		= 0x0002;
    static final int BEHAVIOR_NODES	= 0x0004;
    static final int SOUND_NODES	= 0x0008;
    static final int BOUNDINGLEAF_NODES	= 0x0010;

    /**
     * The value specifing which child to render.
     */
    int whichChild = Switch.CHILD_NONE;

    /**
     * The BitSet specifying which children are to be selected for
     * rendering. This is used ONLY if whichChild is set to CHILD_MASK.
     */
    BitSet	childMask = new BitSet();

    /**
     * The childmask bitset used for rendering
     */
    BitSet 	renderChildMask = new BitSet();

    // A boolean indication that something changed
    boolean isDirty = true;

// switchLevel per key, used in traversing switch children
ArrayList switchLevels = new ArrayList(1);

    // key which identifies a unique path from a locale to this switch link
    HashKey switchKey = new HashKey();

    // switch index counter to identify specific children
    int switchIndexCount = 0;

    // for message processing
    UpdateTargets updateTargets = null;

ArrayList> childrenSwitchStates = null;

    SwitchRetained() {
        this.nodeType = NodeRetained.SWITCH;
    }

    /**
     * Sets which child should be drawn.
     * @param whichChild the child to choose during a render operation
     */
    // synchronized with clearLive
    synchronized void setWhichChild(int whichChild, boolean updateAlways) {

        int i, nchildren;

        this.whichChild = whichChild;
	isDirty = true;

        if (source != null && source.isLive()) {
            updateTargets = new UpdateTargets();
            ArrayList updateList = new ArrayList(1);
            nchildren = children.size();
            switch (whichChild) {
            case Switch.CHILD_ALL:
                for (i=0; i this.childMask.size()) {
	    nbits = childMask.size();
	} else {
	    nbits = this.childMask.size();
	}

	for (i=0; i updateList = new ArrayList(1);
            nchildren = children.size();
            for (i=0; i updateList) {

        J3dMessage m ;
        int i,j,size,threads;
        Object[] nodesArr, nodes;

        threads = updateTargets.computeSwitchThreads();

        if (threads > 0) {

            m = new J3dMessage();
            m.type = J3dMessage.SWITCH_CHANGED;
            m.universe = universe;
            m.threads = threads;
            m.args[0] = updateTargets;
            m.args[2] = updateList;
            UnorderList blnList =
                        updateTargets.targetList[Targets.BLN_TARGETS];

            if (blnList != null) {
                BoundingLeafRetained mbleaf;
                size = blnList.size();

                Object[] boundingLeafUsersArr = new Object[size];
                nodesArr = blnList.toArray(false);
                for (j=0; j= children.size()))
	    return null;
	else
	    return getChild(whichChild);
    }

void updateSwitchChild(int child, boolean switchOn, ArrayList updateList) {
        int i;
        int switchLevel;

        if (inSharedGroup) {
            for (i=0; i switchStates;

	// Group's setAuxData()
	super.setAuxData(s, index, hkIndex);
	switchLevels.add(new Integer(s.switchLevels[index]));
	int nchildren = children.size();
        for (int i=0; i= 0) {
                    setAuxData(s, j, hkIndex);
                } else {
                    MasterControl.getCoreLogger().severe("Can't Find matching hashKey in setNodeData.");
                }
                s.hashkeyIndex[j] = hkIndex;
            }
        }
    }

    @Override
    void setLive(SetLiveState s) {
    	int i,j,k;
        boolean switchOn;
	SwitchRetained switchRoot;
	int size;

        // save setLiveState
        Targets[] savedSwitchTargets = s.switchTargets;
	ArrayList savedSwitchStates = s.switchStates;
        SwitchRetained[] savedClosestSwitchParents = s.closestSwitchParents;
        int[] savedClosestSwitchIndices = s.closestSwitchIndices;
        ArrayList savedChildSwitchLinks = s.childSwitchLinks;
        GroupRetained savedParentSwitchLink = s.parentSwitchLink;
        int[] savedHashkeyIndex = s.hashkeyIndex;

        // update setLiveState for this node
        s.closestSwitchParents = (SwitchRetained[])
					savedClosestSwitchParents.clone();
        s.closestSwitchIndices = Arrays.copyOf(savedClosestSwitchIndices, savedClosestSwitchIndices.length);

        // Note that s.containsNodesList is updated in super.setLive
        // Note that s.closestSwitchIndices is updated in super.setLive
        for (i=0; i< s.switchLevels.length; i++) {
            s.switchLevels[i]++;
            s.closestSwitchParents[i] = this;
        }

        super.doSetLive(s);

        initRenderChildMask();

	// update switch leaves' compositeSwitchMask
	// and update switch leaves' switchOn flag if this is top level switch
        if (inSharedGroup) {
            for (i=0; i switchStates;

	if (refCount <= 0) {
        // remove this node from parentSwitchLink's childSwitchLinks
        // clear childSwitchLinks
            if (parentSwitchLink != null) {
                for(i=0; i switchLinks = parentSwitchLink.childrenSwitchLinks.get(i);
                    if (switchLinks.contains(this)) {
                        switchLinks.remove(this);
                        break;
                    }
		}
            }
            for (j=0; j= 0; i--) {
                hkIndex = s.keys[i].equals(localToVworldKeys, 0,
                                        localToVworldKeys.length);
                if(hkIndex >= 0) {
                    for (j=0; j updateList) {
	int i,j,k;
	SwitchRetained sw;
	LinkRetained ln;
	Object obj;

	boolean newSwChanged = false;
        ArrayList childSwitchStates = childrenSwitchStates.get(child);
        SwitchState switchState = childSwitchStates.get(index);
        switchState.updateCompositeSwitchMask(switchLevel, switchOn);

        if (switchRoot != null) {
            if (init) {
                if (!switchState.initialized) {
                    switchState.initSwitchOn();
                }
            } else {
                boolean compositeSwitchOn = switchState.evalCompositeSwitchOn();
                if (switchState.cachedSwitchOn != compositeSwitchOn) {
                    switchState.updateCachedSwitchOn();

                    switchRoot.updateTargets.addCachedTargets(
						switchState.cachedTargets);
                    newSwChanged = true;
                    updateList.add(switchState);
                }
            }
        }


	ArrayList childSwitchLinks = childrenSwitchLinks.get(child);
	int cslSize =childSwitchLinks.size();
        for (i=0; i= 0 &&
                    whichChild < children.size()) {

			NodeRetained child = children.get(whichChild);
                if (child != null) {
                    child.computeCombineBounds(boundingObject);
                }
            }

            return boundingObject;
        } else {
            return super.getBounds();
        }
    }


    /*
    void compile(CompileState compState) {
	setCompiled();
	compState.startGroup(null); // don't merge at this level
	compileChildren(compState);
	compState.endGroup();
    }
    */

    /**
     * Compiles the children of the switch, preventing shape merging at
     * this level or above
     */
    @Override
    void compile(CompileState compState) {


        super.compile(compState);

	// don't remove this group node
        mergeFlag = SceneGraphObjectRetained.DONT_MERGE;

        if (J3dDebug.devPhase && J3dDebug.debug) {
            compState.numSwitches++;
        }
    }

    @Override
    void insertChildrenData(int index) {
        if (childrenSwitchStates == null) {
		childrenSwitchStates = new ArrayList>(1);
            childrenSwitchLinks = new ArrayList>(1);
        }

        childrenSwitchLinks.add(index, new ArrayList(1));

	ArrayList switchStates = new ArrayList(1);
        childrenSwitchStates.add(index, switchStates);
        if (source != null && source.isLive()) {
            for (int i=0; i>(1);
            childrenSwitchLinks = new ArrayList>(1);
        }
        childrenSwitchLinks.add(new ArrayList(1));

        ArrayList switchStates = new ArrayList(1);
        childrenSwitchStates.add(switchStates);
        if (source != null && source.isLive()) {
            for (int i=0; i oldSwitchStates = childrenSwitchStates.get(index);
        oldSwitchStates.clear();
        childrenSwitchStates.remove(index);

        ArrayList oldSwitchLinks = childrenSwitchLinks.get(index);
        oldSwitchLinks.clear();
        childrenSwitchLinks.remove(index);
    }

    @Override
    void childDoSetLive(NodeRetained child, int childIndex, SetLiveState s) {

        int numPaths = (inSharedGroup)? s.keys.length : 1;
        s.childSwitchLinks = childrenSwitchLinks.get(childIndex);
        for (int j=0; j< numPaths; j++) {
            s.closestSwitchIndices[j] = switchIndexCount;
            s.closestSwitchParents[j] = this;
        }
        // use switchIndexCount instead of child index to avoid
        // reordering due to add/remove child later
        switchIndexCount++;

        Targets[] newTargets = new Targets[numPaths];
        for(int i=0; i switchStates = childrenSwitchStates.get(child);
            if (index < switchStates.size()) {
                SwitchState switchState = switchStates.get(index);
                return switchState.cachedTargets;
            } else {
                return null;
	    }
        } else {
            System.err.println("getCachedTargets: wrong arguments");
            return null;
        }
    }

    @Override
    public void resetCachedTargets(int type,
			CachedTargets[] newCtArr, int child) {
        if (type == TargetsInterface.SWITCH_TARGETS) {
            ArrayList switchStates = childrenSwitchStates.get(child);
            if (newCtArr.length != switchStates.size()) {
                System.err.println("resetCachedTargets: unmatched length!" +
				   newCtArr.length + " " + switchStates.size());
                System.err.println("  resetCachedTargets: " + this);
            }
            SwitchState switchState;
            for (int i=0; i getTargetsData(int type, int child) {
	if (type == TargetsInterface.SWITCH_TARGETS) {
		return childrenSwitchStates.get(child);
	}
	else {
		System.err.println("getTargetsData: wrong arguments");
		return null;
	}
}

    @Override
    public int getTargetThreads(int type) {
        System.err.println("getTargetsThreads: wrong arguments");
	return -1;
    }

    @Override
    public void updateCachedTargets(int type, CachedTargets[] newCt) {
        System.err.println("updateCachedTarget: wrong arguments");
    }

    @Override
    public void computeTargetThreads(int type, CachedTargets[] newCt) {
        System.err.println("computeTargetThreads: wrong arguments");
    }

    @Override
    public void updateTargetThreads(int type, CachedTargets[] newCt) {
        System.err.println("updateTargetThreads: wrong arguments");
    }

    @Override
    public void propagateTargetThreads(int type, int newTargetThreads) {
        System.err.println("propagateTargetThreads: wrong arguments");
    }

    @Override
    public void copyCachedTargets(int type, CachedTargets[] newCt) {
        System.err.println("copyCachedTarget: wrong arguments");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy