softbody-stage3d-nape
/**
* Copyright J.J ( http://wonderfl.net/user/J.J )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dequ
*/
package {
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.events.MouseEvent;
import nape.phys.BodyList;
import nape.constraint.PivotJoint; import nape.constraint.WeldJoint;
import nape.shape.Circle;
import nape.shape.Shape;
import nape.shape.Polygon;
import nape.phys.BodyType;
import nape.phys.Body;
import nape.util.BitmapDebug;
import nape.geom.Vec2;
import nape.space.Space;
import flash.geom.Vector3D;
import flash.utils.getTimer;
import flash.geom.Matrix3D;
import flash.display3D.Program3D;
import flash.display3D.Context3DProgramType;
import com.adobe.utils.AGALMiniAssembler;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.textures.Texture;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.Context3D;
import flash.display.Stage3D;
import flash.events.Event;
import flash.display.Sprite;
/**
* @author javid jafari
*/
public class Stage3dAndNapeSoftBody extends Sprite {
private static var DEBUG : Boolean;
private var Math : Object;
private var h : int;
private var w : int;
private var vertecies : Vector.<Number>;
private var s3d : Stage3D;
private var c3d : Context3D;
private var vertexBuffer : VertexBuffer3D;
private var indexbuffer : IndexBuffer3D;
private var texture : Texture;
private var vertexShaderAssembler : AGALMiniAssembler;
private var fragmentShaderAssembler : AGALMiniAssembler;
private var program : Program3D;
private var m : Matrix3D;
private var space : Space;
private var bitmapDebugger : BitmapDebug;
private var border : Body;
private var b0 : Body;
private var b1 : Body;
private var b2 : Body;
private var b3 : Body;
private var b4 : Body;
private var handjoint : PivotJoint;
private var rad : Number=20;
private var b1id : Number;
public function Stage3dAndNapeSoftBody() {
Wonderfl.disable_capture();
Wonderfl.capture_delay( 60);
if (stage) inits()
else addEventListener(Event.ADDED_TO_STAGE, inits)
}
private function inits(event : Event=null) : void {
stage.frameRate=60
w=stage.stageWidth , h=stage.stageHeight
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onCreate)
stage.stage3Ds[0].requestContext3D()
}
private function onCreate(event : Event) : void {
s3d=event.target as Stage3D
c3d=s3d.context3D
c3d.enableErrorChecking=true
c3d.configureBackBuffer(w,h,1)
// x, y, z, u, v
vertecies=Vector.<Number>([
-0.5,-0.5,0, 0, 1,
-0.5, 0.5,0, 0, 0,
0.5, 0.5,0, 1, 0,
0.5,-0.5,0, 1, 1
])
vertexBuffer=c3d.createVertexBuffer(4, 5)
vertexBuffer.uploadFromVector(vertecies, 0, 4)
var indexVertices:Vector.<uint>=Vector.<uint>([0,1,2,2,3,0])
indexbuffer=c3d.createIndexBuffer(6)
indexbuffer.uploadFromVector(indexVertices,0,6)
var shape:Sprite=new Sprite()
shape.filters=[new BlurFilter(20,20)]
with(shape.graphics){
beginGradientFill(GradientType.RADIAL, [0x00ff00,0x005500], [1,1], [50,255])
drawCircle(0, 0, 100)
endFill()
}
var bmp:BitmapData=new BitmapData(256, 256,true,0x00000000)
//bmp.noise(.1,0,255)
var mtrx:Matrix=new Matrix()
mtrx.translate(bmp.width/2, bmp.height/2)
bmp.draw(shape,mtrx)
texture=c3d.createTexture(bmp.width, bmp.height, Context3DTextureFormat.BGRA, false)
texture.uploadFromBitmapData(bmp)
vertexShaderAssembler=new AGALMiniAssembler()
vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
'm44 op,va0,vc0\n'+
'mov v0,va1\n'
)
fragmentShaderAssembler=new AGALMiniAssembler()
fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
'tex ft0,v0,fs0 <2d,linear,nomip>\n'+
'mov oc,ft0')
program=c3d.createProgram()
program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode)
c3d.setVertexBufferAt(0,vertexBuffer,0,'float3')
c3d.setVertexBufferAt(1, vertexBuffer,3,'float2')
c3d.setTextureAt(0, texture)
c3d.setProgram(program)
m=new Matrix3D()
m.appendScale(.5, .5,1)
c3d.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,m,true)
//initialize phyX
space=new Space(new Vec2(0,600))
DEBUG=false
if(DEBUG){
bitmapDebugger=new BitmapDebug(w, h)
bitmapDebugger.display.alpha=.3
stage.addChild(bitmapDebugger.display)
}
border=new Body(BodyType.STATIC)
with(border.shapes){
add(new Polygon(Polygon.rect(0, 0, w, -1)))
add(new Polygon(Polygon.rect(0, 0, -1, h)))
add(new Polygon(Polygon.rect(0, h, w, 1)))
add(new Polygon(Polygon.rect(w,0, 1, h)))
}
space.bodies.add(border)
b0=getBall(50, 50, rad);
b1=getBall(150, 50, rad)
b2=getBall(150, 150, rad)
b3=getBall(50, 150, rad)
b4=getBall(50, 150, rad)
var j0:WeldJoint=new WeldJoint(b0, b1, new Vec2(50,50), new Vec2())
var j1:WeldJoint=new WeldJoint(b1, b2, new Vec2(50,-50), Vec2.weak())
var j2:WeldJoint=new WeldJoint(b1, b3, new Vec2(50,50), Vec2.weak())
var j3:WeldJoint=new WeldJoint(b1, b4, new Vec2(-50,50), Vec2.weak())
j0.stiff=j1.stiff=j2.stiff=j3.stiff=false
j0.frequency=j1.frequency=j2.frequency=j3.frequency=2
with(space.constraints){add(j0),add(j1),add(j2),add(j3)}
b1id=b1.id
handjoint=new PivotJoint(space.world, null, Vec2.weak(), Vec2.weak())
handjoint.active=false
handjoint.stiff=false
space.constraints.add(handjoint)
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown)
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp)
//set mathematical tools
Math={}
Math.prop=function (A:Number,Amin:Number,Amax:Number,Bmin:Number,Bmax:Number):Number
{
var a:Number=((Bmin-Bmax)/(Amin-Amax));
var b:Number=Bmin-(Amin*a);
var _y:Number=(a*A)+b;
return _y;
}
addEventListener(Event.ENTER_FRAME, loop)
}
private function getBall(x:Number,y:Number,rad:Number) : Body {
var ball:Body=new Body();ball.position.setxy(x, y);ball.allowRotation=false
var shp:Shape=new Circle(rad)
shp.material.dynamicFriction=.1
shp.material.elasticity=20
shp.filter.collisionGroup=2
shp.filter.collisionMask=~2
ball.shapes.add(shp),space.bodies.add(ball);
return ball
private function onStageMouseUp(event : MouseEvent) : void {
if(handjoint.active) handjoint.active=false
}
private function checkHand(x:Number,y:Number) : void {
var p:Vec2=Vec2.get(x,y)
var bodies:BodyList=space.bodiesUnderPoint(p)
for (var i : int = 0; i < bodies.length; i++) {
var body:Body=bodies.at(i)
if(body.isDynamic() && body.id==b1id){
handjoint.body2=body
handjoint.anchor2.set(body.worldPointToLocal(p))
handjoint.active=true
break
}
}
}
private function loop(event : Event) : void {
//calculating verteX position
vertecies[0]=Math.prop(b4.position.x-rad,0,w,-2,2)
vertecies[1]=-Math.prop(b4.position.y+rad,0,h,-2,2)
vertecies[5]=Math.prop(b0.position.x-rad,0,w,-2,2)
vertecies[6]=Math.prop(b0.position.y-rad,0,h,2,-2)
vertecies[10]=Math.prop(b2.position.x+rad,0,w,-2,2)
vertecies[11]=Math.prop(b2.position.y-rad,0,h,2,-2)
vertecies[15]=Math.prop(b3.position.x+rad,0,w,-2,2)
vertecies[16]=Math.prop(b3.position.y+rad,0,h,2,-2)
//render Stage3D
c3d.clear(0,0,0)
if(vertexBuffer) vertexBuffer.dispose()
vertexBuffer=c3d.createVertexBuffer(4, 5)
vertexBuffer.uploadFromVector(vertecies, 0, 4)
c3d.setVertexBufferAt(0,vertexBuffer,0,'float3')
c3d.drawTriangles(indexbuffer)
c3d.present()
//render physX
if(handjoint.active) handjoint.anchor1.setxy(stage.mouseX,stage.mouseY)
space.step(1/stage.frameRate)
if(DEBUG){
bitmapDebugger.clear()
bitmapDebugger.draw(space)
bitmapDebugger.flush()
}
}
}
}