/extensions/examples/extension3D/Extension3DScene.java

http://mt4j.googlecode.com/ · Java · 487 lines · 312 code · 120 blank · 55 comment · 25 complexity · f79e806651cfc1fb8a626312daaaf3d1 MD5 · raw file

  1. package examples.extension3D;
  2. import java.awt.event.KeyEvent;
  3. import java.io.File;
  4. import java.util.ArrayList;
  5. import javax.media.opengl.GL;
  6. import org.mt4j.MTApplication;
  7. import org.mt4j.components.MTComponent;
  8. import org.mt4j.components.MTLight;
  9. import org.mt4j.components.TransformSpace;
  10. import org.mt4j.components.visibleComponents.shapes.mesh.MTTriangleMesh;
  11. import org.mt4j.input.IMTEventListener;
  12. import org.mt4j.input.gestureAction.DefaultDragAction;
  13. import org.mt4j.input.gestureAction.DefaultRotateAction;
  14. import org.mt4j.input.inputProcessors.IGestureEventListener;
  15. import org.mt4j.input.inputProcessors.MTGestureEvent;
  16. import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
  17. import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
  18. import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleEvent;
  19. import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
  20. import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer;
  21. import org.mt4j.sceneManagement.AbstractScene;
  22. import org.mt4j.util.camera.Icamera;
  23. import org.mt4j.util.math.Tools3D;
  24. import org.mt4j.util.math.Vector3D;
  25. import org.mt4j.util.modelImporter.ModelImporterFactory;
  26. import org.mt4j.util.opengl.GLMaterial;
  27. import org.mt4jx.input.gestureAction.CreateDragHelperAction;
  28. import org.mt4jx.input.gestureAction.Rotate3DAction;
  29. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.ClusterDataManager;
  30. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.ClusterHub;
  31. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.IVisualizeMethodProvider;
  32. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.FingerTapGrouping.FingerTapSelectionManager;
  33. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.GroupVisualizations.BlinkingLineVisualizationAction;
  34. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.GroupVisualizations.LineVisualizationAction;
  35. import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.GroupVisualizations.LineVisualizationWithOutlinesAction;
  36. import org.mt4jx.input.inputProcessors.componentProcessors.Rotate3DProcessor.Rotate3DProcessor;
  37. import org.mt4jx.util.extension3D.ComponentHelper;
  38. import org.mt4jx.util.extension3D.Collision.CollisionManager;
  39. import processing.core.PGraphics;
  40. public class Extension3DScene extends AbstractScene {
  41. private MTApplication mtApp;
  42. private CollisionManager collisionManager;
  43. private ClusterHub clusterHub;
  44. private ArrayList<Rotate3DAction> drawAction = new ArrayList<Rotate3DAction>(); //REMOVE
  45. private MTComponent comp = null;
  46. Vector3D grundflaecheTranslation = null;
  47. public Extension3DScene(MTApplication mtApplication, String name) {
  48. super(mtApplication, name);
  49. mtApp = mtApplication;
  50. Icamera cam = this.getSceneCam();
  51. collisionManager = new CollisionManager(this,mtApp);
  52. this.registerGlobalInputProcessor(new CursorTracer(mtApp, this));
  53. //Init light settings
  54. MTLight.enableLightningAndAmbient(mtApplication, 150, 150, 150, 255);
  55. //Create a light source //I think GL_LIGHT0 is used by processing!
  56. MTLight light = new MTLight(mtApplication, GL.GL_LIGHT3, new Vector3D(0,0,0));
  57. //Set up a material to react to the light
  58. GLMaterial material = new GLMaterial(Tools3D.getGL(mtApplication));
  59. material.setAmbient(new float[]{ .3f, .3f, .3f, 1f });
  60. material.setDiffuse(new float[]{ .9f, .9f, .9f, 1f } );
  61. material.setEmission(new float[]{ .0f, .0f, .0f, 1f });
  62. material.setSpecular(new float[]{ 1.0f, 1.0f, 1.0f, 1f }); // almost white: very reflective
  63. material.setShininess(110);// 0=no shine, 127=max shine
  64. MTComponent machine4;
  65. machine4 = getMeshGroup(mtApplication, new Vector3D(-400.0f,-700.0f,1200.0f), System.getProperty("user.dir") + File.separator + "extensions" +File.separator + "examples" + File.separator + "extension3D" + File.separator + "data" + File.separator +
  66. "elevtruck" + File.separator + "elev_truck.obj",light,material,"elevTruck");
  67. machine4.rotateX(ComponentHelper.getCenterPointGlobal(machine4), -90.0f);
  68. machine4.scale(0.5f,0.5f,0.5f,ComponentHelper.getCenterPointGlobal(machine4));
  69. MTComponent machine5;
  70. machine5 = getMeshGroup(mtApplication, new Vector3D(-100.0f,-700.0f,1200.0f), System.getProperty("user.dir") + File.separator + "extensions" + File.separator + "examples" + File.separator + "extension3D" + File.separator + "data" + File.separator +
  71. "elevtruck" + File.separator + "elev_truck.obj",light,material,"elevTruck");
  72. machine5.rotateX(ComponentHelper.getCenterPointGlobal(machine5), -90.0f);
  73. machine5.scale(0.5f,0.5f,0.5f,ComponentHelper.getCenterPointGlobal(machine5));
  74. MTComponent robotArm;
  75. robotArm = getMeshGroup(mtApplication, new Vector3D(-450.0f,-150.0f,-200.0f), System.getProperty("user.dir") + File.separator + "extensions" + File.separator + "examples" + File.separator + "extension3D" + File.separator + "data" + File.separator +
  76. "robotArm" + File.separator + "robotArm.obj",light,material,"robotArm");
  77. robotArm.scale(0.4f,0.4f,0.4f,ComponentHelper.getCenterPointGlobal(robotArm));
  78. MTComponent robotArm2;
  79. robotArm2 = getMeshGroup(mtApplication, new Vector3D(-150.0f,-150.0f,-200.0f), System.getProperty("user.dir") + File.separator + "extensions" + File.separator + "examples" + File.separator + "extension3D" + File.separator + "data" + File.separator +
  80. "robotArm" + File.separator + "robotArm.obj",light,material,"robotArm");
  81. robotArm2.scale(0.4f,0.4f,0.4f,ComponentHelper.getCenterPointGlobal(robotArm2));
  82. MTComponent grundflaecheGroup = getGroundMesh(mtApplication, System.getProperty("user.dir") + File.separator + "extensions" + File.separator + "examples" + File.separator + "extension3D" + File.separator + "data" + File.separator +
  83. "floor" + File.separator + "grundflaeche3.obj",light,material,cam);
  84. /**/
  85. //NORMAL 3D OBJECTS VERSION
  86. /*MTCube cube1 = new MTCube(mtApplication, 50.0f);
  87. MTComponent group10 = getMeshGroupForSimpleObject(mtApplication,cube1,new Vector3D(0.0f,0.0f,0.0f),light,material,"cube");
  88. MTSphere sphere1 = new MTSphere(mtApplication,"sphere1",32,32,100.0f);
  89. MTComponent group20 = getMeshGroupForSimpleObject(mtApplication,sphere1,new Vector3D(0.0f,200.0f,0.0f),light,material,"sphere1");
  90. MTSphere sphere2 = new MTSphere(mtApplication,"sphere2",32,32,100.0f);
  91. MTComponent group30 = getMeshGroupForSimpleObject(mtApplication,sphere2,new Vector3D(200.0f,000.0f,0.0f),light,material,"sphere2");*/
  92. //END NORMAL 3D OBJECTS VERSION DO NOT FORGET selectionManager addclusterable below
  93. ClusterDataManager clusterManager = new ClusterDataManager(mtApplication,this.getCanvas(),collisionManager);
  94. clusterHub = new ClusterHub();
  95. clusterManager.addClusterEventListener(clusterHub);
  96. LineVisualizationAction visAction = new LineVisualizationAction(mtApplication);
  97. clusterHub.addEventListener(visAction);
  98. //BlinkingLineVisualizationAction visAction2 = new BlinkingLineVisualizationAction(mtApplication);
  99. //clusterHub.addEventListener(visAction2);
  100. //LASSO GROUPING
  101. //LassoGroupSelectionManager selectionManager = new LassoGroupSelectionManager(this.getCanvas(),clusterManager);
  102. //selectionManager.addSelectionListener(clusterHub);
  103. //this.getCanvas().registerInputProcessor(selectionManager);
  104. //LASSO GROUPING END
  105. //FINGERTAP GROUPING
  106. FingerTapSelectionManager selectionManager = new FingerTapSelectionManager(clusterManager,this.getCanvas());
  107. selectionManager.addSelectionListener(clusterHub);
  108. this.registerGlobalInputProcessor(selectionManager);
  109. //FINGERTAP GROUPING END
  110. selectionManager.addClusterable(machine4);
  111. selectionManager.addClusterable(machine5);
  112. selectionManager.addClusterable(robotArm);
  113. selectionManager.addClusterable(robotArm2);
  114. //NORMAL 3D OBJECTS VERSION
  115. //selectionManager.addClusterable(group10);
  116. //selectionManager.addClusterable(group20);
  117. //selectionManager.addClusterable(group30);
  118. //NORMAL 3D OBJECTS VERSION END
  119. collisionManager.addObjectsToCollisionDomain();
  120. }
  121. public MTTriangleMesh getBiggestMesh(MTTriangleMesh[] meshes){
  122. MTTriangleMesh currentBiggestMesh = null;
  123. //Get the biggest mesh and extract its width
  124. float currentBiggestWidth = Float.MIN_VALUE;
  125. for (int i = 0; i < meshes.length; i++) {
  126. MTTriangleMesh triangleMesh = meshes[i];
  127. float width = triangleMesh.getWidthXY(TransformSpace.GLOBAL);
  128. if (width > currentBiggestWidth){
  129. currentBiggestWidth = width;
  130. currentBiggestMesh = triangleMesh;
  131. }
  132. }
  133. return currentBiggestMesh;
  134. }
  135. public void onEnter() {
  136. getMTApplication().registerKeyEvent(this);
  137. }
  138. public void onLeave() {
  139. getMTApplication().unregisterKeyEvent(this);
  140. }
  141. public void keyEvent(KeyEvent e){
  142. //System.out.println(e.getKeyCode());
  143. int evtID = e.getID();
  144. if (evtID != KeyEvent.KEY_PRESSED)
  145. return;
  146. switch (e.getKeyCode()){
  147. case KeyEvent.VK_F:
  148. System.out.println("FPS: " + mtApp.frameRate);
  149. break;
  150. case KeyEvent.VK_PLUS:
  151. this.getSceneCam().moveCamAndViewCenter(0, 0, -10);
  152. break;
  153. case KeyEvent.VK_MINUS:
  154. this.getSceneCam().moveCamAndViewCenter(0, 0, +10);
  155. break;
  156. case KeyEvent.VK_1:
  157. LineVisualizationAction visAction = new LineVisualizationAction(mtApp);
  158. removeAllVisualization(clusterHub);
  159. clusterHub.addEventListener(visAction);
  160. break;
  161. case KeyEvent.VK_2:
  162. BlinkingLineVisualizationAction visAction2 = new BlinkingLineVisualizationAction(this.mtApp);
  163. removeAllVisualization(clusterHub);
  164. clusterHub.addEventListener(visAction2);
  165. break;
  166. case KeyEvent.VK_3:
  167. LineVisualizationWithOutlinesAction visAction3 = new LineVisualizationWithOutlinesAction(this.mtApp);
  168. removeAllVisualization(clusterHub);
  169. clusterHub.addEventListener(visAction3);
  170. break;
  171. case KeyEvent.VK_4:
  172. this.getCanvas().rotateY(new Vector3D(400.0f,300.0f,0.0f),-90.0f);
  173. break;
  174. default:
  175. break;
  176. }
  177. }
  178. public void removeAllVisualization(ClusterHub cHub)
  179. {
  180. ArrayList<IMTEventListener> toRemove = new ArrayList<IMTEventListener>();
  181. for(IMTEventListener listener : cHub.getListeners())
  182. {
  183. if(listener instanceof IVisualizeMethodProvider)
  184. {
  185. toRemove.add(listener);
  186. }
  187. }
  188. cHub.getListeners().removeAll(toRemove);
  189. }
  190. public void drawAndUpdate(PGraphics g, long timeDelta) {
  191. super.drawAndUpdate(g, timeDelta);
  192. g.pushMatrix();
  193. Tools3D.beginGL(mtApp);
  194. GL gl = Tools3D.getGL(mtApp);
  195. if(drawAction!=null)
  196. {
  197. for(Rotate3DAction act:drawAction)
  198. {
  199. if(act.isDrawAble())
  200. {
  201. act.draw();
  202. }
  203. }
  204. }
  205. Tools3D.endGL(mtApp);
  206. g.popMatrix();
  207. }
  208. private MTComponent getMeshGroupForSimpleObject(MTApplication mtApplication,MTTriangleMesh inputMesh,Vector3D translation,MTLight light,GLMaterial material,String name)
  209. {
  210. //Create a group and set the light for the whole mesh group ->better for performance than setting light to more comps
  211. //MTComponent group1 = new MTComponent(mtApplication);
  212. final MTComponent meshGroup = new MTComponent(mtApplication, "Mesh group");
  213. meshGroup.setLight(light);
  214. this.getCanvas().addChild(meshGroup);
  215. //Desired position for the meshes to appear at
  216. Vector3D destinationPosition = new Vector3D(mtApplication.width/2+200.0f, mtApplication.height/2, 50);
  217. //Desired scale for the meshes
  218. float destinationScale = mtApplication.width*0.94f;
  219. //Load the meshes with the ModelImporterFactory (A file can contain more than 1 mesh)
  220. MTTriangleMesh[] meshes = new MTTriangleMesh[1];
  221. meshes[0] = inputMesh;
  222. //Get the biggest mesh in the group to use as a reference for setting the position/scale
  223. final MTTriangleMesh biggestMesh = this.getBiggestMesh(meshes);
  224. Vector3D translationToScreenCenter = new Vector3D(destinationPosition);
  225. translationToScreenCenter.subtractLocal(biggestMesh.getCenterPointGlobal());
  226. Vector3D scalingPoint = new Vector3D(biggestMesh.getCenterPointGlobal());
  227. float biggestWidth = biggestMesh.getWidthXY(TransformSpace.GLOBAL);
  228. float scale = destinationScale/biggestWidth;
  229. //Move the group the the desired position
  230. meshGroup.translateGlobal(translationToScreenCenter.getAdded(translation));
  231. meshGroup.scale(scale/10, scale/10, scale/10,translationToScreenCenter.getAdded(translation));
  232. meshGroup.setName(name);
  233. //meshGroup.addChild(meshGroup);
  234. for (int i = 0; i < meshes.length; i++) {
  235. MTTriangleMesh mesh = meshes[i];
  236. mesh.setName(name + " " + i);
  237. meshGroup.addChild(mesh);
  238. mesh.unregisterAllInputProcessors(); //Clear previously registered input processors
  239. mesh.setPickable(true);
  240. //If the mesh has more than 20 vertices, use a display list for faster rendering
  241. if (mesh.getVertexCount() > 20)
  242. mesh.generateAndUseDisplayLists();
  243. //Set the material to the mesh (determines the reaction to the lightning)
  244. if (mesh.getMaterial() == null)
  245. mesh.setMaterial(material);
  246. mesh.setDrawNormals(false);
  247. }
  248. meshGroup.rotateX(translationToScreenCenter.getAdded(translation),90.0f);
  249. //add to Collision World
  250. for(int i=0;i<meshes.length;i++)
  251. {
  252. collisionManager.addMeshToCollisionGroup(meshGroup, meshes[i], translationToScreenCenter.getAdded(translation));
  253. }
  254. settingsForNormalMeshGroup(mtApplication,meshGroup);
  255. return meshGroup;
  256. }
  257. private MTComponent getMeshGroup(MTApplication mtApplication,Vector3D translation,String filename,MTLight light,GLMaterial material,String name)
  258. {
  259. //Create a group and set the light for the whole mesh group ->better for performance than setting light to more comps
  260. //MTComponent group1 = new MTComponent(mtApplication);
  261. final MTComponent meshGroup = new MTComponent(mtApplication, "Mesh group");
  262. meshGroup.setLight(light);
  263. this.getCanvas().addChild(meshGroup);
  264. //Desired position for the meshes to appear at
  265. Vector3D destinationPosition = new Vector3D(mtApplication.width/2+200.0f, mtApplication.height/2, 50);
  266. //Desired scale for the meshes
  267. float destinationScale = mtApplication.width*0.94f;
  268. //Load the meshes with the ModelImporterFactory (A file can contain more than 1 mesh)
  269. MTTriangleMesh[] meshes = ModelImporterFactory.loadModel(mtApp,filename, 180, true, false );
  270. //Get the biggest mesh in the group to use as a reference for setting the position/scale
  271. final MTTriangleMesh biggestMesh = this.getBiggestMesh(meshes);
  272. Vector3D translationToScreenCenter = new Vector3D(destinationPosition);
  273. translationToScreenCenter.subtractLocal(biggestMesh.getCenterPointGlobal());
  274. Vector3D scalingPoint = new Vector3D(biggestMesh.getCenterPointGlobal());
  275. float biggestWidth = biggestMesh.getWidthXY(TransformSpace.GLOBAL);
  276. float scale = destinationScale/biggestWidth;
  277. //Move the group the the desired position
  278. meshGroup.translateGlobal(translationToScreenCenter.getAdded(translation));
  279. meshGroup.scale(scale/2, scale/2, scale/2,translationToScreenCenter.getAdded(translation));
  280. meshGroup.setName(name);
  281. //meshGroup.addChild(meshGroup);
  282. for (int i = 0; i < meshes.length; i++) {
  283. MTTriangleMesh mesh = meshes[i];
  284. mesh.setName(name + " " + i);
  285. meshGroup.addChild(mesh);
  286. mesh.unregisterAllInputProcessors(); //Clear previously registered input processors
  287. mesh.setPickable(true);
  288. //If the mesh has more than 20 vertices, use a display list for faster rendering
  289. if (mesh.getVertexCount() > 20)
  290. mesh.generateAndUseDisplayLists();
  291. //Set the material to the mesh (determines the reaction to the lightning)
  292. if (mesh.getMaterial() == null)
  293. mesh.setMaterial(material);
  294. mesh.setDrawNormals(false);
  295. }
  296. meshGroup.rotateX(translationToScreenCenter.getAdded(translation),90.0f);
  297. //add to Collision World
  298. for(int i=0;i<meshes.length;i++)
  299. {
  300. collisionManager.addMeshToCollisionGroup(meshGroup, meshes[i], translationToScreenCenter.getAdded(translation));
  301. }
  302. settingsForNormalMeshGroup(mtApplication,meshGroup);
  303. return meshGroup;
  304. }
  305. private MTComponent getGroundMesh(MTApplication mtApplication,String filename,MTLight light,GLMaterial material,Icamera cam)
  306. {
  307. MTComponent grundflaecheGroup = new MTComponent(mtApplication);
  308. MTTriangleMesh[] grundflaeche = ModelImporterFactory.loadModel(mtApp,filename, 0, true, false );
  309. grundflaecheGroup.setLight(light);
  310. this.getCanvas().addChild(grundflaecheGroup);
  311. grundflaecheTranslation = new Vector3D(mtApp.getWidth()/2.f,mtApp.getHeight()/2.f,-300.0f);
  312. final MTTriangleMesh biggestMeshGrundflaeche = this.getBiggestMesh(grundflaeche);
  313. grundflaecheGroup.translateGlobal(grundflaecheTranslation);
  314. grundflaecheGroup.rotateXGlobal(grundflaecheTranslation,90.0f);
  315. float biggestWidthGrundflaeche = biggestMeshGrundflaeche.getWidthXY(TransformSpace.GLOBAL);
  316. float biggestHeightGrundflaeche = biggestMeshGrundflaeche.getHeightXY(TransformSpace.GLOBAL);
  317. grundflaecheGroup.scale(cam.getFrustum().getWidthOfPlane(-300.0f)/biggestWidthGrundflaeche,
  318. cam.getFrustum().getHeightOfPlane(-300.0f)/biggestHeightGrundflaeche,1.0f,grundflaecheTranslation);
  319. grundflaecheGroup.setComposite(true);
  320. //grundflaecheGroup.setPickable(false);
  321. grundflaecheGroup.setName("grundflaeche");
  322. for(int i=0;i<grundflaeche.length;i++)
  323. {
  324. grundflaecheGroup.addChild(grundflaeche[i]);
  325. grundflaeche[i].unregisterAllInputProcessors(); //Clear previously registered input processors
  326. grundflaeche[i].setPickable(false);
  327. //If the mesh has more than 20 vertices, use a display list for faster rendering
  328. if (grundflaeche[i].getVertexCount() > 20)
  329. grundflaeche[i].generateAndUseDisplayLists();
  330. //Set the material to the mesh (determines the reaction to the lightning)
  331. if (grundflaeche[i].getMaterial() == null)
  332. grundflaeche[i].setMaterial(material);
  333. grundflaeche[i].setDrawNormals(false);
  334. }
  335. for(int i=0;i<grundflaeche.length;i++)
  336. {
  337. collisionManager.addMeshToCollisionGroup(grundflaecheGroup,grundflaeche[i], grundflaecheTranslation);
  338. }
  339. return grundflaecheGroup;
  340. }
  341. private void settingsForNormalMeshGroup(MTApplication mtApplication,final MTComponent meshGroup)
  342. {
  343. meshGroup.setComposite(true); //-> Group gets picked instead of its children
  344. meshGroup.registerInputProcessor(new ScaleProcessor(mtApplication));
  345. meshGroup.addGestureListener(ScaleProcessor.class, new IGestureEventListener(){
  346. //@Override
  347. public boolean processGestureEvent(MTGestureEvent ge) {
  348. ScaleEvent se = (ScaleEvent)ge;
  349. meshGroup.scaleGlobal(se.getScaleFactorX(), se.getScaleFactorY(), se.getScaleFactorX(), ComponentHelper.getCenterPointGlobal(meshGroup));
  350. return false;
  351. }
  352. });
  353. meshGroup.registerInputProcessor(new RotateProcessor(mtApplication));
  354. meshGroup.addGestureListener(RotateProcessor.class, new DefaultRotateAction());
  355. meshGroup.setGestureAllowance(RotateProcessor.class,true);
  356. meshGroup.addGestureListener(DragProcessor.class, new CreateDragHelperAction(mtApplication,this.getCanvas(),this.getSceneCam(),meshGroup));
  357. meshGroup.registerInputProcessor(new Rotate3DProcessor(mtApplication,meshGroup));
  358. Rotate3DAction act = new Rotate3DAction(mtApplication,meshGroup);
  359. drawAction.add(act);
  360. meshGroup.addGestureListener(Rotate3DProcessor.class,act);
  361. meshGroup.setGestureAllowance(Rotate3DProcessor.class,true);
  362. meshGroup.registerInputProcessor(new DragProcessor(mtApplication));
  363. meshGroup.addGestureListener(DragProcessor.class,new DefaultDragAction());
  364. meshGroup.setGestureAllowance(DragProcessor.class,true);
  365. }
  366. }