package
{
import flash.geom.Point;
import flash.utils.getTimer;
import flash.display. * ;
import flash.events. * ;
import flash.ui.Keyboard;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.core.geom. * ;
import org.papervision3d.core.math. * ;
import org.papervision3d.core.proto. * ;
import org.papervision3d.cameras. * ;
import org.papervision3d.render. * ;
import org.papervision3d.events. * ;
import org.papervision3d.materials.utils. * ;
import org.papervision3d.materials.shadematerials. * ;
import org.papervision3d.objects.primitives. * ;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.scenes. * ;
import org.papervision3d.view.stats.StatsView;
import org.papervision3d.view.layer.ViewportLayer;
import org.papervision3d.view.layer.util.ViewportLayerSortMode;
import org.papervision3d.core.utils.Mouse3D;
import org.papervision3d.core.utils.InteractiveSceneManager;
import jiglib.math. * ;
import jiglib.geometry. * ;
import jiglib.physics. * ;
import jiglib.physics.constraint. * ;
public class MouseDrag extends Sprite
{
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var mylight:PointLight3D;
private var mouse3D:Mouse3D;
private var shadeMateria:FlatShadeMaterial;
private var boxBody:Array;
private var onDraging:Boolean = false ;
private var currDragBody:RigidBody;
private var dragConstraint:JConstraintWorldPoint;
private var startMousePos:JNumber3D;
private var planeToDragOn:Plane3D;
private var cameraTarget:DisplayObject3D;
public function MouseDrag()
{
stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseRelease);
stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
init3D();
}
/**
* 初始化3D
*/
private function init3D(): void
{
// 初始化3D视图
viewport = new Viewport3D( 800 , 600 , true , true );
scene = new Scene3D(); // 3D场景初始化
this .addChild(viewport);
// 排序模式
viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT
// 启用mouse3D
Mouse3D.enabled = true ;
mouse3D = viewport.interactiveSceneManager.mouse3D;
// 初始化灯光
mylight = new PointLight3D( true , true );
mylight.x = 0 ;
mylight.y = 600 ;
mylight.z = - 300 ;
// 建立地面着色材质
shadeMateria = new FlatShadeMaterial(mylight, 0x77ee77 );
// 建立地面
var planeSkin:Plane = new Plane(shadeMateria, 500 , 500 );
viewport.getChildLayer(planeSkin).layerIndex = 1 ;
scene.addChild(planeSkin);
// 建立物理世界地面
var plane:JPlane = new JPlane(planeSkin);
plane.MoveTo( new JNumber3D( 0 , 250 , 0 ), JMatrix3D.rotationX(Math.PI / 2 ));
PhysicsSystem.getInstance().AddBody(plane);
// 建立视图层
var vplObjects:ViewportLayer = new ViewportLayer(viewport, null );
vplObjects.layerIndex = 2 ;
vplObjects.sortMode = ViewportLayerSortMode.Z_SORT;
viewport.containerSprite.addLayer(vplObjects);
// 初始化立方体着色材质
shadeMateria = new FlatShadeMaterial(mylight, 0xeeee00 );
shadeMateria.interactive = true ;
var materiaList:MaterialsList = new MaterialsList();
materiaList.addMaterial(shadeMateria, " all " );
// 初始化立方体
boxBody = new Array();
var boxSkin:Cube;
var xNum: int = 6 ;
var yNum: int = 5 ;
var zNum: int = 1 ;
var num: int = 0 ;
var boxSize:JNumber3D = new JNumber3D( 40 , 30 , 40 ); // 立方体大小
var xstart:Number = - xNum * boxSize.x / 2 ;
var ystart:Number = plane.CurrentState.Position.y + boxSize.y / 2 ;
var zstart:Number = - zNum * boxSize.z / 2 ;
for (var i: int = 0 ; i < xNum; i ++ )
{
for (var j: int = 0 ; j < yNum; j ++ )
{
for (var k: int = 0 ; k < zNum; k ++ )
{
// 创建立方体
boxSkin = new Cube(materiaList, boxSize.x, boxSize.z, boxSize.y);
boxSkin.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, handleMousePress);
vplObjects.addDisplayObject3D(boxSkin);
scene.addChild(boxSkin);
// 创建物理世界立方体
boxBody[num] = new JBox(boxSkin, true , boxSize.x, boxSize.z, boxSize.y);
boxBody[num].MoveTo( new JNumber3D(xstart + (boxSize.x + 1 ) * i, ystart + boxSize.y * j, zstart + (boxSize.z + 1 ) * k), JMatrix3D.IDENTITY);
PhysicsSystem.getInstance().AddBody(boxBody[num]);
num ++ ;
}
}
}
// 创建摄像头对象
cameraTarget = new Cone( new FlatShadeMaterial(mylight, 0xee0000 ), 50 , 50 , 1 , 1 );
cameraTarget.x = 0 ;
cameraTarget.y = 250 ;
cameraTarget.z = 0 ;
// 创建摄像头对象
camera = new Camera3D();
camera.x = 0 ;
camera.y = 500 ;
camera.z = - 400 ;
camera.target = cameraTarget;
// 创建渲染引擎
renderer = new BasicRenderEngine();
// 创建视图
var stats:StatsView = new StatsView(renderer);
addChild(stats);
// 添加循环侦听(用于调用渲染引擎与物理引擎的迭代)
this .addEventListener(Event.ENTER_FRAME, loop3D);
}
/**
* 查找刚体
* 利用渲染引擎里的对象匹对
* @param skin 渲染引擎里的对象
* @return
*/
private function findSkinBody(skin:DisplayObject3D): int
{
for (var i:String in PhysicsSystem.getInstance().Bodys)
{
if (skin == PhysicsSystem.getInstance().Bodys[i].BodySkin)
{
return int (i);
}
}
return - 1 ;
}
// 处理鼠标按下
private function handleMousePress(event:InteractiveScene3DEvent): void
{
onDraging = true ;
// 取出3D中的鼠标坐标
startMousePos = new JNumber3D(mouse3D.x, mouse3D.y, mouse3D.z);
// 取出刚体
currDragBody = PhysicsSystem.getInstance().Bodys[findSkinBody(event.displayObject3D)];
// 创建拖拉平面
planeToDragOn = new Plane3D( new Number3D( 0 , 0 , - 1 ), new Number3D( 0 , 0 , - startMousePos.z));
// 添加拖拉约束
var bodyPoint:JNumber3D = JNumber3D.sub(startMousePos, currDragBody.CurrentState.Position);
dragConstraint = new JConstraintWorldPoint(currDragBody, bodyPoint, startMousePos);
PhysicsSystem.getInstance().AddConstraint(dragConstraint);
}
// 处理鼠标移动
private function handleMouseMove(event:MouseEvent): void
{
if (onDraging)
{
// 射线
var ray:Number3D = camera.unproject(viewport.containerSprite.mouseX, viewport.containerSprite.mouseY);
ray = Number3D.add(ray, new Number3D(camera.x, camera.y, camera.z));
// 更新坐标
var cameraVertex3D:Vertex3D = new Vertex3D(camera.x, camera.y, camera.z);
var rayVertex3D:Vertex3D = new Vertex3D(ray.x, ray.y, ray.z);
var intersectPoint:Vertex3D = planeToDragOn.getIntersectionLine(cameraVertex3D, rayVertex3D);
// 更新约束位置
dragConstraint.WorldPosition = new JNumber3D(intersectPoint.x, intersectPoint.y, intersectPoint.z);
}
}
// 处理鼠标释放
private function handleMouseRelease(event:MouseEvent): void
{
if (onDraging)
{
onDraging = false ;
PhysicsSystem.getInstance().RemoveConstraint(dragConstraint);
currDragBody.SetActive();
}
}
// 刷新
private function loop3D( event :Event ): void
{
PhysicsSystem.getInstance().Integrate( 0.2 ); // 调用物理引擎迭代
renderer.renderScene( scene, camera, viewport ); // 渲染
}
}
}
{
import flash.geom.Point;
import flash.utils.getTimer;
import flash.display. * ;
import flash.events. * ;
import flash.ui.Keyboard;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.core.geom. * ;
import org.papervision3d.core.math. * ;
import org.papervision3d.core.proto. * ;
import org.papervision3d.cameras. * ;
import org.papervision3d.render. * ;
import org.papervision3d.events. * ;
import org.papervision3d.materials.utils. * ;
import org.papervision3d.materials.shadematerials. * ;
import org.papervision3d.objects.primitives. * ;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.scenes. * ;
import org.papervision3d.view.stats.StatsView;
import org.papervision3d.view.layer.ViewportLayer;
import org.papervision3d.view.layer.util.ViewportLayerSortMode;
import org.papervision3d.core.utils.Mouse3D;
import org.papervision3d.core.utils.InteractiveSceneManager;
import jiglib.math. * ;
import jiglib.geometry. * ;
import jiglib.physics. * ;
import jiglib.physics.constraint. * ;
public class MouseDrag extends Sprite
{
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var mylight:PointLight3D;
private var mouse3D:Mouse3D;
private var shadeMateria:FlatShadeMaterial;
private var boxBody:Array;
private var onDraging:Boolean = false ;
private var currDragBody:RigidBody;
private var dragConstraint:JConstraintWorldPoint;
private var startMousePos:JNumber3D;
private var planeToDragOn:Plane3D;
private var cameraTarget:DisplayObject3D;
public function MouseDrag()
{
stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseRelease);
stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
init3D();
}
/**
* 初始化3D
*/
private function init3D(): void
{
// 初始化3D视图
viewport = new Viewport3D( 800 , 600 , true , true );
scene = new Scene3D(); // 3D场景初始化
this .addChild(viewport);
// 排序模式
viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT
// 启用mouse3D
Mouse3D.enabled = true ;
mouse3D = viewport.interactiveSceneManager.mouse3D;
// 初始化灯光
mylight = new PointLight3D( true , true );
mylight.x = 0 ;
mylight.y = 600 ;
mylight.z = - 300 ;
// 建立地面着色材质
shadeMateria = new FlatShadeMaterial(mylight, 0x77ee77 );
// 建立地面
var planeSkin:Plane = new Plane(shadeMateria, 500 , 500 );
viewport.getChildLayer(planeSkin).layerIndex = 1 ;
scene.addChild(planeSkin);
// 建立物理世界地面
var plane:JPlane = new JPlane(planeSkin);
plane.MoveTo( new JNumber3D( 0 , 250 , 0 ), JMatrix3D.rotationX(Math.PI / 2 ));
PhysicsSystem.getInstance().AddBody(plane);
// 建立视图层
var vplObjects:ViewportLayer = new ViewportLayer(viewport, null );
vplObjects.layerIndex = 2 ;
vplObjects.sortMode = ViewportLayerSortMode.Z_SORT;
viewport.containerSprite.addLayer(vplObjects);
// 初始化立方体着色材质
shadeMateria = new FlatShadeMaterial(mylight, 0xeeee00 );
shadeMateria.interactive = true ;
var materiaList:MaterialsList = new MaterialsList();
materiaList.addMaterial(shadeMateria, " all " );
// 初始化立方体
boxBody = new Array();
var boxSkin:Cube;
var xNum: int = 6 ;
var yNum: int = 5 ;
var zNum: int = 1 ;
var num: int = 0 ;
var boxSize:JNumber3D = new JNumber3D( 40 , 30 , 40 ); // 立方体大小
var xstart:Number = - xNum * boxSize.x / 2 ;
var ystart:Number = plane.CurrentState.Position.y + boxSize.y / 2 ;
var zstart:Number = - zNum * boxSize.z / 2 ;
for (var i: int = 0 ; i < xNum; i ++ )
{
for (var j: int = 0 ; j < yNum; j ++ )
{
for (var k: int = 0 ; k < zNum; k ++ )
{
// 创建立方体
boxSkin = new Cube(materiaList, boxSize.x, boxSize.z, boxSize.y);
boxSkin.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, handleMousePress);
vplObjects.addDisplayObject3D(boxSkin);
scene.addChild(boxSkin);
// 创建物理世界立方体
boxBody[num] = new JBox(boxSkin, true , boxSize.x, boxSize.z, boxSize.y);
boxBody[num].MoveTo( new JNumber3D(xstart + (boxSize.x + 1 ) * i, ystart + boxSize.y * j, zstart + (boxSize.z + 1 ) * k), JMatrix3D.IDENTITY);
PhysicsSystem.getInstance().AddBody(boxBody[num]);
num ++ ;
}
}
}
// 创建摄像头对象
cameraTarget = new Cone( new FlatShadeMaterial(mylight, 0xee0000 ), 50 , 50 , 1 , 1 );
cameraTarget.x = 0 ;
cameraTarget.y = 250 ;
cameraTarget.z = 0 ;
// 创建摄像头对象
camera = new Camera3D();
camera.x = 0 ;
camera.y = 500 ;
camera.z = - 400 ;
camera.target = cameraTarget;
// 创建渲染引擎
renderer = new BasicRenderEngine();
// 创建视图
var stats:StatsView = new StatsView(renderer);
addChild(stats);
// 添加循环侦听(用于调用渲染引擎与物理引擎的迭代)
this .addEventListener(Event.ENTER_FRAME, loop3D);
}
/**
* 查找刚体
* 利用渲染引擎里的对象匹对
* @param skin 渲染引擎里的对象
* @return
*/
private function findSkinBody(skin:DisplayObject3D): int
{
for (var i:String in PhysicsSystem.getInstance().Bodys)
{
if (skin == PhysicsSystem.getInstance().Bodys[i].BodySkin)
{
return int (i);
}
}
return - 1 ;
}
// 处理鼠标按下
private function handleMousePress(event:InteractiveScene3DEvent): void
{
onDraging = true ;
// 取出3D中的鼠标坐标
startMousePos = new JNumber3D(mouse3D.x, mouse3D.y, mouse3D.z);
// 取出刚体
currDragBody = PhysicsSystem.getInstance().Bodys[findSkinBody(event.displayObject3D)];
// 创建拖拉平面
planeToDragOn = new Plane3D( new Number3D( 0 , 0 , - 1 ), new Number3D( 0 , 0 , - startMousePos.z));
// 添加拖拉约束
var bodyPoint:JNumber3D = JNumber3D.sub(startMousePos, currDragBody.CurrentState.Position);
dragConstraint = new JConstraintWorldPoint(currDragBody, bodyPoint, startMousePos);
PhysicsSystem.getInstance().AddConstraint(dragConstraint);
}
// 处理鼠标移动
private function handleMouseMove(event:MouseEvent): void
{
if (onDraging)
{
// 射线
var ray:Number3D = camera.unproject(viewport.containerSprite.mouseX, viewport.containerSprite.mouseY);
ray = Number3D.add(ray, new Number3D(camera.x, camera.y, camera.z));
// 更新坐标
var cameraVertex3D:Vertex3D = new Vertex3D(camera.x, camera.y, camera.z);
var rayVertex3D:Vertex3D = new Vertex3D(ray.x, ray.y, ray.z);
var intersectPoint:Vertex3D = planeToDragOn.getIntersectionLine(cameraVertex3D, rayVertex3D);
// 更新约束位置
dragConstraint.WorldPosition = new JNumber3D(intersectPoint.x, intersectPoint.y, intersectPoint.z);
}
}
// 处理鼠标释放
private function handleMouseRelease(event:MouseEvent): void
{
if (onDraging)
{
onDraging = false ;
PhysicsSystem.getInstance().RemoveConstraint(dragConstraint);
currDragBody.SetActive();
}
}
// 刷新
private function loop3D( event :Event ): void
{
PhysicsSystem.getInstance().Integrate( 0.2 ); // 调用物理引擎迭代
renderer.renderScene( scene, camera, viewport ); // 渲染
}
}
}