void sendChangedMessage(int component, Object attr) {
   J3dMessage changeMessage = new J3dMessage();
   changeMessage.type = J3dMessage.ORIENTEDSHAPE3D_CHANGED;
   changeMessage.threads = targetThreads;
   changeMessage.universe = universe;
   changeMessage.args[0] = getGeomAtomsArray(mirrorShape3D);
   changeMessage.args[1] = new Integer(component);
   changeMessage.args[2] = attr;
   OrientedShape3DRetained[] o3dArr = new OrientedShape3DRetained[mirrorShape3D.size()];
   mirrorShape3D.toArray(o3dArr);
   changeMessage.args[3] = o3dArr;
   changeMessage.args[4] = this;
   VirtualUniverse.mc.processMessage(changeMessage);
 }
  final void sendMessage(int attrMask, Object attr) {
    ArrayList univList = new ArrayList();
    ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);

    // Send to rendering attribute structure, regardless of
    // whether there are users or not (alternate appearance case ..)
    J3dMessage createMessage = new J3dMessage();
    createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
    createMessage.type = J3dMessage.LINEATTRIBUTES_CHANGED;
    createMessage.universe = null;
    createMessage.args[0] = this;
    createMessage.args[1] = new Integer(attrMask);
    createMessage.args[2] = attr;
    createMessage.args[3] = new Integer(changedFrequent);
    VirtualUniverse.mc.processMessage(createMessage);

    // System.err.println("univList.size is " + univList.size());
    for (int i = 0; i < univList.size(); i++) {
      createMessage = new J3dMessage();
      createMessage.threads = J3dThread.UPDATE_RENDER;
      createMessage.type = J3dMessage.LINEATTRIBUTES_CHANGED;

      createMessage.universe = (VirtualUniverse) univList.get(i);
      createMessage.args[0] = this;
      createMessage.args[1] = new Integer(attrMask);
      createMessage.args[2] = attr;

      ArrayList gL = (ArrayList) gaList.get(i);
      GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
      gL.toArray(gaArr);
      createMessage.args[3] = gaArr;

      VirtualUniverse.mc.processMessage(createMessage);
    }
  }
  /**
   * 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();
  }
  void addView(View view) {
    int i;
    Integer mtype = new Integer(ADD_VIEW);

    apiViewList.add(view);
    if (source.isLive() && view != null) {
      // Gather all affected leaf nodes and send a message to
      // RenderingEnv and RenderBin
      if (inSharedGroup) {
        ArrayList parentList;
        for (int k = 0; k < localToVworldKeys.length; k++) {
          parentList = (ArrayList) parentLists.get(k);
          // If the parentList contains this view or if this is the
          // first VSG then ..
          if (parentList == null || parentList.contains(view)) {
            Object[] objAry = new Object[4];
            ArrayList addVsgList = new ArrayList();
            ArrayList addLeafList = new ArrayList();
            int[] addKeyList = new int[10];

            HashKey key = localToVworldKeys[k];
            addVsgList.add(this);
            addKeyList[0] = k;
            objAry[0] = view;
            objAry[1] = addVsgList;
            objAry[2] = addLeafList;
            /*
            for (int n = 0; n < addLeafList.size(); n++) {
                System.err.println("Shared:n = "+n+" addLeafList = "+addLeafList.get(n));
            }
            */
            objAry[3] =
                super.processViewSpecificInfo(
                    ADD_VIEW, (HashKey) key, view, addVsgList, addKeyList, addLeafList);
            J3dMessage message = new J3dMessage();
            message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
            message.threads =
                (J3dThread.UPDATE_RENDERING_ENVIRONMENT
                    | J3dThread.UPDATE_RENDER
                    | J3dThread.UPDATE_SOUND
                    | J3dThread.SOUND_SCHEDULER);
            message.universe = universe;
            message.args[0] = mtype;
            message.args[1] = objAry;
            VirtualUniverse.mc.processMessage(message);
          }
        }

      } else {
        ArrayList parentList = (ArrayList) parentLists.get(0);

        // If the parentList contains this view or if this is the
        // first VSG then ..
        if (parentList == null || parentList.contains(view)) {
          Object[] objAry = new Object[4];
          ArrayList addVsgList = new ArrayList();
          ArrayList addLeafList = new ArrayList();
          int[] addKeyList = new int[10];

          objAry[0] = view;
          objAry[1] = addVsgList;
          objAry[2] = addLeafList;

          addVsgList.add(this);
          addKeyList[0] = 0;
          tempKey.reset();
          objAry[3] =
              super.processViewSpecificInfo(
                  ADD_VIEW, tempKey, view, addVsgList, addKeyList, addLeafList);

          /*
          for (int n = 0; n < addLeafList.size(); n++) {
          System.err.println("n = "+n+" addLeafList = "+addLeafList.get(n));
          }
          */

          J3dMessage message = new J3dMessage();
          message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
          message.threads =
              (J3dThread.UPDATE_RENDERING_ENVIRONMENT
                  | J3dThread.UPDATE_RENDER
                  | J3dThread.UPDATE_SOUND
                  | J3dThread.SOUND_SCHEDULER);
          message.universe = universe;
          message.args[0] = mtype;
          message.args[1] = objAry;
          VirtualUniverse.mc.processMessage(message);
        }
      }
    }
  }
  void setView(View view, int index) {
    int i;

    View oldView = (View) apiViewList.get(index);
    Integer mtype = new Integer(SET_VIEW);

    if (oldView == view) return;

    apiViewList.set(index, view);
    if (source.isLive()) {
      // Gather all affected leaf nodes and send a message to
      // RenderingEnv and RenderBin
      if (inSharedGroup) {
        ArrayList parentList;
        for (int k = 0; k < localToVworldKeys.length; k++) {
          parentList = (ArrayList) parentLists.get(k);
          Object[] objAry = new Object[8];
          ArrayList addVsgList = new ArrayList();
          ArrayList removeVsgList = new ArrayList();
          ArrayList addLeafList = new ArrayList();
          ArrayList removeLeafList = new ArrayList();
          int[] addKeyList = new int[10];
          int[] removeKeyList = new int[10];

          objAry[0] = view;
          objAry[1] = addVsgList;
          objAry[2] = addLeafList;
          objAry[4] = oldView;
          objAry[5] = removeVsgList;
          objAry[6] = removeLeafList;

          HashKey key = localToVworldKeys[k];
          if (oldView != null && (parentList == null || parentList.contains(oldView))) {
            removeVsgList.add(this);
            removeKeyList[0] = k;
            objAry[7] =
                super.processViewSpecificInfo(
                    REMOVE_VIEW,
                    (HashKey) key,
                    oldView,
                    removeVsgList,
                    removeKeyList,
                    removeLeafList);
          }

          if (view != null && (parentList == null || parentList.contains(view))) {
            addVsgList.add(this);
            addKeyList[0] = k;
            objAry[3] =
                super.processViewSpecificInfo(
                    ADD_VIEW, (HashKey) key, view, addVsgList, addKeyList, addLeafList);
          }
          J3dMessage message = new J3dMessage();
          message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
          message.threads =
              (J3dThread.UPDATE_RENDERING_ENVIRONMENT
                  | J3dThread.UPDATE_RENDER
                  | J3dThread.UPDATE_SOUND
                  | J3dThread.SOUND_SCHEDULER);
          message.universe = universe;
          message.args[0] = mtype;
          message.args[1] = objAry;
          VirtualUniverse.mc.processMessage(message);
        }

      } else {
        ArrayList parentList = (ArrayList) parentLists.get(0);
        Object[] objAry = new Object[8];
        ArrayList addVsgList = new ArrayList();
        ArrayList removeVsgList = new ArrayList();
        ArrayList addLeafList = new ArrayList();
        ArrayList removeLeafList = new ArrayList();
        int[] addKeyList = new int[10];
        int[] removeKeyList = new int[10];

        objAry[0] = view;
        objAry[1] = addVsgList;
        objAry[2] = addLeafList;
        objAry[4] = oldView;
        objAry[5] = removeVsgList;
        objAry[6] = removeLeafList;

        tempKey.reset();
        if (oldView != null && (parentList == null || parentList.contains(oldView))) {
          removeVsgList.add(this);
          removeKeyList[0] = 0;
          objAry[7] =
              super.processViewSpecificInfo(
                  REMOVE_VIEW,
                  (HashKey) tempKey,
                  oldView,
                  removeVsgList,
                  removeKeyList,
                  removeLeafList);
        }
        if (view != null && (parentList == null || parentList.contains(view))) {
          tempKey.reset();
          addVsgList.add(this);
          addKeyList[0] = 0;
          objAry[3] =
              super.processViewSpecificInfo(
                  ADD_VIEW, (HashKey) tempKey, view, addVsgList, addKeyList, addLeafList);
        }
        J3dMessage message = new J3dMessage();
        message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
        message.threads =
            (J3dThread.UPDATE_RENDERING_ENVIRONMENT
                | J3dThread.UPDATE_RENDER
                | J3dThread.UPDATE_SOUND
                | J3dThread.SOUND_SCHEDULER);

        message.universe = universe;
        message.args[0] = mtype;
        message.args[1] = objAry;
        VirtualUniverse.mc.processMessage(message);
      }
    }
  }