Package javax.media.j3d

Source Code of javax.media.j3d.ModelClipRetained

/*
* 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.Enumeration;
import java.util.Vector;

import javax.vecmath.Vector4d;

/**
* The ModelClip retained object.
*/
class ModelClipRetained extends LeafRetained {

    // Statics used when something in the fog changes
    static final int PLANE_CHANGED           = 0x0001;
    static final int PLANES_CHANGED          = 0x0002;
    static final int ENABLE_CHANGED          = 0x0004;
    static final int ENABLES_CHANGED         = 0x0008;
    static final int BOUNDS_CHANGED          = 0x0010;
    static final int BOUNDINGLEAF_CHANGED    = 0x0020;
    static final int SCOPE_CHANGED       = 0x0040;
    static final int INIT_MIRROR       = 0x0080;
    static final int CLEAR_MIRROR       = 0x0100;
    static final int LAST_DEFINED_BIT        = 0x0100;

    /**
     * The clip planes and the enable bits
     */
    Vector4d[] planes = new Vector4d[6];
    boolean[]  enables = new boolean[6];

    Vector4d[] xformPlanes = new Vector4d[6];

    // enableFlag is true if one of the enables is true
    // only used by mirror object
    boolean    enableFlag = false;

    /**
     * The Boundary object defining the model clip's region of influencing
     */
    Bounds regionOfInfluence = null;

    /**
     * The bounding leaf reference
     */
    BoundingLeafRetained boundingLeaf = null;

    /**
     * The transformed value of the influencingRegion.
     */
    Bounds region = null;

/**
* Vector of GroupRetained nodes that scopes this model clip.
*/
Vector<GroupRetained> scopes = new Vector<GroupRetained>();

    //Boolean to indicate if this object is scoped (only used for mirror objects
    boolean isScoped = false;

    // The object that contains the dynamic HashKey - a string type object
    // Used in scoping
    HashKey tempKey = new HashKey(250);

    // This is true when this model clip is referenced in an immediate mode context
    boolean inImmCtx = false;

    // The mirror copy of this modelClip
    ModelClipRetained mirrorModelClip = null;

    // A reference to the scene graph model clip
    ModelClipRetained sgModelClip = null;

    // Target threads to be notified when model clip changes
    final static int targetThreads = J3dThread.UPDATE_RENDERING_ENVIRONMENT |
                                     J3dThread.UPDATE_RENDER;

    /**
     * The EnvironmentSets which reference this model clip.
     * Note that multiple RenderBin update thread may access
     * this shared environmentSets simultaneously.
     * So we use UnorderList which sync. all the operations.
     */
    UnorderList environmentSets = new UnorderList(1, EnvironmentSet.class);

    // Is true, if the mirror clip is viewScoped
    boolean isViewScoped = false;

    /**
     * Constructs and initializes model clip planes
     */
    ModelClipRetained() {

  // planes contains the negate default values
  planes[0] = new Vector4d( 1.0, 0.00.0,-1.0);
  planes[1] = new Vector4d(-1.0, 0.00.0,-1.0);
  planes[2] = new Vector4d( 0.0, 1.00.0,-1.0);
  planes[3] = new Vector4d( 0.0,-1.00.0,-1.0);
  planes[4] = new Vector4d( 0.0, 0.01.0,-1.0);
  planes[5] = new Vector4d( 0.0, 0.0, -1.0,-1.0);

  for (int i = 0; i < 6; i++)
      xformPlanes[i] = new Vector4d(planes[i]);

        enables[0] = enables[1] = enables[2] = enables[3] =
      enables[4] = enables[5] = true;
    }

    /**
     * Initializes planes before the object is live
     */
    void initPlanes(Vector4d[] planes) {

        if (staticTransform != null) {
      Transform3D xform = staticTransform.getNormalTransform();
      for (int i = 0; i < 6; i++) {
     this.planes[i].set(planes[i]);
           xform.transform(this.planes[i], this.xformPlanes[i]);
      }
  } else {
      for (int i = 0; i < 6; i++) {
     this.planes[i].set(planes[i]);
     this.xformPlanes[i].set(this.planes[i]);
      }
  }
    }

    /**
     * Sets the clip planes and send a message
     */
    void setPlanes(Vector4d[] planes) {
        Vector4d[] pl = new Vector4d[6];
  initPlanes(planes);

  for (int i = 0; i < 6; i++) {
             pl[i] = new Vector4d(this.xformPlanes[i]);
  }

  sendMessage(PLANES_CHANGED, pl, null);
    }

    /**
     * Initializes planes before the object is live
     */
    void initPlane(int planeNum, Vector4d plane) {
        if (planeNum < 0 || planeNum > 5)
      throw new IllegalArgumentException(J3dI18N.getString("ModelClip6"));

  if (staticTransform != null) {
      Transform3D xform = staticTransform.getNormalTransform();
            this.planes[planeNum].set(plane);
      xform.transform(this.planes[planeNum], this.xformPlanes[planeNum]);
  } else {
            this.planes[planeNum].set(plane);
      this.xformPlanes[planeNum].set(plane);
  }
    }

    /**
     * Sets the clip planes and send a message
     */
    void setPlane(int planeNum, Vector4d plane) {
  initPlane(planeNum, plane);
  sendMessage(PLANE_CHANGED,
        new Integer(planeNum),
        new Vector4d(this.xformPlanes[planeNum]));
    }

    /**
     * Gets planes
     */
    void getPlanes(Vector4d[] planes){

  for (int i = 0; i < 6; i++) {
       planes[i].set(this.planes[i]);
    }
    }

    /**
     * Gets the specified clipping plane
     */
    void getPlane(int planeNum, Vector4d plane) {
        if (planeNum < 0 || planeNum > 5)
      throw new IllegalArgumentException(J3dI18N.getString("ModelClip6"));
  plane.set(this.planes[planeNum]);
    }

    /**
     * Initializes planes before the object is live
     */
    void initEnables(boolean[] enables) {
        this.enables[0] = enables[0];
        this.enables[1] = enables[1];
        this.enables[2] = enables[2];
        this.enables[3] = enables[3];
        this.enables[4] = enables[4];
        this.enables[5] = enables[5];
    }

    /**
     * Sets the clip planes and send a message
     */
    void setEnables(boolean[] enables) {
        Boolean[] en = new Boolean[6];

  initEnables(enables);
        en[0] = (enables[0] ? Boolean.TRUE: Boolean.FALSE);
        en[1] = (enables[1] ? Boolean.TRUE: Boolean.FALSE);
        en[2] = (enables[2] ? Boolean.TRUE: Boolean.FALSE);
        en[3] = (enables[3] ? Boolean.TRUE: Boolean.FALSE);
        en[4] = (enables[4] ? Boolean.TRUE: Boolean.FALSE);
        en[5] = (enables[5] ? Boolean.TRUE: Boolean.FALSE);

  sendMessage(ENABLES_CHANGED, en, null);
    }

    /**
     * Initializes planes before the object is live
     */
    void initEnable(int planeNum, boolean enable) {
        if (planeNum < 0 || planeNum > 5)
      throw new IllegalArgumentException(J3dI18N.getString("ModelClip6"));
        this.enables[planeNum] = enable;
    }

    /**
     * Sets the clip planes and send a message
     */
    void setEnable(int planeNum, boolean enable) {
  initEnable(planeNum, enable);
  sendMessage(ENABLE_CHANGED,
        new Integer(planeNum),
         (enable ? Boolean.TRUE: Boolean.FALSE));
    }

    /**
     * Gets enables
     */
    void getEnables(boolean[] enables) {
  enables[0] = this.enables[0];
  enables[1] = this.enables[1];
  enables[2] = this.enables[2];
  enables[3] = this.enables[3];
  enables[4] = this.enables[4];
  enables[5] = this.enables[5];
    }

    /**
     * Gets the specified enable
     */
    boolean getEnable(int planeNum) {
        if (planeNum < 0 || planeNum > 5)
      throw new IllegalArgumentException(J3dI18N.getString("ModelClip6"));
  return (this.enables[planeNum]);
    }

    /**
     * Set the Model Clip's region of influencing
     */
    void initInfluencingBounds(Bounds region) {
        if (region != null) {
            this.regionOfInfluence = (Bounds) region.clone();
            if (staticTransform != null) {
                regionOfInfluence.transform(staticTransform.transform);
            }
        } else {
            this.regionOfInfluence = null;
        }
    }

    /**
     * Set the Model Clip's region of influencing and send message
     */
    void setInfluencingBounds(Bounds region) {
        initInfluencingBounds(region);
  sendMessage(BOUNDS_CHANGED,
        (region != null ? (Bounds) region.clone(): null),
        null);
    }

    /**
     * Get the Model Clip's region of influencing.
     */
    Bounds getInfluencingBounds() {
        Bounds b = null;

        if (regionOfInfluence != null) {
            b = (Bounds) regionOfInfluence.clone();
            if (staticTransform != null) {
                Transform3D invTransform = staticTransform.getInvTransform();
                b.transform(invTransform);
            }
        }
        return b;
    }

    /**
     * Set the Model Clip's region of influencing to the specified Leaf node.
     */
    void initInfluencingBoundingLeaf(BoundingLeaf region) {
        if (region != null) {
            boundingLeaf = (BoundingLeafRetained)region.retained;
        } else {
            boundingLeaf = null;
        }
    }

    /**
     * Set the Model Clip's region of influencing to the specified Leaf node.
     */
    void setInfluencingBoundingLeaf(BoundingLeaf region) {
        if (boundingLeaf != null)
            boundingLeaf.mirrorBoundingLeaf.removeUser(mirrorModelClip);
        if (region != null) {
            boundingLeaf = (BoundingLeafRetained)region.retained;
            boundingLeaf.mirrorBoundingLeaf.addUser(mirrorModelClip);
        } else {
            boundingLeaf = null;
        }

  sendMessage(BOUNDINGLEAF_CHANGED,
        (boundingLeaf != null ?
         boundingLeaf.mirrorBoundingLeaf : null),
        null);
    }


    /**
     * Get the Model Clip's region of influencing.
     */
    BoundingLeaf getInfluencingBoundingLeaf() {
        return (boundingLeaf != null ?
    (BoundingLeaf)boundingLeaf.source : null);
    }

    /**
     * Replaces the specified scope with the scope provided.
     * @param scope the new scope
     * @param index which scope to replace
     */
    void initScope(Group scope, int index) {
        scopes.setElementAt((GroupRetained)(scope.retained), index);
    }

    /**
     * Replaces the specified scope with the scope provided.
     * @param scope the new scope
     * @param index which scope to replace
     */
    void setScope(Group scope, int index) {

        ArrayList addScopeList = new ArrayList();
        ArrayList removeScopeList = new ArrayList();
        GroupRetained group;
        Object[] scopeInfo = new Object[3];

        group = scopes.get(index);
        tempKey.reset();
  group.removeAllNodesForScopedModelClip(mirrorModelClip, removeScopeList, tempKey);

        group = (GroupRetained)scope.retained;
        initScope(scope, index);
        tempKey.reset();
  // If its a group, then add the scope to the group, if
  // its a shape, then keep a list to be added during
  // updateMirrorObject
  group.addAllNodesForScopedModelClip(mirrorModelClip,addScopeList, tempKey);
        scopeInfo[0] = addScopeList;
        scopeInfo[1] = removeScopeList;
        scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE:Boolean.FALSE);
        sendMessage(SCOPE_CHANGED, scopeInfo, null);
    }

    /**
     * Inserts the specified scope at specified index
     * @param scope the new scope
     * @param index position to insert new scope at
     */
    void initInsertScope(Node scope, int index) {
        GroupRetained group = (GroupRetained)scope.retained;
  group.setMclipScope();
        scopes.insertElementAt((GroupRetained)(scope.retained), index);
    }

    /**
     * Inserts the specified scope at specified index and sends
     * a message
     * @param scope the new scope
     * @param index position to insert new scope at
     */
    void insertScope(Node scope, int index) {
        Object[] scopeInfo = new Object[3];
        ArrayList addScopeList = new ArrayList();

        initInsertScope(scope, index);
        GroupRetained group = (GroupRetained)scope.retained;
        tempKey.reset();
  group.addAllNodesForScopedModelClip(mirrorModelClip,addScopeList, tempKey);
        scopeInfo[0] = addScopeList;
        scopeInfo[1] = null;
        scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
        sendMessage(SCOPE_CHANGED, scopeInfo, null);
    }


    void initRemoveScope(int index) {
        GroupRetained group  = scopes.elementAt(index);
  group.removeMclipScope();
        scopes.removeElementAt(index);

    }

    void removeScope(int index) {

        Object[] scopeInfo = new Object[3];
        ArrayList removeScopeList = new ArrayList();
        GroupRetained group  = scopes.elementAt(index);

  initRemoveScope(index);
        tempKey.reset();
  group.removeAllNodesForScopedModelClip(mirrorModelClip, removeScopeList, tempKey);

        scopeInfo[0] = null;
        scopeInfo[1] = removeScopeList;
        scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
        sendMessage(SCOPE_CHANGED, scopeInfo, null);
    }

    /**
     * Removes the specified Group node from this ModelClip's list of
     * scopes if the specified node is not found in the list of scoped
     * nodes, method returns quietly.
     *
     * @param Group node to be removed
     */
    void removeScope(Group node) {
      int ind = indexOfScope(node);
      if(ind >= 0)
  removeScope(ind);
    }

   void initRemoveScope(Group node) {
      int ind = indexOfScope(node);
      if(ind >= 0)
  initRemoveScope(ind);
    }

    /**
     * Removes all the Group nodes from the ModelClip's scope
     * list. The ModelClip reverts to universal scope.
     */
    void removeAllScopes() {
      Object[] scopeInfo = new Object[3];
      ArrayList removeScopeList = new ArrayList();
      int n = scopes.size();
      for(int index = n-1; index >= 0; index--) {
  GroupRetained group  = scopes.elementAt(index);
  initRemoveScope(index);
  tempKey.reset();
  group.removeAllNodesForScopedModelClip(mirrorModelClip, removeScopeList, tempKey);
      }

      scopeInfo[0] = null;
      scopeInfo[1] = removeScopeList;
      scopeInfo[2] = (Boolean.FALSE);
      sendMessage(SCOPE_CHANGED, scopeInfo, null);
    }


    void initRemoveAllScopes() {
      int n = scopes.size();
      for(int i = n-1; i >= 0; i--) {
  initRemoveScope(i);
      }
    }

    /**
     * Returns the scope specified by the index.
     * @param index which scope to return
     * @return the scoperen at location index
     */
    Group getScope(int index) {
        return (Group)scopes.elementAt(index).source;
    }

/**
* Returns an enumeration object of the scoperen.
* @return an enumeration object of the scoperen
*/
Enumeration<Group> getAllScopes() {
  Enumeration<GroupRetained> elm = scopes.elements();
  Vector<Group> v = new Vector<Group>(scopes.size());
  while (elm.hasMoreElements()) {
    v.add((Group)elm.nextElement().source);
  }
  return v.elements();
}

    /**
     * Appends the specified scope to this node's list of scopes before
     * the fog is alive
     * @param scope the scope to add to this node's list of scopes
     */
    void initAddScope(Group scope) {
        GroupRetained group = (GroupRetained)scope.retained;
        scopes.addElement((GroupRetained)(scope.retained));
  group.setMclipScope();
    }

    /**
     * Appends the specified scope to this node's list of scopes.
     * @param scope the scope to add to this node's list of scopes
     */
    void addScope(Group scope) {

        Object[] scopeInfo = new Object[3];
        ArrayList addScopeList = new ArrayList();
        GroupRetained group = (GroupRetained)scope.retained;

        initAddScope(scope);
        tempKey.reset();
  group.addAllNodesForScopedModelClip(mirrorModelClip,addScopeList, tempKey);
        scopeInfo[0] = addScopeList;
        scopeInfo[1] = null;
        scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
        sendMessage(SCOPE_CHANGED, scopeInfo, null);
    }

    /**
     * Returns a count of this nodes' scopes.
     * @return the number of scopes descendant from this node
     */
    int numScopes() {
        return scopes.size();
    }

    /**
     * Returns the index of the specified Group node within the ModelClip's list of scoped
     * Group nodes
     * @param Group node whose index is desired
     * @return index of this node
     */
    int indexOfScope(Group node) {
      if(node != null)
  return scopes.indexOf(node.retained);
      else
  return scopes.indexOf(null);
    }

    /**
     * This sets the immedate mode context flag
     */
    void setInImmCtx(boolean inCtx) {
        inImmCtx = inCtx;
    }

    /**
     * This gets the immedate mode context flag
     */
    boolean getInImmCtx() {
        return (inImmCtx);
    }


    /**
     * This method and its native counterpart update the native context
     * model clip planes.
     */
    void update(Canvas3D cv, int enableMask) {
  cv.setModelViewMatrix(cv.ctx,
            cv.vworldToEc.mat,
            getLastLocalToVworld());
  update(cv.ctx, enableMask, getLastLocalToVworld());
    }

void update(Context ctx, int enableMask, Transform3D trans) {
  for (int i = 0; i < 6; i++) {
    Vector4d v = xformPlanes[i];
    boolean enable = ((enableMask & (1 << i)) != 0);
    Pipeline.getPipeline().updateModelClip(ctx, i, enable,
                                           v.x, v.y, v.z, v.w);
  }
}

    void initMirrorObject(Object[] args) {
  Shape3DRetained shape;
  Object[] scopeInfo = (Object[]) args[2];
  Boolean scoped = (Boolean)scopeInfo[0];
  ArrayList shapeList = (ArrayList)scopeInfo[1];
  BoundingLeafRetained bl=(BoundingLeafRetained)((Object[])args[4])[0];
  Bounds bnds = (Bounds)((Object[])args[4])[1];

  for (int i = 0; i < shapeList.size(); i++) {
      shape = ((GeometryAtom)shapeList.get(i)).source;
      shape.addModelClip(mirrorModelClip);
  }
  mirrorModelClip.isScoped = scoped.booleanValue();

  if (bl != null) {
      mirrorModelClip.boundingLeaf = bl.mirrorBoundingLeaf;
      mirrorModelClip.region = boundingLeaf.transformedRegion;
  } else {
      mirrorModelClip.boundingLeaf = null;
      mirrorModelClip.region = null;
  }

  if (bnds != null) {
      mirrorModelClip.regionOfInfluence = bnds;
      if (mirrorModelClip.region == null) {
    mirrorModelClip.region = (Bounds)regionOfInfluence.clone();
    mirrorModelClip.region.transform(regionOfInfluence, getLastLocalToVworld());
      }
  }
  else {
      mirrorModelClip.regionOfInfluence = null;
  }
  boolean[] ens = (boolean[])((Object[])args[4])[2];

  for (int i = 0; i < ens.length; i++) {
      mirrorModelClip.enables[i] = ens[i];
  }
        mirrorModelClip.enableFlag = mirrorModelClip.enables[0] |
          mirrorModelClip.enables[1] |
          mirrorModelClip.enables[2] |
          mirrorModelClip.enables[3] |
          mirrorModelClip.enables[4] |
          mirrorModelClip.enables[5] ;

    }



    @Override
    void updateMirrorObject(Object[] objs) {
  int component = ((Integer)objs[1]).intValue();
  if ((component & PLANES_CHANGED) != 0) {
      Vector4d[] pl = ((Vector4d[]) objs[2]);

      for (int i = 0; i < 6; i++) {
           mirrorModelClip.xformPlanes[i].set(pl[i]);
      }
  }
  else if ((component & PLANE_CHANGED) != 0) {
      int planeNum = ((Integer)objs[2]).intValue();

      mirrorModelClip.xformPlanes[planeNum].set((Vector4d)objs[3]);
  }
  else if ((component & INIT_MIRROR) != 0) {
      Vector4d[] pl = (Vector4d[]) objs[3];
      for (int i = 0; i < 6; i++) {
           mirrorModelClip.xformPlanes[i].set(pl[i]);
      }
  }
    }

    // The update Object function.
    void updateImmediateMirrorObject(Object[] objs) {
  int component = ((Integer)objs[1]).intValue();

  if  ((component & BOUNDINGLEAF_CHANGED) != 0) {
      mirrorModelClip.boundingLeaf = (BoundingLeafRetained)objs[2];
      if (objs[2] != null) {
    mirrorModelClip.region = mirrorModelClip.boundingLeaf.transformedRegion;
      }
      else {
    if (mirrorModelClip.regionOfInfluence != null) {
        mirrorModelClip.region = mirrorModelClip.regionOfInfluence.copy(mirrorModelClip.region);
        mirrorModelClip.region.transform(mirrorModelClip.regionOfInfluence,
                 getCurrentLocalToVworld());
    }
    else {
        mirrorModelClip.region = null;
    }

      }
  }

  if ((component & BOUNDS_CHANGED) != 0) {
      mirrorModelClip.regionOfInfluence = (Bounds) objs[2];
      if (mirrorModelClip.boundingLeaf == null) {
    if (objs[2] != null) {
        mirrorModelClip.region = mirrorModelClip.regionOfInfluence.copy(mirrorModelClip.region);

        mirrorModelClip.region.transform(mirrorModelClip.regionOfInfluence,
                 getCurrentLocalToVworld());
    }
    else {
        mirrorModelClip.region = null;
    }
      }
  }

  if ((component & SCOPE_CHANGED) != 0) {
            Object[] scopeList = (Object[])objs[2];
            ArrayList addList = (ArrayList)scopeList[0];
            ArrayList removeList = (ArrayList)scopeList[1];
            boolean isScoped = ((Boolean)scopeList[2]).booleanValue();

            if (addList != null) {
                mirrorModelClip.isScoped = isScoped;
                for (int i = 0; i < addList.size(); i++) {
        Shape3DRetained obj = ((GeometryAtom)addList.get(i)).source;
        obj.addModelClip(mirrorModelClip);
                }
            }

            if (removeList != null) {
                mirrorModelClip.isScoped = isScoped;
                for (int i = 0; i < removeList.size(); i++) {
        Shape3DRetained obj = ((GeometryAtom)removeList.get(i)).source;
        obj.removeModelClip(mirrorModelClip);
                }
            }
        }

  if ((component & ENABLES_CHANGED) != 0) {
      Boolean[] en = ((Boolean[]) objs[2]);

      mirrorModelClip.enables[0] = en[0].booleanValue();
      mirrorModelClip.enables[1] = en[1].booleanValue();
      mirrorModelClip.enables[2] = en[2].booleanValue();
      mirrorModelClip.enables[3] = en[3].booleanValue();
      mirrorModelClip.enables[4] = en[4].booleanValue();
      mirrorModelClip.enables[5] = en[5].booleanValue();
            mirrorModelClip.enableFlag = mirrorModelClip.enables[0] |
          mirrorModelClip.enables[1] |
          mirrorModelClip.enables[2] |
          mirrorModelClip.enables[3] |
          mirrorModelClip.enables[4] |
          mirrorModelClip.enables[5] ;
  } else if ((component & ENABLE_CHANGED) != 0) {
      int planeNum = ((Integer)objs[2]).intValue();

      mirrorModelClip.enables[planeNum] = ((Boolean)objs[3]).booleanValue();
            mirrorModelClip.enableFlag = mirrorModelClip.enables[0] |
          mirrorModelClip.enables[1] |
          mirrorModelClip.enables[2] |
          mirrorModelClip.enables[3] |
          mirrorModelClip.enables[4] |
          mirrorModelClip.enables[5] ;
  }
    }


    /** Note: This routine will only be called on
     * the mirror object - will update the object's
     * cached region and transformed region
     */
    @Override
    void updateBoundingLeaf() {
        if (boundingLeaf != null && boundingLeaf.switchState.currentSwitchOn) {
            region = boundingLeaf.transformedRegion;
        } else {
            if (regionOfInfluence != null) {
    region = regionOfInfluence.copy(region);
                region.transform(regionOfInfluence, getCurrentLocalToVworld());
            } else {
                region = null;
            }
        }
    }


    @Override
    void setLive(SetLiveState s) {
  GroupRetained group;

  super.doSetLive(s);

  if (inSharedGroup) {
      throw new
    IllegalSharingException(J3dI18N.getString("ModelClipRetained1"));
  }

  // Create the mirror object


        if (mirrorModelClip == null) {
      mirrorModelClip = (ModelClipRetained)this.clone();
      mirrorModelClip.boundingLeaf = null;
      mirrorModelClip.sgModelClip = this;
  }
  if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
      s.viewScopedNodeList.add(mirrorModelClip);
      s.scopedNodesViewList.add(s.viewLists.get(0));
  } else {
      s.nodeList.add(mirrorModelClip);
  }

  // If bounding leaf is not null, add the mirror object as a user
  // so that any changes to the bounding leaf will be received
  if (boundingLeaf != null) {
      boundingLeaf.mirrorBoundingLeaf.addUser(mirrorModelClip);
  }
        // process switch leaf
        if (s.switchTargets != null &&
                        s.switchTargets[0] != null) {
            s.switchTargets[0].addNode(mirrorModelClip, Targets.ENV_TARGETS);
        }
  mirrorModelClip.switchState = s.switchStates.get(0);

  // add this model clip to the transform target
        if (s.transformTargets != null && s.transformTargets[0] != null) {
            s.transformTargets[0].addNode(mirrorModelClip, Targets.ENV_TARGETS);
      s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
  }

        s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
            J3dThread.UPDATE_RENDER;
  super.markAsLive();


  // Initialize the mirror object, this needs to be done, when
  // renderBin is not accessing any of the fields
  J3dMessage createMessage = new J3dMessage();
  createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
  createMessage.universe = universe;
  createMessage.type = J3dMessage.MODELCLIP_CHANGED;
  createMessage.args[0] = this;
  // a snapshot of all attributes that needs to be initialized
  // in the mirror object
  createMessage.args[1]= new Integer(INIT_MIRROR);
  ArrayList addScopeList = new ArrayList();
  for (int i = 0; i < scopes.size(); i++) {
      group = scopes.get(i);
      tempKey.reset();
      group.addAllNodesForScopedModelClip(mirrorModelClip, addScopeList, tempKey);
  }
  Object[] scopeInfo = new Object[2];
  scopeInfo[0] = ((scopes.size() > 0) ? Boolean.TRUE:Boolean.FALSE);
  scopeInfo[1] = addScopeList;
  createMessage.args[2] = scopeInfo;
  createMessage.args[3] = xformPlanes.clone();

  Object[] obj = new Object[3];
  obj[0] = boundingLeaf;
  obj[1] = (regionOfInfluence != null?regionOfInfluence.clone():null);
  obj[2] = enables.clone();
  createMessage.args[4] = obj;
  VirtualUniverse.mc.processMessage(createMessage);


    }


    /**
     * This clearLive routine first calls the superclass's method, then
     * it removes itself to the list of model clip
     */
    @Override
    void clearLive(SetLiveState s) {

        super.clearLive(s);
        s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
            J3dThread.UPDATE_RENDER;
        if (s.switchTargets != null &&
                        s.switchTargets[0] != null) {
            s.switchTargets[0].addNode(mirrorModelClip, Targets.ENV_TARGETS);
        }
        // Remove this mirror light as users of the bounding leaf
        if (mirrorModelClip.boundingLeaf != null)
            mirrorModelClip.boundingLeaf.removeUser(mirrorModelClip);

  if ((s.viewScopedNodeList != null) && (s.viewLists != null)) {
      s.viewScopedNodeList.add(mirrorModelClip);
      s.scopedNodesViewList.add(s.viewLists.get(0));
  } else {
      s.nodeList.add(mirrorModelClip);
  }
        if (s.transformTargets != null && s.transformTargets[0] != null) {
            s.transformTargets[0].addNode(mirrorModelClip, Targets.ENV_TARGETS);
      s.notifyThreads |= J3dThread.UPDATE_TRANSFORM;
        }


  if (scopes.size() > 0) {
      J3dMessage createMessage = new J3dMessage();
      createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
      createMessage.universe = universe;
      createMessage.type = J3dMessage.MODELCLIP_CHANGED;
      createMessage.args[0] = this;
      createMessage.args[1]= new Integer(CLEAR_MIRROR);
      ArrayList removeScopeList = new ArrayList();
      for (int i = 0; i < scopes.size(); i++) {
    GroupRetained group = scopes.get(i);
    tempKey.reset();
    group.removeAllNodesForScopedModelClip(mirrorModelClip, removeScopeList, tempKey);
      }
      createMessage.args[2] = removeScopeList;
      VirtualUniverse.mc.processMessage(createMessage);
  }
    }

   // This is called on the parent object
    void clearMirrorObject(Object[] args) {
  Shape3DRetained shape;
  ArrayList shapeList = (ArrayList)args[2];

  for (int i = 0; i < shapeList.size(); i++) {
      shape = ((GeometryAtom)shapeList.get(i)).source;
      shape.removeModelClip(mirrorModelClip);
  }

  mirrorModelClip.isScoped = false;

    }


    // Clone the retained side only, internal use only
    @Override
    protected Object clone() {
        ModelClipRetained mc = (ModelClipRetained)super.clone();

        mc.planes = new Vector4d[6];
  for (int i = 0; i < 6; i++) {
       mc.planes[i] = new Vector4d(this.planes[i]);
       mc.xformPlanes[i] = new Vector4d(this.xformPlanes[i]);
  }

        mc.enables = new boolean[6];
        getEnables(mc.enables);

  // Derive the enables flag
        mc.enableFlag = (mc.enables[0] |
       mc.enables[1] |
       mc.enables[2] |
       mc.enables[3] |
       mc.enables[4] |
       mc.enables[5] );

        mc.inImmCtx = false;
        mc.region = null;
        mc.sgModelClip = null;
        mc.mirrorModelClip = null;
  mc.environmentSets = new UnorderList(1, EnvironmentSet.class);

  if (regionOfInfluence != null) {
      mc.regionOfInfluence = (Bounds) regionOfInfluence.clone();
  }

        return mc;
    }


    // Called on mirror object
    void updateImmediateTransformChange() {
        // If bounding leaf is null, tranform the bounds object
        if (boundingLeaf == null) {
            if (regionOfInfluence != null) {
    region = regionOfInfluence.copy(region);
                region.transform(regionOfInfluence,
         sgModelClip.getCurrentLocalToVworld());
            }

        }
    }


    void printPlane(int index, String string)
    {
  System.err.println(string + " : < " + planes[index].toString()
    + " > " + enables[index]);
    }

    void printPlanes(String string, Vector4d[] planes)
    {
  System.err.println(string);
  printPlane(0, "[0]");
  printPlane(1, "[1]");
  printPlane(2, "[2]");
  printPlane(3, "[3]");
  printPlane(4, "[4]");
  printPlane(5, "[5]");
    }


    void printEnables(String string, boolean[] enables)
    {
  System.err.println(string);
  System.err.println("[0] : < " + enables[0] + " >");
  System.err.println("[1] : < " + enables[1] + " >");
  System.err.println("[2] : < " + enables[2] + " >");
  System.err.println("[3] : < " + enables[3] + " >");
  System.err.println("[4] : < " + enables[4] + " >");
  System.err.println("[5] : < " + enables[5] + " >");
    }

   final void sendMessage(int attrMask, Object attr1, Object attr2) {
  J3dMessage createMessage = new J3dMessage();
  createMessage.threads = targetThreads;
  createMessage.type = J3dMessage.MODELCLIP_CHANGED;
        createMessage.universe = universe;
  createMessage.args[0] = this;
  createMessage.args[1]= new Integer(attrMask);
  createMessage.args[2] = attr1;
  createMessage.args[3] = attr2;
  VirtualUniverse.mc.processMessage(createMessage);
    }

    @Override
    void mergeTransform(TransformGroupRetained staticTransform) {
  super.mergeTransform(staticTransform);

  if (regionOfInfluence != null) {
            regionOfInfluence.transform(staticTransform.transform);
  }

  Transform3D xform = staticTransform.getNormalTransform();
  for (int i = 0; i < 6; i++) {
       xform.transform(planes[i], xformPlanes[i]);
  }
    }
    @Override
    void getMirrorObjects(ArrayList leafList, HashKey key) {
  leafList.add(mirrorModelClip);
    }
}
TOP

Related Classes of javax.media.j3d.ModelClipRetained

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.