jiglib3D物理引擎 + PV3d 鼠标拖拽示例(中文注释)

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 ); //  渲染
    }
}
}

转载于:https://www.cnblogs.com/cwin5/archive/2009/11/01/1593567.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值