📄 transition3d.java
字号:
destMesh = createMesh(source); source = dest; } else { destMesh = createMesh(dest); } createStaticRotation(group, destMesh, background3D, source, transitionType == SWING_IN); break; } default: throw new IllegalArgumentException("Bad 3D mode : " + transitionType); } world.animate(0); // prevent a GC in the middle of the animation... System.gc(); startTime = System.currentTimeMillis(); } private void createFlyIn(Mesh destMesh, Background background3D) { background3D.setImage(createImage2D(getSource())); KeyframeSequence trans = new KeyframeSequence(10, 3, KeyframeSequence.LINEAR); KeyframeSequence alpha = new KeyframeSequence(2, 1, KeyframeSequence.LINEAR); alpha.setDuration(duration); trans.setDuration(duration); alpha.setKeyframe(0, 0, new float[] {0.1f}); alpha.setKeyframe(1, duration, new float[] {1}); int frac = duration / 10; int time = 0; float position = -31; for(int iter = 0 ; iter < 10 ; iter++) { float[] pos = new float[] {0, 0, position}; trans.setKeyframe(iter, time, pos); position += 3; time += frac; } AnimationController animation = new AnimationController(); AnimationTrack track = new AnimationTrack(trans, AnimationTrack.TRANSLATION); destMesh.addAnimationTrack(track); track.setController(animation); track = new AnimationTrack(alpha, AnimationTrack.ALPHA); destMesh.addAnimationTrack(track); track.setController(animation); } private void createCubeRotation(Group parent, Mesh destMesh) { Group group = new Group(); parent.addChild(group); Mesh sourceMesh = createMesh(getSource()); group.addChild(destMesh); group.addChild(sourceMesh); sourceMesh.setTranslation(0f, 0, 1.0f); if(rotateRight) { destMesh.setOrientation(270, 0, 1, 0); destMesh.setTranslation(-1.0f, 0, 0f); } else { destMesh.setOrientation(90, 0, 1, 0); destMesh.setTranslation(1.0f, 0, 0f); } group.translate(0f, 0, -4.7f); KeyframeSequence rotation = new KeyframeSequence(3, 4, KeyframeSequence.SPLINE); rotation.setDuration(duration); rotation.setKeyframe(0, 0, getYRoation(0)); if(rotateRight) { rotation.setKeyframe(1, duration / 2, getYRoation(20)); rotation.setKeyframe(2, duration, getYRoation(45)); } else { rotation.setKeyframe(1, duration / 2, getYRoation(-20)); rotation.setKeyframe(2, duration, getYRoation(-45)); } AnimationController animation = new AnimationController(); AnimationTrack track = new AnimationTrack(rotation, AnimationTrack.ORIENTATION); group.addAnimationTrack(track); track.setController(animation); } private void createRotation(Group group, Mesh destMesh) { Node sourceMesh = (Node)createMesh(getSource()); group.addChild(sourceMesh); sourceMesh.setTranslation(0, 0, -3.79f); destMesh.setTranslation(0, 0, -3.8f); KeyframeSequence rotationSource = new KeyframeSequence(3, 4, KeyframeSequence.SPLINE); KeyframeSequence rotationDest = new KeyframeSequence(3, 4, KeyframeSequence.SPLINE); rotationSource.setDuration(duration); rotationDest.setDuration(duration); int half = 45; int full = 90; // prevent the rotation from staying too long in 90 degrees int halfDest = 150; int fullDest = 180; if(rotateRight) { half = -half; full = -full; halfDest = -halfDest; fullDest = -fullDest; } rotationSource.setKeyframe(0, 0, getYRoation(0)); rotationSource.setKeyframe(1, duration / 4, getYRoation(half)); rotationSource.setKeyframe(2, duration / 2, getYRoation(full)); rotationDest.setKeyframe(0, 0, getYRoation(full)); rotationDest.setKeyframe(1, duration / 2, getYRoation(halfDest)); rotationDest.setKeyframe(2, duration, getYRoation(fullDest)); AnimationController animation = new AnimationController(); AnimationTrack track = new AnimationTrack(rotationSource, AnimationTrack.ORIENTATION); sourceMesh.addAnimationTrack(track); track.setController(animation); track = new AnimationTrack(rotationDest, AnimationTrack.ORIENTATION); destMesh.addAnimationTrack(track); track.setController(animation); } private void createStaticRotation(Group group, Mesh destMesh, Background background3D, Component source, boolean swingIn) { background3D.setImage(createImage2D(source)); KeyframeSequence rotationDest; // prevent the rotation from staying too long in 90 degrees int halfDest = 90; int fullDest = 180; int mid = 135; AnimationController animation = new AnimationController(); Node rotatingNode; if(swingIn) { rotationDest = new KeyframeSequence(5, 4, KeyframeSequence.SPLINE); rotationDest.setDuration(duration); Group rotation = new Group(); group.addChild(rotation); rotation.addChild(destMesh); if(rotateRight) { rotation.translate(0, 0.8f, -4.0f); destMesh.translate(0, -0.8f, 0); } else { rotation.translate(0, -0.8f, -4.0f); destMesh.translate(0, 0.8f, 0); } int quarter = duration / 4; if(source == getSource()) { rotationDest.setKeyframe(0, 0, getXRoationTop(halfDest)); rotationDest.setKeyframe(1, quarter, getXRoationTop(mid)); rotationDest.setKeyframe(2, quarter * 2, getXRoationTop(fullDest)); rotationDest.setKeyframe(3, quarter * 3, getXRoationTop(fullDest + halfDest / 6)); rotationDest.setKeyframe(4, duration, getXRoationTop(fullDest)); } else { rotationDest.setKeyframe(0, 0, getXRoationTop(fullDest)); rotationDest.setKeyframe(1, quarter, getXRoationTop(fullDest + halfDest / 6)); rotationDest.setKeyframe(2, quarter * 2, getXRoationTop(fullDest)); rotationDest.setKeyframe(3, quarter * 3, getXRoationTop(mid)); rotationDest.setKeyframe(4, duration, getXRoationTop(halfDest)); } rotatingNode = rotation; } else { if(rotateRight) { halfDest = -halfDest; fullDest = -fullDest; mid = -mid; } destMesh.setTranslation(0, 0, -3.8f); rotationDest = new KeyframeSequence(3, 4, KeyframeSequence.SPLINE); rotationDest.setDuration(duration); group.addChild(destMesh); if(source == getSource()) { rotationDest.setKeyframe(0, 0, getYRoation(halfDest)); rotationDest.setKeyframe(1, duration / 2, getYRoation(mid)); rotationDest.setKeyframe(2, duration, getYRoation(fullDest)); } else { rotationDest.setKeyframe(0, 0, getYRoation(fullDest)); rotationDest.setKeyframe(1, duration / 2, getYRoation(mid)); rotationDest.setKeyframe(2, duration, getYRoation(halfDest)); } rotatingNode = destMesh; } AnimationTrack track = new AnimationTrack(rotationDest, AnimationTrack.ORIENTATION); rotatingNode.addAnimationTrack(track); track.setController(animation); } /** * Creates a rotation matrix on the Y axis */ private float[] getYRoation(float angle) { angle = (float)Math.toRadians(angle); return new float[] {0, (float)Math.sin(angle), 0, (float)Math.cos(angle)}; } /** * Creates a rotation matrix on the top X axis */ private float[] getXRoationTop(float angle) { angle = (float)Math.toRadians(angle); return new float[] {(float)Math.sin(angle), 0, 0, (float)Math.cos(angle)}; } private Image2D createImage2D(Component c) { int w = c.getWidth(); int h = c.getHeight(); Dialog dlg = null; if(getSource() instanceof Dialog) { dlg = (Dialog)getSource(); w = dlg.getContentPane().getWidth(); h = dlg.getContentPane().getHeight() + dlg.getTitleComponent().getHeight(); } else { if(getDestination() instanceof Dialog) { dlg = (Dialog)getDestination(); w = dlg.getContentPane().getWidth(); h = dlg.getContentPane().getHeight() + dlg.getTitleComponent().getHeight(); } } int textureW; int textureH; if(highQualityMode) { // use the true texture maximum resolution ignoring light mode... int max = M3G.getInstance().getMaxTextureDimension(); textureW = Math.min(M3G.closestHigherPowerOf2(w - 1), max); textureH = Math.min(M3G.closestHigherPowerOf2(h - 1), max); } else { textureW = Math.min(M3G.closestLowerPowerOf2(w + 1), maxTextureResolution); textureH = Math.min(M3G.closestLowerPowerOf2(h + 1), maxTextureResolution); } Image mutable = Image.createImage(w, h); Graphics g = mutable.getGraphics(); if(c instanceof Dialog) { c = dlg.getContentPane(); g.translate(-c.getAbsoluteX(), -c.getAbsoluteY() + dlg.getTitleComponent().getHeight()); dlg.getContentPane().paintComponent(g, false); dlg.getTitleComponent().paintComponent(g, false); //g.setClip(c.getAbsoluteX(), c.getAbsoluteY() + dlg.getTitleComponent().getHeight(), mutable.getWidth(), mutable.getHeight()); } else { if(dlg != null) { Component content = dlg.getContentPane(); g.translate(-content.getAbsoluteX(), -content.getAbsoluteY() + dlg.getTitleComponent().getHeight()); } else { g.translate(-c.getAbsoluteX(), -c.getAbsoluteY()); } c.paintComponent(g); } mutable = mutable.scaled(textureW, textureH); return M3G.getInstance().createImage2D(Image2D.RGB, mutable); } private Mesh createMesh(Component c) { Texture2D tex = createTexture(createImage2D(c)); CompositingMode cm = new CompositingMode(); cm.setBlending(CompositingMode.ALPHA); cm.setAlphaWriteEnable(true); cm.setDepthTestEnable(true); Appearance appearance = new Appearance(); PolygonMode polyMode = new PolygonMode(); polyMode.setPerspectiveCorrectionEnable(true); appearance.setPolygonMode(polyMode); appearance.setCompositingMode(cm); appearance.setTexture(0, tex); VertexBuffer vb = makeGeometry(); int[] indicies = {1,2,0,3}; // one quad int[] stripLens = {4}; IndexBuffer ib = new TriangleStripArray(indicies, stripLens); Mesh m = new Mesh(vb, ib, appearance); return m; } private VertexBuffer makeGeometry() { // create vertices short[] verts = { -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0 }; VertexArray va = new VertexArray(verts.length / 3, 3, 2); va.set(0, verts.length / 3, verts); // create texture coordinates short[] tcs = { 0, 1, 1, 1, 1, 0, 0, 0 }; VertexArray texArray = new VertexArray(tcs.length / 2, 2, 2); texArray.set(0, tcs.length / 2, tcs); VertexBuffer vb = new VertexBuffer(); vb.setPositions(va, 1.0f, null); // no scale, bias vb.setTexCoords(0, texArray, 1.0f, null); return vb; } /** * Creates a texture making */ private Texture2D createTexture(Image2D img) { Texture2D tex = new Texture2D(img); tex.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST); tex.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP); tex.setBlending(Texture2D.FUNC_REPLACE); return tex; } /** * @inheritDoc */ public void paintM3G(Graphics3D g) { g.render(world); } /** * High quality mode renders the transition using smoother graphics but can * take a whole lot more memory per texture and bitmap resulting in a likely * out of memory error on high resolution/low memory devices with complex UI * elements. */ public boolean isHighQualityMode() { return highQualityMode; } /** * High quality mode renders the transition using smoother graphics but can * take a whole lot more memory per texture and bitmap resulting in a likely * out of memory error on high resolution/low memory devices with complex UI * elements. */ public void setHighQualityMode(boolean highQualityMode) { this.highQualityMode = highQualityMode; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -