📄 text3dretained.java
字号:
} else { // Slightly wasteful, but not quite worth to optimize yet. geometryCnt++; } } newGA.geometryArray = new GeometryRetained[geometryCnt]; newGA.lastLocalTransformArray = new Transform3D[geometryCnt]; // Reset geometryCnt; geometryCnt = 0; newGA.locale = s.locale; newGA.visible = s.visible; newGA.source = s; int gaCnt=0; GeometryRetained geometry = null; for(; gaCnt<gSize; gaCnt++) { geometry = (GeometryRetained) s.geometryList.get(gaCnt); if(geometry != null) { newGA.geoType = geometry.geoType; newGA.alphaEditable = s.isAlphaEditable(geometry); break; } } for(; gaCnt<gSize; gaCnt++) { geometry = (GeometryRetained) s.geometryList.get(gaCnt); if(geometry == null) { newGA.geometryArray[gaCnt] = null; } else { Text3DRetained t = (Text3DRetained)geometry; GeometryRetained geo; for (k=0; k<t.numChars; k++, geometryCnt++) { geo = t.geometryList[k]; if (geo != null) { newGA.geometryArray[geometryCnt] = geo; newGA.lastLocalTransformArray[geometryCnt] = t.charTransforms[k]; } else { newGA.geometryArray[geometryCnt] = null; newGA.lastLocalTransformArray[geometryCnt] = null; } } } } oldGeometryAtomList.add(oldGA); newGeometryAtomList.add(newGA); Shape3DRetained.setGeomAtom(s, newGA); } Object[] oldGAArray = oldGeometryAtomList.toArray(); Object[] newGAArray = newGeometryAtomList.toArray(); ArrayList uniqueList = getUniqueSource(shapeList); int numSrc = uniqueList.size(); int numMS3D; Shape3DRetained ms, src; for (j=0; j<numSrc; j++) { CachedTargets[] newCtArr = null; src = (Shape3DRetained)uniqueList.get(j); numMS3D = src.mirrorShape3D.size(); TargetsInterface ti = ((GroupRetained)src. parent).getClosestTargetsInterface( TargetsInterface.TRANSFORM_TARGETS); if (ti != null) { CachedTargets ct; newCtArr = new CachedTargets[numMS3D]; for (k=0; k<numMS3D; k++) { ms = (Shape3DRetained)src.mirrorShape3D.get(k); GeometryAtom ga = Shape3DRetained.getGeomAtom(ms); for(kk=0; kk<newGAArray.length; kk++) { if(ga == newGAArray[kk]) { break; } } if(kk==newGAArray.length) { System.err.println("Text3DRetained : Problem !!! Can't find matching geomAtom"); } ct = ti.getCachedTargets(TargetsInterface. TRANSFORM_TARGETS, k, -1); if (ct != null) { newCtArr[k] = new CachedTargets(); newCtArr[k].copy(ct); newCtArr[k].replace((NnuId)oldGAArray[kk], (NnuId)newGAArray[kk], Targets.GEO_TARGETS); } else { newCtArr[k] = null; } } ti.resetCachedTargets( TargetsInterface.TRANSFORM_TARGETS, newCtArr, -1); tiArrList.add(ti); newCtArrArrList.add(newCtArr); } } m[i].args[0] = oldGAArray; m[i].args[1] = newGAArray; m[i].universe = (VirtualUniverse)universeList.get(i); if(tiArrList.size() > 0) { m[i].args[2] = tiArrList.toArray(); m[i].args[3] = newCtArrArrList.toArray(); } tiArrList.clear(); newCtArrArrList.clear(); } VirtualUniverse.mc.processMessage(m); } } } } final void sendTransformChangedMessage() { J3dMessage[] m; int i, j, numMessages, sCnt; ArrayList shapeList; ArrayList gaList = new ArrayList(); Shape3DRetained s; GeometryRetained geomR; synchronized(liveStateLock) { if (source.isLive()) { synchronized (universeList) { numMessages = universeList.size(); m = new J3dMessage[numMessages]; for (i=0; i<numMessages; i++) { m[i] = new J3dMessage(); m[i].type = J3dMessage.TEXT3D_TRANSFORM_CHANGED; m[i].threads = targetThreads; shapeList = (ArrayList)userLists.get(i); // gaList = new GeometryAtom[shapeList.size() * numChars]; for (j=0; j<shapeList.size(); j++) { s = (Shape3DRetained)shapeList.get(j); // Find the right geometry. for(sCnt=0; sCnt<s.geometryList.size(); sCnt++) { geomR = (GeometryRetained) s.geometryList.get(sCnt); if(geomR == this) { break; } } if(sCnt < s.geometryList.size()) gaList.add(Shape3DRetained.getGeomAtom(s)); } m[i].args[0] = gaList.toArray(); m[i].args[1] = charTransforms; m[i].universe = (VirtualUniverse)universeList.get(i); } VirtualUniverse.mc.processMessage(m); } } } } /** * Update internal reprsentation of tranform matrices and geometry. * This method will be called whenever string or font3D change. */ final void updateCharacterData() { char c[] = new char[1]; if (geometryList.length != numChars) { geometryList = new GeometryArrayRetained[numChars]; glyphVecs = new GlyphVector[numChars]; } if (font3D != null) { for (int i=0; i<numChars; i++) { c[0] = string.charAt(i); glyphVecs[i] = font3D.font.createGlyphVector(font3D.frc, c); geometryList[i] = font3D.triangulateGlyphs(glyphVecs[i], c[0]); } } updateTransformData(); } /** * Update per character transform based on Text3D location, * per character size and path. * * WARNING: Caller of this method must make sure SceneGraph is live, * else exceptions may be thrown. */ final void updateTransformData(){ int i, k=0, numTotal=0; double width = 0, height = 0; Vector3f location = new Vector3f(this.position); Rectangle2D bounds; //Reset bounds data lower.set(location); upper.set(location); charTransforms = new Transform3D[numChars]; for (i=0; i<numChars; i++) { charTransforms[i] = new Transform3D(); } if (numChars != 0) { charTransforms[0].set(location); // Set loop counters based on path type if (path == Text3D.PATH_RIGHT || path == Text3D.PATH_UP) { k = 0; numTotal = numChars + 1; } else if (path == Text3D.PATH_LEFT || path == Text3D.PATH_DOWN) { k = 1; numTotal = numChars; // Reset bounds to bounding box if first character bounds = glyphVecs[0].getVisualBounds(); upper.x += bounds.getWidth(); upper.y += bounds.getHeight(); } for (i=1; i<numTotal; i++, k++) { width = glyphVecs[k].getLogicalBounds().getWidth(); bounds = glyphVecs[k].getVisualBounds(); // 'switch' could be outside loop with little hacking, width += charSpacing; height = bounds.getHeight(); switch (this.path) { case Text3D.PATH_RIGHT: location.x += width; upper.x += (width); if (upper.y < (height + location.y)) { upper.y = location.y + height; } break; case Text3D.PATH_LEFT: location.x -= width; lower.x -= (width); if (upper.y < ( height + location.y)) { upper.y = location.y + height; } break; case Text3D.PATH_UP: location.y += height; upper.y += height; if (upper.x < (bounds.getWidth() + location.x)) { upper.x = location.x + bounds.getWidth(); } break; case Text3D.PATH_DOWN: location.y -= height; lower.y -= height; if (upper.x < (bounds.getWidth() + location.x)) { upper.x = location.x + bounds.getWidth(); } break; } if (i < numChars) { charTransforms[i].set(location); } } // Handle string alignment. ALIGN_FIRST is handled by default if (alignment != Text3D.ALIGN_FIRST) { double cx = (upper.x - lower.x); double cy = (upper.y - lower.y); if (alignment == Text3D.ALIGN_CENTER) { cx *= .5; cy *= .5; } switch (path) { case Text3D.PATH_RIGHT: for (i=0;i < numChars;i++) { charTransforms[i].mat[3] -= cx; } lower.x -= cx; upper.x -= cx; break; case Text3D.PATH_LEFT: for (i=0;i < numChars;i++) { charTransforms[i].mat[3] += cx; } lower.x += cx; upper.x += cx; break; case Text3D.PATH_UP: for (i=0;i < numChars;i++) { charTransforms[i].mat[7] -=cy; } lower.y -= cy; upper.y -= cy; break; case Text3D.PATH_DOWN: for (i=0;i < numChars;i++) { charTransforms[i].mat[7] +=cy; } lower.y += cy; upper.y += cy; break; } } } lower.z = 0.0f; if ((font3D == null) || (font3D.fontExtrusion == null)) { upper.z = lower.z; } else { upper.z = lower.z + font3D.fontExtrusion.length; } // update geoBounds getBoundingBox(geoBounds); } /** * This method is called when the SceneGraph becomes live. All characters * used by this.string are tesselated in this method, to avoid wait during * traversal and rendering. */ void setLive(boolean inBackgroundGroup, int refCount) { // Tesselate all character data and update character transforms updateCharacterData(); super.doSetLive(inBackgroundGroup, refCount); super.markAsLive(); } // TODO -- Need to rethink. Might have to consider charTransform[] in returns pickInfo. boolean intersect(PickShape pickShape, PickInfo pickInfo, int flags, Point3d iPnt, GeometryRetained geom, int geomIndex) { Transform3D tempT3D = new Transform3D(); GeometryArrayRetained geo = null; int sIndex = -1; PickShape newPS; double minDist = Double.MAX_VALUE; double distance =0.0; Point3d closestIPnt = new Point3d(); for (int i=0; i < numChars; i++) { geo= geometryList[i]; if (geo != null) { tempT3D.invert(charTransforms[i]); newPS = pickShape.transform(tempT3D); if (geo.intersect(newPS, pickInfo, flags, iPnt, geom, geomIndex)) { if (flags == 0) { return true; } distance = newPS.distance(iPnt); if (distance < minDist) { sIndex = i; minDist = distance; closestIPnt.set(iPnt); } } } } if (sIndex >= 0) { // We need to transform iPnt to the vworld to compute the actual distance. // In this method we'll transform iPnt by its char. offset. Shape3D will // do the localToVworld transform. iPnt.set(closestIPnt); charTransforms[sIndex].transform(iPnt); return true; } return false; } boolean intersect(Point3d[] pnts) { Transform3D tempT3D = new Transform3D(); GeometryArrayRetained ga; boolean isIntersect = false; Point3d transPnts[] = new Point3d[pnts.length]; for (int j=pnts.length-1; j >= 0; j--) { transPnts[j] = new Point3d(); } for (int i=numChars-1; i >= 0; i--) { ga = geometryList[i]; if ( ga != null) { tempT3D.invert(charTransforms[i]); for (int j=pnts.length-1; j >= 0; j--) { tempT3D.transform(pnts[j], transPnts[j]); } if (ga.intersect(transPnts)) { isIntersect = true; break; } } } return isIntersect; } boolean intersect(Transform3D thisToOtherVworld, GeometryRetained geom) { GeometryArrayRetained ga; for (int i=numChars-1; i >=0; i--) { ga = geometryList[i]; if ((ga != null) && ga.intersect(thisToOtherVworld, geom)) { return true; } } return false; } boolean intersect(Bounds targetBound) { GeometryArrayRetained ga; for (int i=numChars-1; i >=0; i--) { ga = geometryList[i]; if ((ga != null) && ga.intersect(targetBound)) { return true; } } return false; } void setModelViewMatrix(Transform3D vpcToEc, Transform3D drawTransform) { this.vpcToEc = vpcToEc; this.drawTransform = drawTransform; } void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, boolean updateAlpha, float alpha, int screen, boolean ignoreVertexColors) { Transform3D trans = new Transform3D(); for (int i = 0; i < geometryList.length; i++) { trans.set(drawTransform); trans.mul(charTransforms[i]); cv.setModelViewMatrix(cv.ctx, vpcToEc.mat, trans); geometryList[i].execute(cv, ra, isNonUniformScale, updateAlpha, alpha, screen, ignoreVertexColors); } } int getClassType() { return TEXT3D_TYPE; } ArrayList getUniqueSource(ArrayList shapeList) { ArrayList uniqueList = new ArrayList(); int size = shapeList.size(); Object src; int i, index; for (i=0; i<size; i++) { src = ((Shape3DRetained)shapeList.get(i)).sourceNode; index = uniqueList.indexOf(src); if (index == -1) { uniqueList.add(src); } } return uniqueList; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -