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