-
-
Save JohnBrookes/62e4c7d57dd2b02a153e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import away3d.cameras.Camera3D; | |
import away3d.containers.ObjectContainer3D; | |
import away3d.containers.Scene3D; | |
import away3d.containers.View3D; | |
import away3d.controllers.HoverController; | |
import away3d.core.partition.MeshNode; | |
//import away3d.core.base.CompactSubGeometry; | |
import away3d.core.pick.PickingColliderType; | |
import away3d.core.pick.PickingType; | |
import away3d.debug.AwayStats; | |
import away3d.entities.Mesh; | |
import away3d.events.AssetEvent; | |
import away3d.events.LoaderEvent; | |
import away3d.events.MouseEvent3D; | |
import away3d.library.AssetLibrary; | |
import away3d.lights.DirectionalLight; | |
import away3d.lights.shadowmaps.NearDirectionalShadowMapper; | |
import away3d.loaders.Loader3D; | |
import away3d.loaders.parsers.AWD2Parser; | |
import away3d.materials.ColorMaterial; | |
import away3d.materials.lightpickers.StaticLightPicker; | |
import away3d.materials.methods.EnvMapMethod; | |
import away3d.materials.methods.FilteredShadowMapMethod; | |
import away3d.materials.methods.NearShadowMapMethod; | |
import away3d.materials.TextureMaterial; | |
import away3d.primitives.CapsuleGeometry; | |
import away3d.primitives.CubeGeometry; | |
import away3d.primitives.PlaneGeometry; | |
import away3d.primitives.SphereGeometry; | |
import away3d.textures.BitmapCubeTexture; | |
//import away3d.textures.CubeReflectionTexture; | |
import away3d.tools.utils.Drag3D; | |
import away3d.utils.Cast; | |
import awayphysics.collision.dispatch.AWPCollisionObject; | |
import awayphysics.collision.dispatch.AWPGhostObject; | |
import awayphysics.collision.shapes.AWPBoxShape; | |
import awayphysics.collision.shapes.AWPCapsuleShape; | |
import awayphysics.collision.shapes.AWPCompoundShape; | |
import awayphysics.collision.shapes.AWPSphereShape; | |
import awayphysics.collision.shapes.AWPStaticPlaneShape; | |
import awayphysics.debug.AWPDebugDraw; | |
import awayphysics.dynamics.AWPDynamicsWorld; | |
import awayphysics.dynamics.AWPRigidBody; | |
import awayphysics.dynamics.constraintsolver.AWPGeneric6DofConstraint; | |
import awayphysics.dynamics.constraintsolver.AWPPoint2PointConstraint; | |
import awayphysics.math.AWPMath; | |
import flash.display.Sprite; | |
import flash.display.StageAlign; | |
import flash.display.StageScaleMode; | |
import flash.events.Event; | |
import flash.events.MouseEvent; | |
import flash.geom.Vector3D; | |
public class JBChainPickingTest extends Sprite | |
{ | |
[Embed(source="chianLink.awd",mimeType="application/octet-stream")] | |
private var AWDAsset:Class; | |
// Environment map. | |
[Embed(source="../embeds/skybox/snow_positive_x.jpg")] | |
private var EnvPosX:Class; | |
[Embed(source="../embeds/skybox/snow_positive_y.jpg")] | |
private var EnvPosY:Class; | |
[Embed(source="../embeds/skybox/snow_positive_z.jpg")] | |
private var EnvPosZ:Class; | |
[Embed(source="../embeds/skybox/snow_negative_x.jpg")] | |
private var EnvNegX:Class; | |
[Embed(source="../embeds/skybox/snow_negative_y.jpg")] | |
private var EnvNegY:Class; | |
[Embed(source="../embeds/skybox/snow_negative_z.jpg")] | |
private var EnvNegZ:Class; | |
private var view:View3D; | |
private var scene:Scene3D; | |
private var camera:Camera3D; | |
//camera controls | |
private var move:Boolean = false; | |
private var lastPanAngle:Number; | |
private var lastTiltAngle:Number; | |
private var lastMouseX:Number; | |
private var lastMouseY:Number; | |
//lights | |
private var slp:StaticLightPicker; | |
private var dlight:DirectionalLight; | |
// | |
private var timeStep:Number = 1.0 / 60; | |
private var physics:AWPDynamicsWorld; | |
private var debugDraw:AWPDebugDraw; | |
private var camController:HoverController; | |
private var links:Array = []; | |
private var sphereShape:AWPSphereShape; | |
private var shadowMapMethod:NearShadowMapMethod; | |
private var dlight2:DirectionalLight; | |
private var slp2:StaticLightPicker; | |
private var shadowMapMethod2:NearShadowMapMethod; | |
private var cubeTexture:BitmapCubeTexture; | |
private var envMethod:EnvMapMethod; | |
//private var reflectionTexture:CubeReflectionTexture; | |
private var drag3D:Drag3D; | |
private var ready:Boolean; | |
private var mat:ColorMaterial; | |
private var sg:SphereGeometry; | |
private var body:AWPRigidBody; | |
private var pc:AWPPoint2PointConstraint; | |
//private var pc:AWPGeneric6DofConstraint; | |
private var currentDrag:Mesh; | |
private var mouseRb:AWPRigidBody; | |
private var d3d:Drag3D; | |
private const collsionGround : int = 1; | |
private const collsionLink : int = 2; | |
private const collsionMouse : int = 4; | |
private var debugPick:Mesh; | |
private var mat2:ColorMaterial; | |
private var debugPick2:Mesh; | |
private var p2pA:Mesh; | |
public function JBChainPickingTest() | |
{ | |
if (stage) | |
init(); | |
else | |
addEventListener(Event.ADDED_TO_STAGE, init); | |
} | |
private function init(e:Event = null):void | |
{ | |
removeEventListener(Event.ADDED_TO_STAGE, init); | |
// entry point | |
stage.scaleMode = StageScaleMode.NO_SCALE; | |
stage.align = StageAlign.TOP_LEFT; | |
init3D(); | |
initLights(); | |
initPhysics(); | |
initLoader(); | |
initListeners(); | |
} | |
private function init3D():void | |
{ | |
view = new View3D(); | |
view.backgroundColor = 0x0; | |
view.antiAlias = 8; | |
scene = view.scene; | |
camera = view.camera; | |
//view.mousePicker = PickingType.RAYCAST_BEST_HIT; | |
addChild(view); | |
camController = new HoverController(camera, null, 0, 0, 3000); | |
camController.tiltAngle = 20; | |
camController.yFactor = 2; | |
camController.steps = 32 | |
camController.minTiltAngle = 0 | |
camController.maxTiltAngle = 50 | |
camController.lookAtPosition = (new Vector3D(0, 400, 0)); | |
camera.lens.far = 9000; | |
addChild(new AwayStats(view)); | |
} | |
private function initLights():void | |
{ | |
dlight = new DirectionalLight(1, -1, -1); | |
scene.addChild(dlight); | |
dlight.specular = 1; | |
dlight.ambient = 0.1; | |
dlight.diffuse = 0.4; | |
dlight.shadowMapper = new NearDirectionalShadowMapper(.8); | |
// slp = new StaticLightPicker([dlight]); | |
shadowMapMethod = new NearShadowMapMethod(new FilteredShadowMapMethod(dlight)); | |
shadowMapMethod.epsilon = .0007; | |
dlight2 = new DirectionalLight(1, -1, 0); | |
scene.addChild(dlight2); | |
dlight2.specular = 1; | |
dlight2.ambient = 0.1; | |
dlight2.diffuse = 0.4; | |
dlight2.shadowMapper = new NearDirectionalShadowMapper(.8); | |
slp = new StaticLightPicker([dlight, dlight2]); | |
shadowMapMethod2 = new NearShadowMapMethod(new FilteredShadowMapMethod(dlight2)); | |
shadowMapMethod2.epsilon = .0007; | |
cubeTexture = new BitmapCubeTexture(Cast.bitmapData(EnvPosX), Cast.bitmapData(EnvNegX), Cast.bitmapData(EnvPosY), Cast.bitmapData(EnvNegY), Cast.bitmapData(EnvPosZ), Cast.bitmapData(EnvNegZ)); | |
envMethod = new EnvMapMethod(cubeTexture, 0.8); | |
} | |
private function initPhysics():void | |
{ | |
physics = AWPDynamicsWorld.getInstance(); | |
physics.initWithDbvtBroadphase(); | |
//1 visual units equal to 0.01 bullet meters by default, this value is inversely with physics world scaling | |
// so 1cm = 1 away unit | |
physics.scaling = 1000; | |
debugDraw = new AWPDebugDraw(view, physics); | |
//debugDraw.debugMode = AWPDebugDraw.DBG_NoDebug; | |
//debugDraw.debugMode = AWPDebugDraw.DBG_DrawCollisionShapes; | |
debugDraw.debugMode = AWPDebugDraw.DBG_DrawConstraints | AWPDebugDraw.DBG_DrawConstraintLimits; | |
} | |
private function initLoader():void | |
{ | |
Loader3D.enableParser(AWD2Parser); | |
AssetLibrary.loadData(new AWDAsset(), null, null, new AWD2Parser()); | |
AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, initObjects); | |
AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, assetComplete); | |
} | |
private function assetComplete(e:AssetEvent):void | |
{ | |
if (e.asset is Mesh) | |
{ | |
TextureMaterial(Mesh(e.asset).material).specular = 1; | |
TextureMaterial(Mesh(e.asset).material).addMethod(envMethod) | |
TextureMaterial(Mesh(e.asset).material).shadowMethod = shadowMapMethod; | |
Mesh(e.asset).material.lightPicker = slp; | |
} | |
} | |
private function initObjects(e:LoaderEvent):void | |
{ | |
var sph:Mesh = new Mesh(new SphereGeometry(100, 0, 0), new ColorMaterial()); | |
var groundshape:AWPStaticPlaneShape = new AWPStaticPlaneShape(); | |
var groundCO:AWPRigidBody = new AWPRigidBody(groundshape, null,0); | |
//physics.addRigidBodyWithGroup(groundCO, collsionGround, collsionLink); | |
physics.addRigidBody(groundCO); | |
//groundCO.restitution = 0.5; | |
groundCO.friction = 1; | |
//groundCO.rollingFriction = 1; | |
var groundMat:ColorMaterial = new ColorMaterial(); | |
groundMat.lightPicker = slp; | |
groundMat.shadowMethod = shadowMapMethod; | |
var ground:Mesh = new Mesh(new PlaneGeometry(8000, 8000), groundMat); | |
scene.addChild(ground); | |
var groundMat2:ColorMaterial = new ColorMaterial(0xcccccc, 0.4); | |
groundMat2.lightPicker = slp; | |
groundMat2.shadowMethod = shadowMapMethod2; | |
var ground2:Mesh = new Mesh(new PlaneGeometry(8000, 8000), groundMat2); | |
ground2.y = 1; | |
scene.addChild(ground2); | |
/*var cubeGeom:CubeGeometry = new CubeGeometry(8000, 8000, 8000); | |
var cubeMat:ColorMaterial = new ColorMaterial(0x0,0.1); | |
var cubeMesh:Mesh = new Mesh(cubeGeom, cubeMat); | |
cubeMesh.castsShadows = false; | |
scene.addChild(cubeMesh); | |
Mesh(cubeMesh).mouseEnabled = true; | |
Mesh(cubeMesh).addEventListener(MouseEvent3D.DOUBLE_CLICK, onMouseDb);*/ | |
var linkMesh:Mesh = AssetLibrary.getAsset("polySurface3") as Mesh; | |
linkMesh.geometry.convertToSeparateBuffers(); | |
for (var i:uint = 1; i < 2; i++) | |
for (var j:uint = 12; j > 1; j--) | |
{ | |
createLink(new Vector3D(i * 260, 100 + j * 350, 0), new Vector3D(0, j * 90, 0), linkMesh); | |
// if (j % 21 == 0) | |
// links[links.length - 1].mass = 0 | |
} | |
//balls | |
sphereShape = new AWPSphereShape(80); | |
mat = new ColorMaterial(0xfc6a11); | |
mat.lightPicker = slp; | |
mat2 = new ColorMaterial(0x6afc11,0.4); | |
mat2.lightPicker = slp; | |
sg = new SphereGeometry(80) | |
debugPick = new Mesh(sg, mat); | |
debugPick.visible = false | |
scene.addChild(debugPick) | |
/*debugPick2 = new Mesh(sg, mat2); | |
debugPick2.scaleX =2 | |
scene.addChild(debugPick2) | |
//debugPick.visible = false | |
p2pA = new Mesh(sg, new ColorMaterial(0xff0000)); | |
p2pA.scaleY = 2 | |
scene.addChild(p2pA);*/ | |
d3d = new Drag3D(view, Mesh(debugPick), Drag3D.PLANE_XY); | |
mouseRb = new AWPRigidBody(new AWPSphereShape(1010), debugPick,0); | |
physics.addRigidBodyWithGroup(mouseRb, collsionMouse, 0); | |
mouseRb.angularDamping = 0.9; | |
mouseRb.linearDamping = 0.9; | |
} | |
private function createLink(pos:Vector3D, rot:Vector3D, mesh:Mesh = null):void | |
{ | |
var clone:Mesh = Mesh(mesh.clone()) | |
Mesh(clone).mouseEnabled = true; | |
Mesh(clone).pickingCollider = PickingColliderType.AS3_BEST_HIT; | |
Mesh(clone).addEventListener(MouseEvent3D.DOUBLE_CLICK, onMouseDb); | |
Mesh(clone).addEventListener(MouseEvent3D.MOUSE_DOWN, onMouseLinkDown); | |
scene.addChild(clone); | |
var linkCompound:AWPCompoundShape = new AWPCompoundShape(); | |
var linkShape:AWPCapsuleShape = new AWPCapsuleShape(50, 100); | |
linkCompound.addChildShape(linkShape, new Vector3D(0, 250, 0), new Vector3D(0, 0, 90)); | |
linkCompound.addChildShape(linkShape, new Vector3D(0, -250, 0), new Vector3D(0, 0, 90)); | |
linkCompound.addChildShape(linkShape, new Vector3D(105, 204, 0), new Vector3D(0, 0, 27)); | |
linkCompound.addChildShape(linkShape, new Vector3D(-105, 204, 0), new Vector3D(0, 0, -27)); | |
linkCompound.addChildShape(linkShape, new Vector3D(105, -204, 0), new Vector3D(0, 0, -27)); | |
linkCompound.addChildShape(linkShape, new Vector3D(-105, -204, 0), new Vector3D(0, 0, 27)); | |
linkShape = new AWPCapsuleShape(50, 320); | |
linkCompound.addChildShape(linkShape, new Vector3D(128, 0, 0)); | |
linkCompound.addChildShape(linkShape, new Vector3D(-128, 0, 0)); | |
var cubeRb:AWPRigidBody = new AWPRigidBody(linkCompound, clone, 0.5); | |
cubeRb.position = pos; | |
cubeRb.rotationY = rot.y; | |
cubeRb.restitution = 0.1; | |
cubeRb.friction = 0.3; | |
physics.addRigidBody(cubeRb); | |
cubeRb.activationState = AWPCollisionObject.DISABLE_DEACTIVATION; | |
clone.extra = { rb:cubeRb }; | |
links.push(cubeRb); | |
/**/ | |
} | |
private function onMouseLinkDown(e:MouseEvent3D):void | |
{ | |
trace("chain click" + e.scenePosition) | |
var pos:Vector3D = e.scenePosition | |
pos = pos.add(e.localPosition); | |
d3d.planePosition = pos//e.scenePosition | |
mouseRb.transform = Mesh(e.currentTarget).transform.clone(); | |
trace(e.localPosition) | |
//pc = new AWPGeneric6DofConstraint( Mesh(e.currentTarget).extra.rb, new Vector3D(0, 0, 0), new Vector3D(), mouseRb, new Vector3D(0, 0, 0), new Vector3D()); | |
pc= new AWPPoint2PointConstraint(mouseRb,new Vector3D(), Mesh(e.currentTarget).extra.rb, e.localPosition); | |
//pc.limitSoftness = 0.0001 | |
// | |
//pc.setLinearLimit(new Vector3D(0, 0, 0), new Vector3D(0, 420, 0)); | |
//pc.getRotationalLimitMotor(0).stopERP = 42; | |
//pc.getRotationalLimitMotor(1).stopERP = 42; | |
//pc.getRotationalLimitMotor(2).stopERP = 42; | |
//pc.getTranslationalLimitMotor().stopERP = new Vector3D(2,2,2); | |
// | |
//pc.getRotationalLimitMotor(0).stopCFM = 8; | |
//pc.getRotationalLimitMotor(1).stopCFM = 8; | |
//pc.getRotationalLimitMotor(2).stopCFM = 8; | |
//pc.getTranslationalLimitMotor().stopCFM = new Vector3D(4,4,4); | |
//pc.getTranslationalLimitMotor().enableMotorY | |
//pc.getTranslationalLimitMotor().targetVelocity = new Vector3D(0, 1, 0); | |
//pc.getTranslationalLimitMotor().maxMotorForce = new Vector3D(0, 1,0); | |
//pc.getTranslationalLimitMotor().damping = 0.9 | |
//pc.getTranslationalLimitMotor().limitSoftness = 0.8 | |
physics.addConstraint(pc, true); | |
currentDrag = Mesh(e.currentTarget); | |
} | |
private function handleEnterFrame(e:Event):void | |
{ | |
if (ready) | |
{ | |
var pos:Vector3D = d3d.getIntersect(); | |
pos.y = Math.max(pos.y, 150); | |
mouseRb.position = pos; | |
physics.step(view.deltaTime/1000,6,1.0/240); | |
//physics.step(1.0 / 60, 1, 1.0 / 240); | |
debugDraw.debugDrawWorld(); | |
if (body) | |
trace(body.linearVelocity.length); | |
} | |
if (pc) | |
{ | |
//if (d3d.getIntersect().y > 10) | |
d3d.updateDrag(); | |
// pc.getTranslationalLimitMotor().targetVelocity = new Vector3D(0, -0.01,0) | |
} | |
if (move) | |
{ | |
camController.panAngle = 0.3 * (stage.mouseX - lastMouseX) + lastPanAngle; | |
camController.tiltAngle = 0.3 * (stage.mouseY - lastMouseY) + lastTiltAngle; | |
} | |
//trace(_drag3D.getIntersect()); | |
view.render(); | |
} | |
private function onMouseDown(event:MouseEvent):void | |
{ | |
ready = true; | |
/*lastPanAngle = camController.panAngle; | |
lastTiltAngle = camController.tiltAngle; | |
lastMouseX = stage.mouseX; | |
lastMouseY = stage.mouseY; | |
move = true;*/ | |
stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); | |
} | |
/** | |
* Mouse up listener for navigation | |
*/ | |
private function onMouseUp(event:MouseEvent):void | |
{ | |
move = false; | |
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); | |
if (pc) | |
{ | |
physics.removeConstraint(pc) | |
physics.removeRigidBody(mouseRb); | |
} | |
} | |
private function onMouseDb(event:MouseEvent3D):void | |
{ | |
var pos:Vector3D = view.camera.position; | |
var mpos:Vector3D = event.scenePosition; | |
trace(mpos) | |
var impulse:Vector3D = mpos.subtract(pos); | |
impulse.normalize(); | |
impulse.scaleBy(14); | |
// shoot a sphere | |
var sphereMesh:Mesh = new Mesh(sg, mat); | |
scene.addChild(sphereMesh); | |
body = new AWPRigidBody(sphereShape, sphereMesh, 1); | |
physics.addRigidBody(body); | |
body.position = pos; | |
body.ccdSweptSphereRadius = 0.08 | |
body.friction = 1; | |
body.angularDamping = 0.8; | |
//body.rollingFriction = 1; | |
body.applyCentralImpulse(impulse); | |
} | |
private function onMouseWheel(event:MouseEvent):void | |
{ | |
camController.distance -= event.delta * 80; | |
} | |
/** | |
* Mouse stage leave listener for navigation | |
*/ | |
private function onStageMouseLeave(event:Event):void | |
{ | |
move = false; | |
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave); | |
} | |
private function onStageResize(event:Event):void | |
{ | |
view.width = stage.stageWidth; | |
view.height = stage.stageHeight; | |
} | |
private function initListeners():void | |
{ | |
addEventListener(Event.ENTER_FRAME, handleEnterFrame); | |
stage.addEventListener(Event.RESIZE, onStageResize); | |
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); | |
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment