For a project I am trying to create an interactive bone model in Flash using Away3D. I came pretty far using the discussions in this group, but now I am stuck. So far I have a model with bones designed in 3ds Max, exported with the ColladaMax plug-in. I am able to drag items in 3d space using a helper plane, and I can also animate the bone model using jointRotationX. What I am trying to do is to make the bones draggable. What happens at this moment is that the bones break as soon as you try to drag the upper leg. I want to keep the bone structure intact.
What I have so far can be found here: http://marnick.sohosted.com/upload/InteractiveWireModel.swf The source-file: http://marnick.sohosted.com/upload/InteractiveWireModel.zip I had to rename the .dae file to .xml because Microsoft IIS webserver somehow doesn't allow access to 3d models. Any ideas how to keep the bones together, but still be able to move the bones with the mouse? My idea is to calculate the Euler angles from point 0,0,0 of the world coordinate system to the mouse x,y,z and put them into the jointRotation variables, but I get very mathematical and I hope this can be done easier. Here also the shortened source: /* Collada bones example in Away3d ... */ import away3d.animators.SkinAnimation; import away3d.animators.skin.Bone; import away3d.cameras.HoverCamera3D; import away3d.containers.ObjectContainer3D; import away3d.containers.Scene3D; import away3d.containers.View3D; import away3d.core.base.Object3D; import away3d.events.MouseEvent3D; import away3d.events.Loader3DEvent; import away3d.loaders.Collada; import away3d.loaders.data.AnimationData; import away3d.loaders.Loader3D; import away3d.primitives.Cube; import away3d.primitives.Plane; //engine variables var cam:HoverCamera3D; var view:View3D; var scene:Scene3D; //objectvariables var collada:Collada; var loader:Loader3D; var model:ObjectContainer3D; var cube:Cube; var colPlane:Plane; var draggingObject:Object3D = null; var bone :Bone; var bones :Array; //navigation variables var rotate:Number; var scrollX:Number; var scrollY:Number; var mouseDownBool:Boolean = false; var mX:Number = 0; var mY:Number = 0; var tempX:Number = 0; var tempY:Number = 0; var tempZ:Number = 0; var lastKey:uint; var keyIsDown:Boolean = false; var clickEvent:MouseEvent3D; //navigation variables var dragBool:Boolean = false; var lastPanAngle:Number; var lastTiltAngle:Number; var lastMouseX:Number; var lastMouseY:Number; // dragging variables var clickOn:Number = 0; var Minus:Number = 1; var Plus:Number = 1; stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; init(); /** * Global initialise function */ function init():void { //Debug.active = true; initEngine(); initObjects(); initListeners(); } /** * Initialise the engine */ function initEngine():void { scene = new Scene3D(); cam = new HoverCamera3D(); cam.z = -300; cam.panangle = 0; cam.targetpanangle = 210; cam.tiltangle = 90; cam.targettiltangle = 20; cam.mintiltangle = 5; cam.maxtiltangle = 70; cam.hover(); //view = new View3D({cam:cam, scene:scene}); view = new View3D(); view.camera = cam; view.scene = scene; view.x = 400; view.y = 300; view.mouseZeroMove = true; addChild(view); cube = new Cube({name:"cube",material:"blue#black", depth:10, width: 10, height:10, x:50, y:50}); view.scene.addChild(cube); view.render(); } /** * Initialise the scene objects */ function initObjects():void { collada = new Collada(); collada.scaling = 1; loader = Collada.load("leg_running.xml"); loader.addOnSuccess(onLoaderSuccess); scene.addChild(loader); colPlane = new Plane(); //colPlane.material = NullMaterial; colPlane.width = 400; colPlane.height = 400; colPlane.ownCanvas = true; colPlane.alpha = 0.3; colPlane.yUp = false; scene.addChild(colPlane); colPlane.addEventListener(MouseEvent3D.MOUSE_MOVE, onMouseMoveEvent); } /** * Listener function for loading complete event */ function onLoaderSuccess(event:Loader3DEvent):void { model = ObjectContainer3D(event.loader.handle); scene.addChild(model); cam.target = model; cube.addOnMouseDown(onModelMouseDown); model.addOnMouseOver(onModelMouseOver); model.addOnMouseDown(onModelMouseDown); model.useHandCursor = true; model.mouseEnabled = true; } /** * Initialise the listeners */ function initListeners():void { addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(Event.RESIZE, onResize); stage.addEventListener('mouseDown', onMouseDownEvent); stage.addEventListener('mouseUp', onMouseUpEvent); onResize(); } /** * Navigation and render loop */ function onEnterFrame(event:Event):void { //update the cam position if(mouseDownBool && !dragBool) { tempX = (mouseX - mX) / 2; cam.targetpanangle += tempX; mX = mouseX; tempY = (mouseY - mY) / 2; cam.targettiltangle += tempY; mY = mouseY; } //render scene cam.hover(); view.render(); } function movePlane(x:int, y:int, z:int) { colPlane.x = x; colPlane.y = y; colPlane.z = z; colPlane.rotationX = cam.rotationX; colPlane.rotationY = cam.rotationY; } function onModelMouseDown(e:MouseEvent3D):void { movePlane(e.sceneX, e.sceneY,e.sceneZ); dragBool = true; draggingObject = e.object; // start dragging } function onModelMouseOver(e:MouseEvent3D):void { trace(e.object.name); } function onMouseDownEvent(e:Event):void { mouseDownBool = true; mX = mouseX; mY = mouseY; stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); } function onMouseUpEvent(e:Event):void { mouseDownBool = false; mX = 0; mY = 0; dragBool = false; draggingObject = null; stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); } function onStageMouseLeave(event:Event):void { dragBool = false; stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); } function onMouseMoveEvent(e:MouseEvent3D):void { if (dragBool) { if(draggingObject.name == "cube") { draggingObject.x = e.sceneX; draggingObject.y = e.sceneY; draggingObject.z = e.sceneZ; } else if(draggingObject.name == "Cylinder03-node") { model.getBoneByName("upperleg-node").x = e.sceneX; model.getBoneByName("upperleg-node").y = e.sceneY; model.getBoneByName("upperleg-node").z = e.sceneZ; } } }
