0001: /*
0002: * $RCSfile: RenderingEnvironmentStructure.java,v $
0003: *
0004: * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.7 $
0028: * $Date: 2008/02/28 20:17:29 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: import java.util.*;
0035: import javax.vecmath.*;
0036:
0037: /**
0038: * A rendering environment structure is an object that organizes lights,
0039: * fogs, backgrounds, clips, and model clips.
0040: */
0041:
0042: class RenderingEnvironmentStructure extends J3dStructure implements
0043: ObjectUpdate {
0044: /**
0045: * The list of light nodes
0046: */
0047: ArrayList nonViewScopedLights = new ArrayList();
0048: HashMap viewScopedLights = new HashMap();
0049: int numberOfLights = 0;
0050:
0051: /**
0052: * The list of fog nodes
0053: */
0054: ArrayList nonViewScopedFogs = new ArrayList();
0055: HashMap viewScopedFogs = new HashMap();
0056: int numberOfFogs = 0;
0057:
0058: /**
0059: * The list of alternate app nodes
0060: */
0061: ArrayList nonViewScopedAltAppearances = new ArrayList();
0062: HashMap viewScopedAltAppearances = new HashMap();
0063: int numberOfAltApps = 0;
0064:
0065: /**
0066: * The list of model clip nodes
0067: */
0068: ArrayList nonViewScopedModelClips = new ArrayList();
0069: HashMap viewScopedModelClips = new HashMap();
0070: int numberOfModelClips = 0;
0071:
0072: /**
0073: * The list of background nodes
0074: */
0075: ArrayList nonViewScopedBackgrounds = new ArrayList();
0076: HashMap viewScopedBackgrounds = new HashMap();
0077: int numberOfBgs = 0;
0078:
0079: /**
0080: * The list of clip nodes
0081: */
0082: ArrayList nonViewScopedClips = new ArrayList();
0083: HashMap viewScopedClips = new HashMap();
0084: int numberOfClips = 0;
0085:
0086: // For closest Background selection
0087: BackgroundRetained[] intersectedBacks = new BackgroundRetained[1];
0088:
0089: // For closest Clip selection
0090: ClipRetained[] intersectedClips = new ClipRetained[1];
0091:
0092: // For closest Background, Clip, Fog selection
0093: Bounds[] intersectedBounds = new Bounds[1];
0094:
0095: Transform3D localeXform = new Transform3D();
0096: Vector3d localeTranslation = new Vector3d();
0097: Bounds localeBounds = null;
0098:
0099: // For closest Fog selection
0100: FogRetained[] intersectedFogs = new FogRetained[1];
0101:
0102: // for closest alternate appearance selection
0103: AlternateAppearanceRetained[] intersectedAltApps = new AlternateAppearanceRetained[1];
0104:
0105: // For closest ModelClip selection
0106: ModelClipRetained[] intersectedModelClips = new ModelClipRetained[1];
0107:
0108: // Back clip distance in V world
0109: double backClipDistance;
0110:
0111: // ArrayList of leafRetained object whose mirrorObjects
0112: // should be updated
0113: ArrayList objList = new ArrayList();
0114:
0115: // ArrayList of leafRetained object whose boundingleaf xform
0116: // should be updated
0117: ArrayList xformChangeList = new ArrayList();
0118:
0119: // freelist management of objects
0120: ArrayList objFreeList = new ArrayList();
0121:
0122: LightRetained[] retlights = new LightRetained[5];
0123:
0124: // variables used for processing transform messages
0125: boolean transformMsg = false;
0126: UpdateTargets targets = null;
0127: ArrayList blUsers = null;
0128:
0129: Integer ogInsert = new Integer(J3dMessage.ORDERED_GROUP_INSERTED);
0130: Integer ogRemove = new Integer(J3dMessage.ORDERED_GROUP_REMOVED);
0131:
0132: // Used to lock the intersectedBounds {used by fog, mclip etc}
0133: // Can used intersectedBounds itself, since this may be realloced
0134: Object lockObj = new Object();
0135:
0136: /**
0137: * Constructs a RenderingEnvironmentStructure object in the specified
0138: * virtual universe.
0139: */
0140: RenderingEnvironmentStructure(VirtualUniverse u) {
0141: super (u, J3dThread.UPDATE_RENDERING_ENVIRONMENT);
0142: }
0143:
0144: /**
0145: * Returns a object array of length 5 to save the 5 objects in the message list.
0146: */
0147: Object[] getObjectArray() {
0148: Object[] objs;
0149: int size;
0150:
0151: size = objFreeList.size();
0152: if (size == 0) {
0153: objs = new Object[5];
0154: } else {
0155: objs = (Object[]) objFreeList.get(size - 1);
0156: objFreeList.remove(size - 1);
0157: }
0158: return objs;
0159: }
0160:
0161: void addObjArrayToFreeList(Object[] objs) {
0162: int i;
0163:
0164: for (i = 0; i < objs.length; i++)
0165: objs[i] = null;
0166:
0167: objFreeList.add(objs);
0168: }
0169:
0170: public void updateObject() {
0171: int i, j;
0172: Object[] args;
0173: LeafRetained leaf;
0174: Boolean masks;
0175: int size;
0176:
0177: size = objList.size();
0178: for (i = 0; i < size; i++) {
0179: args = (Object[]) objList.get(i);
0180: leaf = (LeafRetained) args[0];
0181: leaf.updateMirrorObject(args);
0182: addObjArrayToFreeList(args);
0183: }
0184: objList.clear();
0185:
0186: size = xformChangeList.size();
0187: for (i = 0; i < size; i++) {
0188: leaf = (LeafRetained) xformChangeList.get(i);
0189: leaf.updateTransformChange();
0190: }
0191: xformChangeList.clear();
0192:
0193: }
0194:
0195: void processMessages(long referenceTime) {
0196: J3dMessage[] messages = getMessages(referenceTime);
0197: ;
0198: J3dMessage m;
0199: int nMsg = getNumMessage();
0200:
0201: if (nMsg <= 0) {
0202: return;
0203: }
0204:
0205: for (int i = 0; i < nMsg; i++) {
0206: m = messages[i];
0207:
0208: switch (m.type) {
0209: case J3dMessage.INSERT_NODES:
0210: insertNodes(m);
0211: break;
0212: case J3dMessage.REMOVE_NODES:
0213: removeNodes(m);
0214: break;
0215: case J3dMessage.LIGHT_CHANGED:
0216: updateLight((Object[]) m.args);
0217: break;
0218: case J3dMessage.BOUNDINGLEAF_CHANGED:
0219: updateBoundingLeaf((Object[]) m.args);
0220: break;
0221: case J3dMessage.FOG_CHANGED:
0222: updateFog((Object[]) m.args);
0223: break;
0224: case J3dMessage.ALTERNATEAPPEARANCE_CHANGED:
0225: updateAltApp((Object[]) m.args);
0226: break;
0227: case J3dMessage.SHAPE3D_CHANGED:
0228: updateShape3D((Object[]) m.args);
0229: break;
0230: case J3dMessage.ORIENTEDSHAPE3D_CHANGED:
0231: updateOrientedShape3D((Object[]) m.args);
0232: break;
0233: case J3dMessage.MORPH_CHANGED:
0234: updateMorph((Object[]) m.args);
0235: break;
0236: case J3dMessage.TRANSFORM_CHANGED:
0237: transformMsg = true;
0238: break;
0239: case J3dMessage.SWITCH_CHANGED:
0240: processSwitchChanged(m);
0241: // may need to process dirty switched-on transform
0242: if (universe.transformStructure.getLazyUpdate()) {
0243: transformMsg = true;
0244: }
0245: break;
0246: case J3dMessage.MODELCLIP_CHANGED:
0247: updateModelClip((Object[]) m.args);
0248: break;
0249: case J3dMessage.BACKGROUND_CHANGED:
0250: updateBackground((Object[]) m.args);
0251: break;
0252: case J3dMessage.CLIP_CHANGED:
0253: updateClip((Object[]) m.args);
0254: break;
0255: case J3dMessage.ORDERED_GROUP_INSERTED:
0256: updateOrderedGroupInserted(m);
0257: break;
0258: case J3dMessage.ORDERED_GROUP_REMOVED:
0259: updateOrderedGroupsRemoved(m);
0260: break;
0261: case J3dMessage.VIEWSPECIFICGROUP_CHANGED:
0262: updateViewSpecificGroupChanged(m);
0263: break;
0264: case J3dMessage.VIEWSPECIFICGROUP_INIT:
0265: initViewSpecificInfo(m);
0266: break;
0267: case J3dMessage.VIEWSPECIFICGROUP_CLEAR:
0268: clearViewSpecificInfo(m);
0269: break;
0270: }
0271: m.decRefcount();
0272: }
0273:
0274: if (transformMsg) {
0275: updateTransformChange();
0276: transformMsg = false;
0277: }
0278:
0279: VirtualUniverse.mc.addMirrorObject(this );
0280:
0281: Arrays.fill(messages, 0, nMsg, null);
0282: }
0283:
0284: void updateOrderedGroupInserted(J3dMessage m) {
0285: Object[] ogList = (Object[]) m.args[0];
0286: Object[] ogChildIdList = (Object[]) m.args[1];
0287: Object[] ogOrderedIdList = (Object[]) m.args[2];
0288: OrderedGroupRetained og;
0289: int index;
0290: Object[] objs;
0291:
0292: for (int n = 0; n < ogList.length; n++) {
0293: og = (OrderedGroupRetained) ogList[n];
0294: og.updateChildIdTableInserted(((Integer) ogChildIdList[n])
0295: .intValue(), ((Integer) ogOrderedIdList[n])
0296: .intValue());
0297: og.incrChildCount();
0298: }
0299: }
0300:
0301: void updateOrderedGroupsRemoved(J3dMessage m) {
0302: Object[] ogList = (Object[]) m.args[0];
0303: Object[] ogChildIdList = (Object[]) m.args[1];
0304: OrderedGroupRetained og;
0305: int index;
0306: Object[] objs;
0307:
0308: for (int n = 0; n < ogList.length; n++) {
0309: og = (OrderedGroupRetained) ogList[n];
0310: og.updateChildIdTableRemoved(((Integer) ogChildIdList[n])
0311: .intValue());
0312: og.decrChildCount();
0313: }
0314:
0315: }
0316:
0317: /**
0318: * This processes a switch change.
0319: */
0320: void processSwitchChanged(J3dMessage m) {
0321: int i;
0322: UnorderList arrList;
0323: int size;
0324: Object[] nodes, nodesArr;
0325: LeafRetained leaf;
0326:
0327: UpdateTargets targets = (UpdateTargets) m.args[0];
0328:
0329: arrList = targets.targetList[Targets.BLN_TARGETS];
0330: if (arrList != null) {
0331: BoundingLeafRetained mbleaf;
0332: Object[] objArr = (Object[]) m.args[1];
0333: Object[] obj;
0334: size = arrList.size();
0335: nodesArr = arrList.toArray(false);
0336:
0337: for (int h = 0; h < size; h++) {
0338: nodes = (Object[]) nodesArr[h];
0339: obj = (Object[]) objArr[h];
0340:
0341: for (i = 0; i < nodes.length; i++) {
0342:
0343: Object[] users = (Object[]) obj[i];
0344: mbleaf = (BoundingLeafRetained) nodes[i];
0345:
0346: //mbleaf.switchState.updateCurrentSwitchOn();
0347: for (int j = 0; j < users.length; j++) {
0348: leaf = (LeafRetained) users[j];
0349: if (leaf instanceof FogRetained
0350: || leaf instanceof LightRetained
0351: || leaf instanceof ModelClipRetained
0352: || leaf instanceof ClipRetained
0353: || leaf instanceof AlternateAppearanceRetained
0354: || leaf instanceof BackgroundRetained) {
0355: leaf.updateBoundingLeaf();
0356: }
0357: }
0358: }
0359: }
0360: }
0361: }
0362:
0363: void insertNodes(J3dMessage m) {
0364: Object[] nodes = (Object[]) m.args[0];
0365: ArrayList viewScopedNodes = (ArrayList) m.args[3];
0366: ArrayList scopedNodesViewList = (ArrayList) m.args[4];
0367: Object n;
0368: int i;
0369: GeometryAtom ga;
0370: int num;
0371: LightRetained lt;
0372: FogRetained fg;
0373: ModelClipRetained mc;
0374: ArrayList list;
0375:
0376: for (i = 0; i < nodes.length; i++) {
0377: n = nodes[i];
0378: if (n instanceof LightRetained) {
0379: lt = (LightRetained) n;
0380: numberOfLights++;
0381:
0382: // If this particulat light is not scoped, added it
0383: // to all the views
0384: if (lt.inBackgroundGroup)
0385: lt.geometryBackground.lights.add(lt);
0386: else
0387: nonViewScopedLights.add(lt);
0388:
0389: } else if (n instanceof FogRetained) {
0390: fg = (FogRetained) n;
0391: numberOfFogs++;
0392: // If the fog is scoped to a view , then ..
0393:
0394: if (fg.inBackgroundGroup) {
0395: fg.geometryBackground.fogs.add(fg);
0396: } else {
0397: nonViewScopedFogs.add(fg);
0398: }
0399:
0400: } else if (n instanceof AlternateAppearanceRetained) {
0401: AlternateAppearanceRetained altApp = (AlternateAppearanceRetained) n;
0402:
0403: numberOfAltApps++;
0404:
0405: nonViewScopedAltAppearances.add(n);
0406:
0407: } else if (n instanceof BackgroundRetained) {
0408: BackgroundRetained bg = (BackgroundRetained) n;
0409: numberOfBgs++;
0410:
0411: nonViewScopedBackgrounds.add(n);
0412:
0413: } else if (n instanceof ClipRetained) {
0414: ClipRetained cl = (ClipRetained) n;
0415: numberOfClips++;
0416:
0417: nonViewScopedClips.add(n);
0418:
0419: } else if (n instanceof ModelClipRetained) {
0420: mc = (ModelClipRetained) n;
0421: numberOfModelClips++;
0422:
0423: nonViewScopedModelClips.add(n);
0424:
0425: }
0426:
0427: }
0428:
0429: if (viewScopedNodes != null) {
0430: int size = viewScopedNodes.size();
0431: int vlsize;
0432:
0433: for (i = 0; i < size; i++) {
0434: n = (NodeRetained) viewScopedNodes.get(i);
0435: ArrayList vl = (ArrayList) scopedNodesViewList.get(i);
0436: if (n instanceof LightRetained) {
0437: ((LightRetained) n).isViewScoped = true;
0438: numberOfLights++;
0439: vlsize = vl.size();
0440: for (int k = 0; k < vlsize; k++) {
0441: View view = (View) vl.get(k);
0442: if ((list = (ArrayList) viewScopedLights
0443: .get(view)) == null) {
0444: list = new ArrayList();
0445: viewScopedLights.put(view, list);
0446: }
0447: list.add(n);
0448: }
0449: } else if (n instanceof FogRetained) {
0450: ((FogRetained) n).isViewScoped = true;
0451: numberOfFogs++;
0452: vlsize = vl.size();
0453: for (int k = 0; k < vlsize; k++) {
0454: View view = (View) vl.get(k);
0455: if ((list = (ArrayList) viewScopedFogs
0456: .get(view)) == null) {
0457: list = new ArrayList();
0458: viewScopedFogs.put(view, list);
0459: }
0460: list.add(n);
0461: }
0462: } else if (n instanceof AlternateAppearanceRetained) {
0463: ((AlternateAppearanceRetained) n).isViewScoped = true;
0464: numberOfAltApps++;
0465: vlsize = vl.size();
0466: for (int k = 0; k < vlsize; k++) {
0467: View view = (View) vl.get(k);
0468: if ((list = (ArrayList) viewScopedAltAppearances
0469: .get(view)) == null) {
0470: list = new ArrayList();
0471: viewScopedAltAppearances.put(view, list);
0472: }
0473: list.add(n);
0474: }
0475: } else if (n instanceof BackgroundRetained) {
0476: ((BackgroundRetained) n).isViewScoped = true;
0477: numberOfBgs++;
0478: vlsize = vl.size();
0479: for (int k = 0; k < vlsize; k++) {
0480: View view = (View) vl.get(k);
0481: if ((list = (ArrayList) viewScopedBackgrounds
0482: .get(view)) == null) {
0483: list = new ArrayList();
0484: viewScopedBackgrounds.put(view, list);
0485: }
0486: list.add(n);
0487: }
0488: } else if (n instanceof ClipRetained) {
0489: ((ClipRetained) n).isViewScoped = true;
0490: numberOfClips++;
0491: vlsize = vl.size();
0492: for (int k = 0; k < vlsize; k++) {
0493: View view = (View) vl.get(k);
0494: if ((list = (ArrayList) viewScopedClips
0495: .get(view)) == null) {
0496: list = new ArrayList();
0497: viewScopedClips.put(view, list);
0498: }
0499: list.add(n);
0500: }
0501: } else if (n instanceof ModelClipRetained) {
0502: ((ModelClipRetained) n).isViewScoped = true;
0503: numberOfModelClips++;
0504: vlsize = vl.size();
0505: for (int k = 0; k < vlsize; k++) {
0506: View view = (View) vl.get(k);
0507: if ((list = (ArrayList) viewScopedModelClips
0508: .get(view)) == null) {
0509: list = new ArrayList();
0510: viewScopedModelClips.put(view, list);
0511: }
0512: list.add(n);
0513: }
0514: }
0515: }
0516:
0517: }
0518: if (numberOfLights > retlights.length)
0519: retlights = new LightRetained[numberOfLights];
0520: if (intersectedFogs.length < numberOfFogs)
0521: intersectedFogs = new FogRetained[numberOfFogs];
0522: if (intersectedAltApps.length < numberOfAltApps)
0523: intersectedAltApps = new AlternateAppearanceRetained[numberOfAltApps];
0524: if (intersectedBacks.length < numberOfBgs)
0525: intersectedBacks = new BackgroundRetained[numberOfBgs];
0526: if (intersectedClips.length < numberOfClips)
0527: intersectedClips = new ClipRetained[numberOfClips];
0528: if (intersectedModelClips.length < numberOfModelClips)
0529: intersectedModelClips = new ModelClipRetained[numberOfModelClips];
0530: }
0531:
0532: void removeNodes(J3dMessage m) {
0533: Object[] nodes = (Object[]) m.args[0];
0534: ArrayList viewScopedNodes = (ArrayList) m.args[3];
0535: ArrayList scopedNodesViewList = (ArrayList) m.args[4];
0536: Object n;
0537: int i;
0538: GeometryAtom ga;
0539: LeafRetained oldsrc = null;
0540:
0541: // System.err.println("RE : removeNodes message " + m);
0542: // System.err.println("RE : removeNodes m.args[0] " + m.args[0]);
0543:
0544: for (i = 0; i < nodes.length; i++) {
0545: n = nodes[i];
0546: if (n instanceof LightRetained) {
0547: LightRetained lt = (LightRetained) n;
0548: if (lt.inBackgroundGroup) {
0549: lt.geometryBackground.lights.remove(lt);
0550: } else {
0551: nonViewScopedLights.remove(nonViewScopedLights
0552: .indexOf(n));
0553: }
0554:
0555: numberOfLights--;
0556: } else if (n instanceof FogRetained) {
0557: numberOfFogs--;
0558: FogRetained fg = (FogRetained) n;
0559: if (fg.inBackgroundGroup) {
0560: fg.geometryBackground.fogs.remove(fg);
0561: } else {
0562: nonViewScopedFogs.remove(nonViewScopedFogs
0563: .indexOf(n));
0564: }
0565: } else if (n instanceof AlternateAppearanceRetained) {
0566: numberOfAltApps--;
0567: nonViewScopedAltAppearances
0568: .remove(nonViewScopedAltAppearances.indexOf(n));
0569: } else if (n instanceof BackgroundRetained) {
0570: numberOfBgs--;
0571: nonViewScopedBackgrounds
0572: .remove(nonViewScopedBackgrounds.indexOf(n));
0573: } else if (n instanceof ClipRetained) {
0574: numberOfClips--;
0575: nonViewScopedClips
0576: .remove(nonViewScopedClips.indexOf(n));
0577: } else if (n instanceof ModelClipRetained) {
0578: ModelClipRetained mc = (ModelClipRetained) n;
0579: numberOfModelClips--;
0580: nonViewScopedModelClips.remove(nonViewScopedModelClips
0581: .indexOf(n));
0582:
0583: } else if (n instanceof GeometryAtom) {
0584: ga = (GeometryAtom) n;
0585: // Check that we have not already cleared the mirrorobject
0586: // since mant geometry atoms could be generated for one
0587: // mirror shape
0588: if (ga.source != oldsrc) {
0589: ga.source.clearMirrorShape();
0590: oldsrc = ga.source;
0591: }
0592: } else if (n instanceof OrderedGroupRetained) {
0593: // Clear the orderedBins for this orderedGroup
0594: ((OrderedGroupRetained) n).clearDerivedDataStructures();
0595: }
0596: }
0597: if (viewScopedNodes != null) {
0598: int size = viewScopedNodes.size();
0599: int vlsize;
0600: ArrayList list;
0601: for (i = 0; i < size; i++) {
0602: n = (NodeRetained) viewScopedNodes.get(i);
0603: ArrayList vl = (ArrayList) scopedNodesViewList.get(i);
0604: if (n instanceof LightRetained) {
0605: ((LightRetained) n).isViewScoped = false;
0606: numberOfLights--;
0607: vlsize = vl.size();
0608: for (int k = 0; k < vlsize; k++) {
0609: View view = (View) vl.get(k);
0610: list = (ArrayList) viewScopedLights.get(view);
0611: list.remove(n);
0612: if (list.size() == 0) {
0613: viewScopedLights.remove(view);
0614: }
0615: }
0616: } else if (n instanceof FogRetained) {
0617: ((FogRetained) n).isViewScoped = false;
0618: numberOfFogs--;
0619: vlsize = vl.size();
0620: for (int k = 0; k < vlsize; k++) {
0621: View view = (View) vl.get(k);
0622: list = (ArrayList) viewScopedFogs.get(view);
0623: list.remove(n);
0624: if (list.size() == 0) {
0625: viewScopedFogs.remove(view);
0626: }
0627: }
0628: } else if (n instanceof AlternateAppearanceRetained) {
0629: ((AlternateAppearanceRetained) n).isViewScoped = false;
0630: numberOfAltApps--;
0631: vlsize = vl.size();
0632: for (int k = 0; k < vlsize; k++) {
0633: View view = (View) vl.get(k);
0634: list = (ArrayList) viewScopedAltAppearances
0635: .get(view);
0636: list.remove(n);
0637: if (list.size() == 0) {
0638: viewScopedAltAppearances.remove(view);
0639: }
0640: }
0641: } else if (n instanceof BackgroundRetained) {
0642: ((BackgroundRetained) n).isViewScoped = false;
0643: numberOfBgs--;
0644: vlsize = vl.size();
0645: for (int k = 0; k < vlsize; k++) {
0646: View view = (View) vl.get(k);
0647: list = (ArrayList) viewScopedBackgrounds
0648: .get(view);
0649: list.remove(n);
0650: if (list.size() == 0) {
0651: viewScopedBackgrounds.remove(view);
0652: }
0653: }
0654: } else if (n instanceof ClipRetained) {
0655: ((ClipRetained) n).isViewScoped = false;
0656: numberOfClips--;
0657: vlsize = vl.size();
0658: for (int k = 0; k < vlsize; k++) {
0659: View view = (View) vl.get(k);
0660: list = (ArrayList) viewScopedClips.get(view);
0661: list.remove(n);
0662: if (list.size() == 0) {
0663: viewScopedClips.remove(view);
0664: }
0665: }
0666: } else if (n instanceof ModelClipRetained) {
0667: ((ModelClipRetained) n).isViewScoped = false;
0668: numberOfModelClips--;
0669: vlsize = vl.size();
0670: for (int k = 0; k < vlsize; k++) {
0671: View view = (View) vl.get(k);
0672: list = (ArrayList) viewScopedModelClips
0673: .get(view);
0674: list.remove(n);
0675: if (list.size() == 0) {
0676: viewScopedModelClips.remove(view);
0677: }
0678: }
0679: }
0680: }
0681:
0682: }
0683: }
0684:
0685: LightRetained[] getInfluencingLights(RenderAtom ra, View view) {
0686: LightRetained[] lightAry = null;
0687: ArrayList globalLights;
0688: int numLights;
0689: int i, j, n;
0690:
0691: // Need to lock retlights, since on a multi-processor
0692: // system with 2 views on a single universe, there might
0693: // be councurrent access
0694: synchronized (retlights) {
0695: numLights = 0;
0696: if (ra.geometryAtom.source.inBackgroundGroup) {
0697: globalLights = ra.geometryAtom.source.geometryBackground.lights;
0698: numLights = processLights(globalLights, ra, numLights);
0699: } else {
0700: if ((globalLights = (ArrayList) viewScopedLights
0701: .get(view)) != null) {
0702: numLights = processLights(globalLights, ra,
0703: numLights);
0704: }
0705: // now process the common lights
0706: numLights = processLights(nonViewScopedLights, ra,
0707: numLights);
0708: }
0709:
0710: boolean newLights = false;
0711: if (ra.lights != null && ra.lights.length == numLights) {
0712: for (i = 0; i < ra.lights.length; i++) {
0713: for (j = 0; j < numLights; j++) {
0714: if (ra.lights[i] == retlights[j]) {
0715: break;
0716: }
0717: }
0718: if (j == numLights) {
0719: newLights = true;
0720: break;
0721: }
0722: }
0723: } else {
0724: newLights = true;
0725: }
0726: if (newLights) {
0727: lightAry = new LightRetained[numLights];
0728: for (i = 0; i < numLights; i++) {
0729: lightAry[i] = (LightRetained) retlights[i];
0730: }
0731: return (lightAry);
0732: } else {
0733: return (ra.lights);
0734: }
0735: }
0736: }
0737:
0738: // Called while holding the retlights lock
0739: int processLights(ArrayList globalLights, RenderAtom ra,
0740: int numLights) {
0741: LightRetained[] shapeScopedLt;
0742: Bounds bounds;
0743: int i, j, n;
0744: bounds = ra.localeVwcBounds;
0745: int size = globalLights.size();
0746:
0747: if (size > 0) {
0748: for (i = 0; i < size; i++) {
0749: LightRetained light = (LightRetained) globalLights
0750: .get(i);
0751: // System.err.println("vwcBounds = "+bounds);
0752: // System.err.println("light.region = "+light.region);
0753: // System.err.println("Intersected = "+bounds.intersect(light.region));
0754: // System.err.println("");
0755:
0756: // if ((light.viewList != null && light.viewList.contains(view)) &&
0757: // Treat lights in background geo as having infinite bounds
0758: if (light.lightOn
0759: && light.switchState.currentSwitchOn
0760: && (ra.geometryAtom.source.inBackgroundGroup || bounds
0761: .intersect(light.region))) {
0762: // Get the mirror Shape3D node
0763: n = ((Shape3DRetained) ra.geometryAtom.source).numlights;
0764: shapeScopedLt = ((Shape3DRetained) ra.geometryAtom.source).lights;
0765:
0766: // System.err.println("numLights per shape= "+n);
0767: // scoped Fog/light is kept in the original
0768: // shape3D node, what happens if this list changes
0769: // while accessing them?. So, Lock.
0770: if (light.isScoped) {
0771: for (j = 0; j < n; j++) {
0772: // then check if the light is scoped to
0773: // this group
0774: if (light == shapeScopedLt[j]) {
0775: retlights[numLights++] = light;
0776: break;
0777: }
0778: }
0779: } else {
0780: retlights[numLights++] = light;
0781: }
0782: }
0783: }
0784: }
0785: return numLights;
0786:
0787: }
0788:
0789: FogRetained getInfluencingFog(RenderAtom ra, View view) {
0790: FogRetained fog = null;
0791: int i, j, k, n, nfogs;
0792: Bounds closestBounds;
0793: ArrayList globalFogs;
0794: int numFogs;
0795:
0796: // Need to lock lockObj, since on a multi-processor
0797: // system with 2 views on a single universe, there might
0798: // be councurrent access
0799: synchronized (lockObj) {
0800: nfogs = 0;
0801: Bounds bounds = ra.localeVwcBounds;
0802:
0803: if (intersectedBounds.length < numberOfFogs)
0804: intersectedBounds = new Bounds[numberOfFogs];
0805:
0806: if (ra.geometryAtom.source.inBackgroundGroup) {
0807: globalFogs = ra.geometryAtom.source.geometryBackground.fogs;
0808: nfogs = processFogs(globalFogs, ra, nfogs);
0809: // If background, then nfogs > 1, take the first one
0810: if (nfogs >= 1)
0811: fog = intersectedFogs[0];
0812:
0813: } else {
0814: if ((globalFogs = (ArrayList) viewScopedFogs.get(view)) != null) {
0815: nfogs = processFogs(globalFogs, ra, nfogs);
0816: }
0817: // now process the common fogs
0818: nfogs = processFogs(nonViewScopedFogs, ra, nfogs);
0819:
0820: if (nfogs == 1)
0821: fog = intersectedFogs[0];
0822:
0823: else if (nfogs > 1) {
0824: closestBounds = bounds
0825: .closestIntersection(intersectedBounds);
0826: for (j = 0; j < nfogs; j++) {
0827: if (intersectedBounds[j] == closestBounds) {
0828: fog = intersectedFogs[j];
0829: break;
0830: }
0831: }
0832: }
0833: }
0834: return (fog);
0835: }
0836: }
0837:
0838: // Called while holding lockObj lock
0839: int processFogs(ArrayList globalFogs, RenderAtom ra, int numFogs) {
0840: int size = globalFogs.size();
0841: FogRetained fog;
0842: int i, k, n;
0843: Bounds bounds = ra.localeVwcBounds;
0844: FogRetained[] shapeScopedFog;
0845:
0846: if (globalFogs.size() > 0) {
0847: for (i = 0; i < size; i++) {
0848: fog = (FogRetained) globalFogs.get(i);
0849: // Note : There is no enable check for fog
0850: if (fog.region != null
0851: && fog.switchState.currentSwitchOn
0852: && (ra.geometryAtom.source.inBackgroundGroup || fog.region
0853: .intersect(bounds))) {
0854: n = ((Shape3DRetained) ra.geometryAtom.source).numfogs;
0855: shapeScopedFog = ((Shape3DRetained) ra.geometryAtom.source).fogs;
0856:
0857: if (fog.isScoped) {
0858: for (k = 0; k < n; k++) {
0859: // then check if the Fog is scoped to
0860: // this group
0861: if (fog == shapeScopedFog[k]) {
0862: intersectedBounds[numFogs] = fog.region;
0863: intersectedFogs[numFogs++] = fog;
0864: break;
0865: }
0866: }
0867: } else {
0868: intersectedBounds[numFogs] = fog.region;
0869: intersectedFogs[numFogs++] = fog;
0870: }
0871: }
0872: }
0873: }
0874: return numFogs;
0875: }
0876:
0877: ModelClipRetained getInfluencingModelClip(RenderAtom ra, View view) {
0878: ModelClipRetained modelClip = null;
0879: int i, j, k, n, nModelClips;
0880: Bounds closestBounds;
0881: ArrayList globalModelClips;
0882:
0883: if (ra.geometryAtom.source.inBackgroundGroup) {
0884: return null;
0885: }
0886: // Need to lock lockObj, since on a multi-processor
0887: // system with 2 views on a single universe, there might
0888: // be councurrent access
0889: synchronized (lockObj) {
0890: Bounds bounds = ra.localeVwcBounds;
0891: nModelClips = 0;
0892: if (intersectedBounds.length < numberOfModelClips)
0893: intersectedBounds = new Bounds[numberOfModelClips];
0894:
0895: if ((globalModelClips = (ArrayList) viewScopedModelClips
0896: .get(view)) != null) {
0897: nModelClips = processModelClips(globalModelClips, ra,
0898: nModelClips);
0899: }
0900:
0901: // now process the common clips
0902: nModelClips = processModelClips(nonViewScopedModelClips,
0903: ra, nModelClips);
0904:
0905: modelClip = null;
0906: if (nModelClips == 1)
0907: modelClip = intersectedModelClips[0];
0908: else if (nModelClips > 1) {
0909: closestBounds = bounds
0910: .closestIntersection(intersectedBounds);
0911: for (j = 0; j < nModelClips; j++) {
0912: if (intersectedBounds[j] == closestBounds) {
0913: modelClip = intersectedModelClips[j];
0914: break;
0915: }
0916: }
0917: }
0918: return (modelClip);
0919: }
0920:
0921: }
0922:
0923: int processModelClips(ArrayList globalModelClips, RenderAtom ra,
0924: int nModelClips) {
0925: int size = globalModelClips.size();
0926: int i, k, n;
0927: ModelClipRetained modelClip;
0928: Bounds bounds = ra.localeVwcBounds;
0929: ModelClipRetained[] shapeScopedModelClip;
0930:
0931: if (size > 0) {
0932: for (i = 0; i < size; i++) {
0933: modelClip = (ModelClipRetained) globalModelClips.get(i);
0934: if (modelClip.enableFlag == true
0935: && modelClip.region != null
0936: && modelClip.switchState.currentSwitchOn) {
0937: if (modelClip.region.intersect(bounds) == true) {
0938: n = ((Shape3DRetained) ra.geometryAtom.source).numModelClips;
0939: shapeScopedModelClip = ((Shape3DRetained) ra.geometryAtom.source).modelClips;
0940:
0941: if (modelClip.isScoped) {
0942: for (k = 0; k < n; k++) {
0943: // then check if the modelClip is scoped to
0944: // this group
0945: if (shapeScopedModelClip[k] == modelClip) {
0946:
0947: intersectedBounds[nModelClips] = modelClip.region;
0948: intersectedModelClips[nModelClips++] = modelClip;
0949: break;
0950: }
0951: }
0952: } else {
0953: intersectedBounds[nModelClips] = modelClip.region;
0954: intersectedModelClips[nModelClips++] = modelClip;
0955: }
0956: }
0957: }
0958: }
0959: }
0960: return nModelClips;
0961: }
0962:
0963: BackgroundRetained getApplicationBackground(BoundingSphere bounds,
0964: Locale viewLocale, View view) {
0965: BackgroundRetained bg = null;
0966: Bounds closestBounds;
0967: BackgroundRetained back;
0968: int i = 0, j = 0;
0969: int nbacks;
0970: ArrayList globalBgs;
0971:
0972: // Need to lock lockObj, since on a multi-processor
0973: // system with 2 views on a single universe, there might
0974: // be councurrent access
0975: synchronized (lockObj) {
0976: nbacks = 0;
0977: if (intersectedBounds.length < numberOfBgs)
0978: intersectedBounds = new Bounds[numberOfBgs];
0979:
0980: if ((globalBgs = (ArrayList) viewScopedBackgrounds
0981: .get(view)) != null) {
0982: nbacks = processBgs(globalBgs, bounds, nbacks,
0983: viewLocale);
0984: }
0985: nbacks = processBgs(nonViewScopedBackgrounds, bounds,
0986: nbacks, viewLocale);
0987:
0988: // If there are no intersections, set to black.
0989: if (nbacks == 1) {
0990: bg = intersectedBacks[0];
0991: } else if (nbacks > 1) {
0992: closestBounds = bounds
0993: .closestIntersection(intersectedBounds);
0994: for (j = 0; j < nbacks; j++) {
0995: if (intersectedBounds[j] == closestBounds) {
0996: bg = intersectedBacks[j];
0997: //System.err.println("matched " + closestBounds);
0998: break;
0999: }
1000: }
1001: }
1002: return (bg);
1003: }
1004: }
1005:
1006: // Called while holding lockObj lock
1007: int processBgs(ArrayList globalBgs, BoundingSphere bounds,
1008: int nbacks, Locale viewLocale) {
1009: int size = globalBgs.size();
1010: int i;
1011: BackgroundRetained back;
1012:
1013: for (i = 0; i < size; i++) {
1014: back = (BackgroundRetained) globalBgs.get(i);
1015: if (back.transformedRegion != null
1016: && back.switchState.currentSwitchOn) {
1017: if (back.cachedLocale != viewLocale) {
1018: localeBounds = (Bounds) back.transformedRegion
1019: .clone();
1020: // Translate the transformed region
1021: back.cachedLocale.hiRes.difference(
1022: viewLocale.hiRes, localeTranslation);
1023: localeXform.setIdentity();
1024: localeXform.setTranslation(localeTranslation);
1025: localeBounds.transform(localeXform);
1026: if (localeBounds.intersect(bounds) == true) {
1027: intersectedBounds[nbacks] = localeBounds;
1028: intersectedBacks[nbacks++] = back;
1029: }
1030: } else {
1031: if (back.transformedRegion.intersect(bounds) == true) {
1032: intersectedBounds[nbacks] = back.transformedRegion;
1033: intersectedBacks[nbacks++] = back;
1034: }
1035: }
1036: }
1037: }
1038: return nbacks;
1039: }
1040:
1041: double[] backClipDistanceInVworld(BoundingSphere bounds, View view) {
1042: int i, j;
1043: int nclips;
1044: Bounds closestBounds;
1045: ClipRetained clip;
1046: boolean backClipActive;
1047: double[] backClipDistance;
1048: double distance;
1049: ArrayList globalClips;
1050:
1051: // Need to lock intersectedBounds, since on a multi-processor
1052: // system with 2 views on a single universe, there might
1053: // be councurrent access
1054: synchronized (lockObj) {
1055: backClipDistance = null;
1056: backClipActive = false;
1057: nclips = 0;
1058: distance = 0.0;
1059: if (intersectedBounds.length < numberOfClips)
1060: intersectedBounds = new Bounds[numberOfClips];
1061:
1062: if ((globalClips = (ArrayList) viewScopedClips.get(view)) != null) {
1063: nclips = processClips(globalClips, bounds, nclips);
1064: }
1065: nclips = processClips(nonViewScopedClips, bounds, nclips);
1066:
1067: if (nclips == 1) {
1068: distance = intersectedClips[0].backDistanceInVworld;
1069: backClipActive = true;
1070: } else if (nclips > 1) {
1071: closestBounds = bounds
1072: .closestIntersection(intersectedBounds);
1073: for (j = 0; j < nclips; j++) {
1074: if (intersectedBounds[j] == closestBounds) {
1075: distance = intersectedClips[j].backDistanceInVworld;
1076: backClipActive = true;
1077: break;
1078: }
1079: }
1080: }
1081: if (backClipActive) {
1082: backClipDistance = new double[1];
1083: backClipDistance[0] = distance;
1084: }
1085: return (backClipDistance);
1086: }
1087: }
1088:
1089: int processClips(ArrayList globalClips, BoundingSphere bounds,
1090: int nclips) {
1091: int i;
1092: int size = globalClips.size();
1093: ClipRetained clip;
1094:
1095: for (i = 0; i < size; i++) {
1096: clip = (ClipRetained) globalClips.get(i);
1097: if (clip.transformedRegion != null
1098: && clip.transformedRegion.intersect(bounds) == true
1099: && clip.switchState.currentSwitchOn) {
1100: intersectedBounds[nclips] = clip.transformedRegion;
1101: intersectedClips[nclips++] = clip;
1102: }
1103: }
1104: return nclips;
1105: }
1106:
1107: void updateLight(Object[] args) {
1108: Object[] objs;
1109: LightRetained light = (LightRetained) args[0];
1110: int component = ((Integer) args[1]).intValue();
1111: // Store the value to be updated during object update
1112: // If its an ambient light, then if color changed, update immediately
1113: if ((component & (LightRetained.INIT_MIRROR)) != 0) {
1114: light.initMirrorObject(args);
1115: }
1116:
1117: if (light instanceof AmbientLightRetained
1118: && ((component & LightRetained.COLOR_CHANGED) != 0)) {
1119: light.updateImmediateMirrorObject(args);
1120: } else if ((component & (LightRetained.COLOR_CHANGED
1121: | LightRetained.INIT_MIRROR
1122: | PointLightRetained.POSITION_CHANGED
1123: | PointLightRetained.ATTENUATION_CHANGED
1124: | DirectionalLightRetained.DIRECTION_CHANGED
1125: | SpotLightRetained.DIRECTION_CHANGED
1126: | SpotLightRetained.CONCENTRATION_CHANGED | SpotLightRetained.ANGLE_CHANGED)) != 0) {
1127: objs = getObjectArray();
1128: objs[0] = args[0];
1129: objs[1] = args[1];
1130: objs[2] = args[2];
1131: objs[3] = args[3];
1132: objs[4] = args[4];
1133:
1134: objList.add(objs);
1135: } else if ((component & LightRetained.CLEAR_MIRROR) != 0) {
1136: light.clearMirrorObject(args);
1137: } else {
1138: light.updateImmediateMirrorObject(args);
1139: }
1140:
1141: }
1142:
1143: void updateBackground(Object[] args) {
1144: BackgroundRetained bg = (BackgroundRetained) args[0];
1145: bg.updateImmediateMirrorObject(args);
1146: }
1147:
1148: void updateFog(Object[] args) {
1149: Object[] objs;
1150: FogRetained fog = (FogRetained) args[0];
1151: int component = ((Integer) args[1]).intValue();
1152: if ((component & FogRetained.INIT_MIRROR) != 0) {
1153: fog.initMirrorObject(args);
1154: // Color, distance et all should be updated when renderer
1155: // is not running ..
1156: objs = getObjectArray();
1157: objs[0] = args[0];
1158: objs[1] = args[1];
1159: objs[2] = args[2];
1160: objs[3] = args[3];
1161: objs[4] = args[4];
1162: objList.add(objs);
1163: } else if ((component & FogRetained.CLEAR_MIRROR) != 0) {
1164: fog.clearMirrorObject(args);
1165: // Store the value to be updated during object update
1166: } else if ((component & (FogRetained.COLOR_CHANGED
1167: | LinearFogRetained.FRONT_DISTANCE_CHANGED
1168: | LinearFogRetained.BACK_DISTANCE_CHANGED | ExponentialFogRetained.DENSITY_CHANGED)) != 0) {
1169: objs = getObjectArray();
1170: objs[0] = args[0];
1171: objs[1] = args[1];
1172: objs[2] = args[2];
1173: objs[3] = args[3];
1174: objs[4] = args[4];
1175: objList.add(objs);
1176: } else {
1177: fog.updateImmediateMirrorObject(args);
1178: }
1179:
1180: }
1181:
1182: void updateAltApp(Object[] args) {
1183: AlternateAppearanceRetained altApp = (AlternateAppearanceRetained) args[0];
1184: int component = ((Integer) args[1]).intValue();
1185: if ((component & AlternateAppearanceRetained.INIT_MIRROR) != 0) {
1186: AlternateAppearanceRetained altapp = (AlternateAppearanceRetained) args[0];
1187: altapp.initMirrorObject(args);
1188: } else if ((component & AlternateAppearanceRetained.CLEAR_MIRROR) != 0) {
1189: AlternateAppearanceRetained altapp = (AlternateAppearanceRetained) args[0];
1190: altapp.clearMirrorObject(args);
1191: } else {
1192: altApp.updateImmediateMirrorObject(args);
1193: }
1194:
1195: }
1196:
1197: void updateClip(Object[] args) {
1198: ClipRetained clip = (ClipRetained) args[0];
1199: clip.updateImmediateMirrorObject(args);
1200: }
1201:
1202: void updateModelClip(Object[] args) {
1203: ModelClipRetained modelClip = (ModelClipRetained) args[0];
1204: Object[] objs;
1205: int component = ((Integer) args[1]).intValue();
1206:
1207: if ((component & ModelClipRetained.INIT_MIRROR) != 0) {
1208: modelClip.initMirrorObject(args);
1209: }
1210: if ((component & ModelClipRetained.CLEAR_MIRROR) != 0) {
1211: modelClip.clearMirrorObject(args);
1212: } else if ((component & (ModelClipRetained.PLANES_CHANGED
1213: | ModelClipRetained.INIT_MIRROR | ModelClipRetained.PLANE_CHANGED)) != 0) {
1214: objs = getObjectArray();
1215: objs[0] = args[0];
1216: objs[1] = args[1];
1217: objs[2] = args[2];
1218: objs[3] = args[3];
1219: objs[4] = args[4];
1220: objList.add(objs);
1221: } else {
1222: modelClip.updateImmediateMirrorObject(args);
1223: }
1224:
1225: }
1226:
1227: void updateBoundingLeaf(Object[] args) {
1228: BoundingLeafRetained bl = (BoundingLeafRetained) args[0];
1229: Object[] users = (Object[]) (args[3]);
1230: bl.updateImmediateMirrorObject(args);
1231: // Now update all users of this bounding leaf object
1232: for (int i = 0; i < users.length; i++) {
1233: LeafRetained mLeaf = (LeafRetained) users[i];
1234: mLeaf.updateBoundingLeaf();
1235: }
1236: }
1237:
1238: void updateShape3D(Object[] args) {
1239: Shape3DRetained shape = (Shape3DRetained) args[0];
1240: shape.updateImmediateMirrorObject(args);
1241: }
1242:
1243: void updateOrientedShape3D(Object[] args) {
1244: OrientedShape3DRetained shape = (OrientedShape3DRetained) args[4];
1245: shape.updateImmediateMirrorObject(args);
1246: }
1247:
1248: void updateMorph(Object[] args) {
1249: MorphRetained morph = (MorphRetained) args[0];
1250: morph.updateImmediateMirrorObject(args);
1251: }
1252:
1253: void updateTransformChange() {
1254: int i, j;
1255: Object[] nodes, nodesArr;
1256: BoundingLeafRetained bl;
1257: LightRetained ml;
1258: UnorderList arrList;
1259: int size;
1260:
1261: targets = universe.transformStructure.getTargetList();
1262: blUsers = universe.transformStructure.getBlUsers();
1263:
1264: // process misc environment nodes
1265: arrList = targets.targetList[Targets.ENV_TARGETS];
1266: if (arrList != null) {
1267: size = arrList.size();
1268: nodesArr = arrList.toArray(false);
1269:
1270: for (j = 0; j < size; j++) {
1271: nodes = (Object[]) nodesArr[j];
1272:
1273: for (i = 0; i < nodes.length; i++) {
1274: if (nodes[i] instanceof LightRetained) {
1275: ml = (LightRetained) nodes[i];
1276: ml.updateImmediateTransformChange();
1277: xformChangeList.add(nodes[i]);
1278:
1279: } else if (nodes[i] instanceof FogRetained) {
1280: FogRetained mfog = (FogRetained) nodes[i];
1281: mfog.updateImmediateTransformChange();
1282: xformChangeList.add(nodes[i]);
1283:
1284: } else if (nodes[i] instanceof AlternateAppearanceRetained) {
1285: AlternateAppearanceRetained mAltApp = (AlternateAppearanceRetained) nodes[i];
1286: mAltApp.updateImmediateTransformChange();
1287: xformChangeList.add(nodes[i]);
1288:
1289: } else if (nodes[i] instanceof BackgroundRetained) {
1290: BackgroundRetained bg = (BackgroundRetained) nodes[i];
1291: bg.updateImmediateTransformChange();
1292:
1293: } else if (nodes[i] instanceof ModelClipRetained) {
1294: ModelClipRetained mc = (ModelClipRetained) nodes[i];
1295: mc.updateImmediateTransformChange();
1296: }
1297: }
1298: }
1299: }
1300:
1301: // process BoundingLeaf nodes
1302: arrList = targets.targetList[Targets.BLN_TARGETS];
1303: if (arrList != null) {
1304: size = arrList.size();
1305: nodesArr = arrList.toArray(false);
1306: for (j = 0; j < size; j++) {
1307: nodes = (Object[]) nodesArr[j];
1308: for (i = 0; i < nodes.length; i++) {
1309: bl = (BoundingLeafRetained) nodes[i];
1310: bl.updateImmediateTransformChange();
1311: }
1312: }
1313: }
1314:
1315: // Now notify the list of all users of bounding leaves
1316: // to update its boundingleaf transformed region
1317: if (blUsers != null) {
1318: for (i = 0; i < blUsers.size(); i++) {
1319: LeafRetained leaf = (LeafRetained) blUsers.get(i);
1320: leaf.updateBoundingLeaf();
1321: }
1322: }
1323: targets = null;
1324: blUsers = null;
1325: }
1326:
1327: // The first element is TRUE, if alternate app is in effect
1328: // The second element return the appearance that should be used
1329: // Note , I can't just return null for app, then I don't know
1330: // if the appearance is null or if the alternate app in not
1331: // in effect
1332: Object[] getInfluencingAppearance(RenderAtom ra, View view) {
1333: AlternateAppearanceRetained altApp = null;
1334: int i, j, k, n, nAltApp;
1335: ;
1336: Bounds closestBounds;
1337: Bounds bounds;
1338: Object[] retVal;
1339: ArrayList globalAltApps;
1340: retVal = new Object[2];
1341:
1342: if (ra.geometryAtom.source.inBackgroundGroup) {
1343: retVal[0] = Boolean.FALSE;
1344: return retVal;
1345: }
1346:
1347: // Need to lock lockObj, since on a multi-processor
1348: // system with 2 views on a single universe, there might
1349: // be councurrent access
1350: synchronized (lockObj) {
1351: nAltApp = 0;
1352: bounds = ra.localeVwcBounds;
1353:
1354: if (intersectedBounds.length < numberOfAltApps)
1355: intersectedBounds = new Bounds[numberOfAltApps];
1356:
1357: if ((globalAltApps = (ArrayList) viewScopedAltAppearances
1358: .get(view)) != null) {
1359: nAltApp = processAltApps(globalAltApps, ra, nAltApp);
1360: }
1361: nAltApp = processAltApps(nonViewScopedAltAppearances, ra,
1362: nAltApp);
1363:
1364: altApp = null;
1365: if (nAltApp == 1)
1366: altApp = intersectedAltApps[0];
1367: else if (nAltApp > 1) {
1368: closestBounds = bounds
1369: .closestIntersection(intersectedBounds);
1370: for (j = 0; j < nAltApp; j++) {
1371: if (intersectedBounds[j] == closestBounds) {
1372: altApp = intersectedAltApps[j];
1373: break;
1374: }
1375: }
1376: }
1377: if (altApp == null) {
1378: retVal[0] = Boolean.FALSE;
1379: return retVal;
1380: } else {
1381: retVal[0] = Boolean.TRUE;
1382: retVal[1] = altApp.appearance;
1383: return retVal;
1384: }
1385: }
1386: }
1387:
1388: // Called while holding lockObj lock
1389: int processAltApps(ArrayList globalAltApps, RenderAtom ra,
1390: int nAltApp) {
1391: int size = globalAltApps.size();
1392: AlternateAppearanceRetained altApp;
1393: int i, k, n;
1394: Bounds bounds = ra.localeVwcBounds;
1395: AlternateAppearanceRetained[] shapeScopedAltApp;
1396:
1397: if (size > 0) {
1398: for (i = 0; i < size; i++) {
1399: altApp = (AlternateAppearanceRetained) globalAltApps
1400: .get(i);
1401: // System.err.println("altApp.region = "+altApp.region+" altApp.switchState.currentSwitchOn = "+altApp.switchState.currentSwitchOn+" intersect = "+altApp.region.intersect(ra.geometryAtom.vwcBounds));
1402: // System.err.println("altApp.isScoped = "+altApp.isScoped);
1403: // Note : There is no enable check for fog
1404: if (altApp.region != null
1405: && altApp.switchState.currentSwitchOn) {
1406: if (altApp.region.intersect(bounds) == true) {
1407: n = ((Shape3DRetained) ra.geometryAtom.source).numAltApps;
1408: shapeScopedAltApp = ((Shape3DRetained) ra.geometryAtom.source).altApps;
1409: if (altApp.isScoped) {
1410: for (k = 0; k < n; k++) {
1411: // then check if the light is scoped to
1412: // this group
1413: if (altApp == shapeScopedAltApp[k]) {
1414:
1415: intersectedBounds[nAltApp] = altApp.region;
1416: intersectedAltApps[nAltApp++] = altApp;
1417: break;
1418: }
1419: }
1420: } else {
1421: intersectedBounds[nAltApp] = altApp.region;
1422: intersectedAltApps[nAltApp++] = altApp;
1423: }
1424: }
1425: }
1426: }
1427: }
1428: return nAltApp;
1429: }
1430:
1431: void initViewSpecificInfo(J3dMessage m) {
1432: int[] keys = (int[]) m.args[2];
1433: ArrayList vlists = (ArrayList) m.args[1];
1434: ArrayList vsgs = (ArrayList) m.args[0];
1435: if (vsgs != null) {
1436: // System.err.println("===> non null Vsg");
1437: int size = vsgs.size();
1438: for (int i = 0; i < size; i++) {
1439: ViewSpecificGroupRetained v = (ViewSpecificGroupRetained) vsgs
1440: .get(i);
1441: ArrayList l = (ArrayList) vlists.get(i);
1442: int index = keys[i];
1443: // System.err.println("v = "+v+" index = "+index+" l = "+l);
1444: v.cachedViewList.add(index, l);
1445: /*
1446: for (int k = 0; k < v.cachedViewList.size(); k++) {
1447: System.err.println("v = "+v+" k = "+k+" v.cachedViewList.get(k) = "+v.cachedViewList.get(k));
1448: }
1449: */
1450: }
1451: }
1452: }
1453:
1454: void clearViewSpecificInfo(J3dMessage m) {
1455: int[] keys = (int[]) m.args[1];
1456: ArrayList vsgs = (ArrayList) m.args[0];
1457: if (vsgs != null) {
1458: int size = vsgs.size();
1459: for (int i = 0; i < size; i++) {
1460: ViewSpecificGroupRetained v = (ViewSpecificGroupRetained) vsgs
1461: .get(i);
1462: int index = keys[i];
1463: if (index == -1) {
1464: int csize = v.cachedViewList.size();
1465: for (int j = 0; j < csize; j++) {
1466: ArrayList l = (ArrayList) v.cachedViewList
1467: .get(j);
1468: l.clear();
1469: }
1470: v.cachedViewList.clear();
1471: } else {
1472: ArrayList l = (ArrayList) v.cachedViewList
1473: .remove(index);
1474: l.clear();
1475: }
1476: }
1477: }
1478: }
1479:
1480: void updateViewSpecificGroupChanged(J3dMessage m) {
1481: int component = ((Integer) m.args[0]).intValue();
1482: Object[] objAry = (Object[]) m.args[1];
1483:
1484: ArrayList ltList = null;
1485: ArrayList fogList = null;
1486: ArrayList mclipList = null;
1487: ArrayList altAppList = null;
1488: ArrayList bgList = null;
1489: ArrayList clipList = null;
1490: int idx;
1491:
1492: if (((component & ViewSpecificGroupRetained.ADD_VIEW) != 0)
1493: || ((component & ViewSpecificGroupRetained.SET_VIEW) != 0)) {
1494: int i;
1495: Object obj;
1496: View view = (View) objAry[0];
1497: ArrayList vsgList = (ArrayList) objAry[1];
1498: ArrayList leafList = (ArrayList) objAry[2];
1499: int[] keyList = (int[]) objAry[3];
1500: int size = vsgList.size();
1501: // Don't add null views
1502:
1503: if (view != null) {
1504: for (i = 0; i < size; i++) {
1505: ViewSpecificGroupRetained vsg = (ViewSpecificGroupRetained) vsgList
1506: .get(i);
1507: int index = keyList[i];
1508: vsg.updateCachedInformation(
1509: ViewSpecificGroupRetained.ADD_VIEW, view,
1510: index);
1511:
1512: }
1513: size = leafList.size();
1514: // Leaves is non-null only for the top VSG
1515:
1516: if (size > 0) {
1517: // Now process the list of affected leaved
1518: for (i = 0; i < size; i++) {
1519: obj = leafList.get(i);
1520: if (obj instanceof LightRetained) {
1521: ((LightRetained) obj).isViewScoped = true;
1522: numberOfLights++;
1523: if (ltList == null) {
1524: if ((ltList = (ArrayList) viewScopedLights
1525: .get(view)) == null) {
1526: ltList = new ArrayList();
1527: viewScopedLights.put(view, ltList);
1528: }
1529: }
1530: ltList.add(obj);
1531: }
1532: if (obj instanceof FogRetained) {
1533: ((FogRetained) obj).isViewScoped = true;
1534: numberOfFogs++;
1535: if (fogList == null) {
1536: if ((fogList = (ArrayList) viewScopedFogs
1537: .get(view)) == null) {
1538: fogList = new ArrayList();
1539: viewScopedFogs.put(view, fogList);
1540: }
1541: }
1542: fogList.add(obj);
1543: }
1544: if (obj instanceof ModelClipRetained) {
1545: ((ModelClipRetained) obj).isViewScoped = true;
1546: numberOfModelClips++;
1547: if (mclipList == null) {
1548: if ((mclipList = (ArrayList) viewScopedModelClips
1549: .get(view)) == null) {
1550: mclipList = new ArrayList();
1551: viewScopedModelClips.put(view,
1552: mclipList);
1553: }
1554: }
1555: mclipList.add(obj);
1556: }
1557: if (obj instanceof AlternateAppearanceRetained) {
1558: ((AlternateAppearanceRetained) obj).isViewScoped = true;
1559: numberOfAltApps++;
1560: if (altAppList == null) {
1561: if ((altAppList = (ArrayList) viewScopedAltAppearances
1562: .get(view)) == null) {
1563: altAppList = new ArrayList();
1564: viewScopedAltAppearances.put(view,
1565: altAppList);
1566: }
1567: }
1568: altAppList.add(obj);
1569: }
1570: if (obj instanceof ClipRetained) {
1571: ((ClipRetained) obj).isViewScoped = true;
1572: numberOfClips++;
1573: if (clipList == null) {
1574: if ((clipList = (ArrayList) viewScopedClips
1575: .get(view)) == null) {
1576: clipList = new ArrayList();
1577: viewScopedClips.put(view, clipList);
1578: }
1579: }
1580: clipList.add(obj);
1581: }
1582: if (obj instanceof BackgroundRetained) {
1583: ((BackgroundRetained) obj).isViewScoped = true;
1584: numberOfBgs++;
1585: if (bgList == null) {
1586: if ((bgList = (ArrayList) viewScopedBackgrounds
1587: .get(view)) == null) {
1588: bgList = new ArrayList();
1589: viewScopedBackgrounds.put(view,
1590: bgList);
1591: }
1592: }
1593: bgList.add(obj);
1594: }
1595: }
1596: if (numberOfLights > retlights.length)
1597: retlights = new LightRetained[numberOfLights];
1598: if (intersectedFogs.length < numberOfFogs)
1599: intersectedFogs = new FogRetained[numberOfFogs];
1600: if (intersectedAltApps.length < numberOfAltApps)
1601: intersectedAltApps = new AlternateAppearanceRetained[numberOfAltApps];
1602: if (intersectedBacks.length < numberOfBgs)
1603: intersectedBacks = new BackgroundRetained[numberOfBgs];
1604: if (intersectedClips.length < numberOfClips)
1605: intersectedClips = new ClipRetained[numberOfClips];
1606: if (intersectedModelClips.length < numberOfModelClips)
1607: intersectedModelClips = new ModelClipRetained[numberOfModelClips];
1608: }
1609: }
1610: }
1611: if (((component & ViewSpecificGroupRetained.REMOVE_VIEW) != 0)
1612: || ((component & ViewSpecificGroupRetained.SET_VIEW) != 0)) {
1613: int i;
1614: Object obj;
1615: ArrayList vsgList;
1616: ArrayList leafList;
1617: int[] keyList;
1618: View view;
1619:
1620: if ((component & ViewSpecificGroupRetained.REMOVE_VIEW) != 0) {
1621: view = (View) objAry[0];
1622: vsgList = (ArrayList) objAry[1];
1623: leafList = (ArrayList) objAry[2];
1624: keyList = (int[]) objAry[3];
1625: } else {
1626: view = (View) objAry[4];
1627: vsgList = (ArrayList) objAry[5];
1628: leafList = (ArrayList) objAry[6];
1629: keyList = (int[]) objAry[7];
1630: }
1631: // Don't add null views
1632: if (view != null) {
1633: int size = vsgList.size();
1634: for (i = 0; i < size; i++) {
1635: ViewSpecificGroupRetained vsg = (ViewSpecificGroupRetained) vsgList
1636: .get(i);
1637: int index = keyList[i];
1638: vsg.updateCachedInformation(
1639: ViewSpecificGroupRetained.REMOVE_VIEW,
1640: view, index);
1641:
1642: }
1643: size = leafList.size();
1644: // Leaves is non-null only for the top VSG
1645: if (size > 0) {
1646: // Now process the list of affected leaved
1647: for (i = 0; i < size; i++) {
1648: obj = leafList.get(i);
1649: if (obj instanceof LightRetained) {
1650: ((LightRetained) obj).isViewScoped = false;
1651: numberOfLights--;
1652: if (ltList == null) {
1653: ltList = (ArrayList) viewScopedLights
1654: .get(view);
1655: }
1656: ltList.remove(obj);
1657: }
1658: if (obj instanceof FogRetained) {
1659: ((FogRetained) obj).isViewScoped = false;
1660: numberOfFogs--;
1661: if (fogList == null) {
1662: fogList = (ArrayList) viewScopedFogs
1663: .get(view);
1664: }
1665: fogList.remove(obj);
1666: }
1667: if (obj instanceof ModelClipRetained) {
1668: ((ModelClipRetained) obj).isViewScoped = false;
1669: numberOfModelClips--;
1670: if (mclipList == null) {
1671: mclipList = (ArrayList) viewScopedModelClips
1672: .get(view);
1673: }
1674: mclipList.remove(obj);
1675: }
1676: if (obj instanceof AlternateAppearanceRetained) {
1677: ((AlternateAppearanceRetained) obj).isViewScoped = false;
1678: numberOfAltApps--;
1679: if (altAppList == null) {
1680: altAppList = (ArrayList) viewScopedAltAppearances
1681: .get(view);
1682: }
1683: altAppList.remove(obj);
1684: }
1685: if (obj instanceof ClipRetained) {
1686: ((ClipRetained) obj).isViewScoped = false;
1687: numberOfClips--;
1688: if (clipList == null) {
1689: clipList = (ArrayList) viewScopedClips
1690: .get(view);
1691: }
1692: clipList.remove(obj);
1693: }
1694: if (obj instanceof BackgroundRetained) {
1695: ((BackgroundRetained) obj).isViewScoped = false;
1696: numberOfBgs++;
1697: if (bgList == null) {
1698: bgList = (ArrayList) viewScopedBackgrounds
1699: .get(view);
1700: }
1701: bgList.remove(obj);
1702: }
1703: }
1704:
1705: // If there are no more lights scoped to the view,
1706: // remove the mapping
1707: if (ltList != null && ltList.size() == 0)
1708: viewScopedLights.remove(view);
1709: if (fogList != null && fogList.size() == 0)
1710: viewScopedFogs.remove(view);
1711: if (mclipList != null && mclipList.size() == 0)
1712: viewScopedModelClips.remove(view);
1713: if (altAppList != null && altAppList.size() == 0)
1714: viewScopedAltAppearances.remove(view);
1715: if (clipList != null && clipList.size() == 0)
1716: viewScopedClips.remove(view);
1717: if (bgList != null && bgList.size() == 0)
1718: viewScopedBackgrounds.remove(view);
1719: }
1720: }
1721: }
1722:
1723: }
1724:
1725: boolean isLightScopedToThisView(Object obj, View view) {
1726: LightRetained light = (LightRetained) obj;
1727: if (light.isViewScoped) {
1728: ArrayList l = (ArrayList) viewScopedLights.get(view);
1729: // If this is a scoped lights, but has no views then ..
1730: if (l == null || !l.contains(light))
1731: return false;
1732: }
1733: return true;
1734: }
1735:
1736: boolean isFogScopedToThisView(Object obj, View view) {
1737: FogRetained fog = (FogRetained) obj;
1738: if (fog.isViewScoped) {
1739: ArrayList l = (ArrayList) viewScopedFogs.get(view);
1740: // If this is a scoped fog, but has no views then ..
1741: if (l == null || !l.contains(fog))
1742: return false;
1743: }
1744: return true;
1745: }
1746:
1747: boolean isAltAppScopedToThisView(Object obj, View view) {
1748: AlternateAppearanceRetained altApp = (AlternateAppearanceRetained) obj;
1749: if (altApp.isViewScoped) {
1750: ArrayList l = (ArrayList) viewScopedAltAppearances
1751: .get(view);
1752: // If this is a scoped altapp, but has no views then ..
1753: if (l == null || !l.contains(altApp))
1754: return false;
1755: }
1756: return true;
1757: }
1758:
1759: boolean isBgScopedToThisView(Object obj, View view) {
1760: BackgroundRetained bg = (BackgroundRetained) obj;
1761: if (bg.isViewScoped) {
1762: ArrayList l = (ArrayList) viewScopedBackgrounds.get(view);
1763: // If this is a scoped bg, but has no views then ..
1764: if (l == null || !l.contains(bg))
1765: return false;
1766: }
1767: return true;
1768: }
1769:
1770: boolean isClipScopedToThisView(Object obj, View view) {
1771: ClipRetained clip = (ClipRetained) obj;
1772: if (clip.isViewScoped) {
1773: ArrayList l = (ArrayList) viewScopedClips.get(view);
1774: // If this is a scoped clip, but has no views then ..
1775: if (l == null || !l.contains(clip))
1776: return false;
1777: }
1778: return true;
1779: }
1780:
1781: boolean isMclipScopedToThisView(Object obj, View view) {
1782: ModelClipRetained mclip = (ModelClipRetained) obj;
1783: if (mclip.isViewScoped) {
1784: ArrayList l = (ArrayList) viewScopedModelClips.get(view);
1785: // If this is a scoped mclip, but has no views then ..
1786: if (l == null || !l.contains(mclip))
1787: return false;
1788: }
1789: return true;
1790: }
1791:
1792: void cleanup() {
1793: }
1794: }
|