package com.akjava.gwt.three.client.java; /** * * based on three.js webgl - draggable cubes */ import com.akjava.gwt.lib.client.JavaScriptUtils; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.three.client.gwt.GWTParamUtils; import com.akjava.gwt.three.client.gwt.core.Intersect; import com.akjava.gwt.three.client.java.utils.GWTThreeUtils; import com.akjava.gwt.three.client.js.THREE; import com.akjava.gwt.three.client.js.cameras.Camera; import com.akjava.gwt.three.client.js.core.Object3D; import com.akjava.gwt.three.client.js.core.Raycaster; import com.akjava.gwt.three.client.js.math.Matrix4; import com.akjava.gwt.three.client.js.math.Vector3; import com.akjava.gwt.three.client.js.objects.Mesh; import com.akjava.gwt.three.client.js.scenes.Scene; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; public class GWTDragObjectControler { private Mesh mouseCatchPlane; public Mesh getMouseCatchPlane() { return mouseCatchPlane; } public GWTDragObjectControler(Scene scene){ //maybe should black&transparent like js-sample mouseCatchPlane=THREE.Mesh(THREE.PlaneBufferGeometry(2000, 2000, 10, 10), THREE.MeshBasicMaterial( GWTParamUtils.MeshBasicMaterial().color(0x00ffff).wireframe(true) .visible(false) //set visible false here,to keep live raycast check )); //mouseCatchPlane.setVisible(false); //don't set visible false.now raycast check only visible objects. scene.add(mouseCatchPlane); } /** * @deprecated no more support projector */ public GWTDragObjectControler(Scene scene,JavaScriptObject projector){ this(scene); } private Object3D selectedDraggablekObject; private Object3D intersectedDraggablekObject; public void copyIntersectedPosition(){ //intersectedDraggablekObject.updateMatrixWorld(true); mouseCatchPlane.getPosition().copy( GWTThreeUtils.toPositionVec(intersectedDraggablekObject.getMatrixWorld()) ); } public Object3D getIntersectedDraggablekObject() { return intersectedDraggablekObject; } public void setIntersectedDraggablekObject(Object3D intersectedDraggablekObject) { this.intersectedDraggablekObject = intersectedDraggablekObject; copyIntersectedPosition(); } public Object3D getSelectedDraggablekObject() { return selectedDraggablekObject; } private Vector3 draggableOffset=THREE.Vector3(); public Vector3 getDraggableOffset() { return draggableOffset; } public final native Raycaster createRaycaster(int mx,int my,int sw,int sh,Camera camera)/*-{ var vector = new $wnd.THREE.Vector3( ( mx / sw ) * 2 - 1, - ( my / sh ) * 2 + 1, 0.5 ); vector.unproject(camera ); var ray = new $wnd.THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() ); return ray; }-*/; public static final native JsArray<Intersect> pickIntersects(int mx,int my,int sw,int sh,Camera camera,JsArray<Object3D> objects)/*-{ var vector = new $wnd.THREE.Vector3( ( mx / sw ) * 2 - 1, - ( my / sh ) * 2 + 1, 0.5 ); vector.unproject(camera); var ray = new $wnd.THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() ); return ray.intersectObjects( objects ); }-*/; public static final JsArray<Intersect> pickIntersectsByList(int mx,int my,int sw,int sh,Camera camera,Iterable<Object3D> objects){ @SuppressWarnings("unchecked") JsArray<Object3D> array=((JsArray<Object3D>) JavaScriptUtils.createJSArray().cast()); for(Object3D obj:objects){ array.push(obj); } return pickIntersects(mx, my, sw, sh, camera, array); } //target must be rayed /* *** sometime it error happend,check * double mouseMoved=(Math.abs(diffX)+Math.abs(diffY)); *double length=newPos.clone().subSelf(getCurrentIkData().getTargetPos()).length(); * if(length<mouseMoved*5){ */ public Vector3 moveSelectionPosition(int mouseX,int mouseY,int screenWidth, int screenHeight,Camera camera){ if(isSelected()){ try{ Raycaster ray=createRaycaster(mouseX, mouseY, screenWidth, screenHeight, camera); JsArray<Intersect> intersects = ray.intersectObject( mouseCatchPlane ); Vector3 newPos=intersects.get(0).getPoint().subSelf( draggableOffset ); log="newPos-raw:"+ThreeLog.get(newPos); Vector3 parentPos=THREE.Vector3(); if(selectedDraggablekObject.getParent()!=null){ //selectedDraggablekObject.getParent().updateMatrixWorld(true); //if call it bone moving will be broken.i have no idea. parentPos=GWTThreeUtils.toPositionVec(selectedDraggablekObject.getParent().getMatrixWorld()); //LogUtils.log("parent:"+ThreeLog.get(parentPos)); log+="parentPos:"+ThreeLog.get(parentPos); } newPos.subSelf(parentPos); Matrix4 rotM=THREE.Matrix4(); Vector3 rotation=GWTThreeUtils.rotationToVector3((selectedDraggablekObject.getParent().getMatrixWorld())); //rotM.getInverse(selectedDraggablekObject.getMatrixRotationWorld()); log+="parentRot:"+ThreeLog.get(GWTThreeUtils.radiantToDegree(rotation)); rotM.getInverse(GWTThreeUtils.rotationToMatrix4(rotation)); rotM.multiplyVector3(newPos); //Vector3 parentRotation=THREE.Vector3(); /* Object3D obj=selectedDraggablekObject; while(obj.getParent()!=null){ parentPos.addSelf(obj.getParent().getPosition()); parentRotation.addSelf(obj.getParent().getRotation()); obj=obj.getParent(); } LogUtils.log("parent-rot:"+ThreeLog.get(GWTThreeUtils.radiantToDegree(parentRotation))); */ //Matrix4 mx=GWTThreeUtils.rotationToMatrix4(parentRotation); //mx.multiplyVector3(parentPos); /* log("m:"+ThreeLog.get(selectedDraggablekObject.getPosition())); log("m:"+ThreeLog.get(GWTThreeUtils.toPositionVec(selectedDraggablekObject.getMatrix()))); log("mw:"+ThreeLog.get(GWTThreeUtils.toPositionVec(selectedDraggablekObject.getMatrixWorld()))); */ //must be same as selectedDraggablekObject return newPos; }catch(Exception e){ LogUtils.log("moveSelectionPosition:"+e.getMessage()); return null; } }else{ return null; } } private String log; public String getLog() { return log; } public void selectObject(Object3D target,int mouseX,int mouseY,int screenWidth, int screenHeight,Camera camera){ try{ selectedDraggablekObject=target; Raycaster ray=createRaycaster(mouseX, mouseY, screenWidth, screenHeight, camera); //ig dry every thing dont work //Vector3 rotation=GWTThreeUtils.rotationToVector3((selectedDraggablekObject.getMatrixWorld())); //mouseClickCatcher.getRotation().copy(rotation); selectedDraggablekObject.updateMatrixWorld(true); mouseCatchPlane.getPosition().copy( GWTThreeUtils.toPositionVec(selectedDraggablekObject.getMatrixWorld()) ); mouseCatchPlane.updateMatrixWorld(true);//very important JsArray<Intersect> pintersects=ray.intersectObject(mouseCatchPlane); if(pintersects.length()==0){ LogUtils.log("visible?:"+mouseCatchPlane.isVisible()); return; } /* * new raycaster cant handle unvisible objects */ draggableOffset.copy(pintersects.get(0).getPoint()).subSelf(mouseCatchPlane.getPosition()); /* * make a problem? if(draggableOffset.getX()<0.0001){ draggableOffset.setX(0); } if(draggableOffset.getY()<0.0001){ draggableOffset.setY(0); } if(draggableOffset.getZ()<0.0001){ draggableOffset.setZ(0); } */ }catch(Exception e){ LogUtils.log("selectObject:"+e.getMessage()); selectedDraggablekObject=null; } //LogUtils.log("offset:"+ThreeLog.get(draggableOffset)); } public void unselectObject(){ if(selectedDraggablekObject!=null){ selectedDraggablekObject=null; } } public boolean isSelected(){ return selectedDraggablekObject!=null; } }