[prev in list] [next in list] [prev in thread] [next in thread]
List: osflash-sandy
Subject: [Sandy] [sandy commit] r921 - in trunk/sandy/as3/trunk/src/sandy:
From: codesite-noreply () google ! com
Date: 2009-02-23 21:54:24
Message-ID: 0016369202cbb2b35d04639d0b3c () google ! com
[Download RAW message or body]
Author: kiroukou
Date: Mon Feb 23 13:53:09 2009
New Revision: 921
Added:
trunk/sandy/as3/trunk/src/sandy/view/BasicView.as (contents, props
changed)
Modified:
trunk/sandy/as3/trunk/src/sandy/core/Renderer.as
trunk/sandy/as3/trunk/src/sandy/core/data/Polygon.as
trunk/sandy/as3/trunk/src/sandy/materials/BitmapMaterial.as
trunk/sandy/as3/trunk/src/sandy/materials/Material.as
Log:
Bug fix with Cache system and moviematerial.
Addition of a new util class, BasicView which simplify the Sandy scene
setup.
Modified: trunk/sandy/as3/trunk/src/sandy/core/Renderer.as
==============================================================================
--- trunk/sandy/as3/trunk/src/sandy/core/Renderer.as (original)
+++ trunk/sandy/as3/trunk/src/sandy/core/Renderer.as Mon Feb 23 13:53:09
2009
@@ -1 +1 @@
-
package sandy.core
{
import flash.display.Sprite;
import sandy.core.data.Matrix4;
import sandy.core.data.Point3D;
import sandy.core.data.Polygon;
import sandy.core.data.Pool;
import sandy.core.data.Vertex;
import sandy.core.scenegraph.Camera3D;
import sandy.core.scenegraph.IDisplayable;
import sandy.core.scenegraph.Renderable;
import sandy.core.scenegraph.Shape3D;
import sandy.core.scenegraph.Sprite2D;
import sandy.view.CullingState;
import sandy.view.Frustum;
/**
* @author thomas
*/
public class Renderer
{
protected const m_aDisplayList:Array = new Array();
protected var m_nDisplayListCount:int;
protected var m_aCamera:Camera3D;
protected const m_aRenderingList:Array = new Array();
protected var m_nRenderingListCount:int;
private var pool:Pool = new Pool();
private var m_bGlobalRedraw:Boolean;
/**
* Default renderer.
*/
public function Renderer()
{
m_nRenderingListCount = 0;
m_nDisplayListCount = 0;
}
/**
* Init the renderer internal data
*/
public function init():void
{
m_nDisplayListCount = 0;
m_bGlobalRedraw = false;
}
/**
* Process the rendering of the scene.
* The camera has all the information needed about the objects to render.
*
* The camera stores all the visible shape/polygons into an array, and
loop through it calling their display method.
* Before the display call, the container graphics is cleared.
*
* @param p_oScene The Scene3D object to render
*/
public function renderDisplayList( p_oScene:Scene3D ):void
{
const l_mcContainer:Sprite = p_oScene.container;
// --
m_aRenderingList.sortOn( "depth", Array.NUMERIC | Array.DESCENDING );
// -- This is the new list to be displayed.
var l_oFace:IDisplayable;
for( var i:int = 0; i < m_nRenderingListCount; i++ )
{
l_oFace = m_aRenderingList[int(i)];
if( l_oFace.changed || ((l_oFace.material !=
null)?l_oFace.material.modified:false) || p_oScene.camera.changed )
{
l_oFace.display();
}
// --
if( i < l_mcContainer.numChildren )
{
if( l_mcContainer.getChildAt(i) != l_oFace.container )
{
l_mcContainer.addChildAt( l_oFace.container, i );
}
}
else
{
l_mcContainer.addChildAt( l_oFace.container, i );
}
}
}
public function addToDisplayList( p_oObject:IDisplayable ):void
{
m_aDisplayList[m_nDisplayListCount++] = p_oObject;
m_bGlobalRedraw = m_bGlobalRedraw || p_oObject.changed ||
((p_oObject.material != null)?p_oObject.material.modified:false);
}
/**
* Render the given scene.
* Objects are transformed, clipped and projected into that function.
*
* @param p_bUseCache Boolean value, default to true, use a cache system
to avoid unnecessary computation
*/
public function render( p_oScene:Scene3D, p_bUseCache:Boolean = true
):Boolean
{
var m11:Number, m21:Number, m31:Number,
m12:Number, m22:Number, m32:Number,
m13:Number, m23:Number, m33:Number,
m14:Number, m24:Number, m34:Number,
x:Number, y:Number, z:Number;
var l_oCamera:Camera3D = p_oScene.camera;
var l_nZNear:Number = l_oCamera.near, l_oCamPos:Point3D =
pool.nextPoint3D, l_nPolyFlags:uint = 0,
l_oMatrix:Matrix4, l_oFrustum:Frustum = l_oCamera.frustrum,
l_oVertex:Vertex, l_aVertices:Array, l_oFace:Polygon, l_nMinZ:Number,
l_nFlags:int;
var l_nVisiblePolyCount:int = 0, i:int;
var l_bForceRedraw:Boolean = p_oScene.camera.changed || !p_bUseCache;
// -- return false because we do not even need to refresh display
if( m_bGlobalRedraw == false && l_bForceRedraw == false )
return false;
// -- Note, this is the displayed list from the previous iteration!
for each( var l_oObj:IDisplayable in m_aRenderingList )
{
if( l_oObj )
{
if( l_bForceRedraw == true || ((l_oObj.material !=
null)?l_oObj.material.modified:false) || l_oObj.changed == true )
{
l_oObj.clear();
}
}
}
// --
m_nRenderingListCount = 0;
m_aRenderingList.length = 0;
// --
for( i = 0; i < m_nDisplayListCount; i ++ )
{
if( m_aDisplayList[int(i)] is Shape3D )
{
var l_oShape:Shape3D = m_aDisplayList[int(i)] as Shape3D;
// if no change for that object, directly go to the draw level
if( l_oShape.changed == false && l_bForceRedraw == false )
{
if( l_oShape.useSingleContainer )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oShape;
else
{
for each( l_oFace in l_oShape.aVisiblePolygons )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oFace;
}
continue;
}
// --
l_nFlags = l_oShape.appearance.flags;
l_oShape.depth = 0;
l_oShape.aVisiblePolygons.length = 0;
l_oCamPos.reset(l_oCamera.modelMatrix.n14, l_oCamera.modelMatrix.n24,
l_oCamera.modelMatrix.n34);
l_oShape.invModelMatrix.transform( l_oCamPos );
// --
l_oMatrix = l_oShape.viewMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 = l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 = l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 = l_oMatrix.n33;
m14 = l_oMatrix.n14; m24 = l_oMatrix.n24; m34 = l_oMatrix.n34;
// --
var l_bClipped:Boolean = ((l_oShape.culled == CullingState.INTERSECT)
&& ( l_oShape.enableClipping || l_oShape.enableNearClipping ));
// --
for each( l_oVertex in l_oShape.geometry.aVertex )
{
l_oVertex.projected = l_oVertex.transformed = false;
}
// --
for each( l_oFace in l_oShape.aPolygons )
{
if( l_oShape.animated )
l_oFace.updateNormal();
// -- visibility test
l_oVertex = l_oFace.normal;
x = l_oFace.a.x; y = l_oFace.a.y; z = l_oFace.a.z;
l_oFace.visible = (l_oVertex.x*( l_oCamPos.x - x) +
l_oVertex.y*( l_oCamPos.y - y) + l_oVertex.z*( l_oCamPos.z - z)) > 0;
// --
if( l_oShape.enableBackFaceCulling )
{
if( l_oFace.visible == false )
continue;
}
// --
l_oVertex = l_oFace.a;
if( l_oVertex.transformed == false )// (l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x) * m11 + (y) * m12 + (z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
l_oVertex = l_oFace.b;
if( l_oVertex.transformed == false )// (l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
l_oVertex = l_oFace.c;
if( l_oVertex )
{
if( l_oVertex.transformed == false )//(l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
}
l_oVertex = l_oFace.d;
if( l_oVertex )
{
if( l_oVertex.transformed == false )
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
l_oVertex.transformed = true;
}
}
// --
l_oFace.precompute();
l_nMinZ = l_oFace.minZ;
// -- culling/clipping phasis
if( l_bClipped )
{
if( l_oShape.enableClipping ) // NEED COMPLETE CLIPPING
{
l_oFace.clip( l_oFrustum );
}
else if( l_oShape.enableNearClipping && l_nMinZ < l_nZNear ) //
PARTIALLY VISIBLE
{
l_oFace.clipFrontPlane( l_oFrustum );
}
else if( l_nMinZ < l_nZNear )
{
continue;
}
}
else if( l_nMinZ < l_nZNear )
{
continue;
}
// --
l_aVertices = l_oFace.isClipped ? l_oFace.cvertices :
l_oFace.vertices;
if( l_aVertices.length > 1 )
{
l_oCamera.projectArray( l_aVertices );
if(l_oShape.enableForcedDepth)
l_oFace.depth = l_oShape.forcedDepth;
else
l_oShape.depth += l_oFace.depth;
// --
l_nVisiblePolyCount++;
l_oShape.aVisiblePolygons[int(l_oShape.aVisiblePolygons.length)] =
l_oFace;
// --
l_nPolyFlags |= l_nFlags;
// --
if( l_oShape.useSingleContainer == false )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oFace;
}
}
// --
if( l_oShape.aVisiblePolygons.length > 0 )
{
if( l_oShape.useSingleContainer == true )
{
if(l_oShape.enableForcedDepth)
l_oShape.depth = l_oShape.forcedDepth;
else
l_oShape.depth /= l_oShape.aVisiblePolygons.length;
// --
m_aRenderingList[int(m_nRenderingListCount++)] = l_oShape;
}
// --
if( l_nFlags != 0 || l_nPolyFlags != 0 )
{
if( (l_nFlags | l_nPolyFlags) & SandyFlags.POLYGON_NORMAL_WORLD )
{
l_oMatrix = l_oShape.modelMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 =
l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 =
l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 =
l_oMatrix.n33;
// -- Now we transform the normals.
for each( l_oFace in l_oShape.aVisiblePolygons )
{
l_oVertex = l_oFace.normal;
l_oVertex.wx = (x=l_oVertex.x) * m11 +
(y=l_oVertex.y) * m12 + (z=l_oVertex.z) * m13;
l_oVertex.wy = x * m21 + y * m22 + z * m23;
l_oVertex.wz = x * m31 + y * m32 + z * m33;
}
}
if( (l_nFlags | l_nPolyFlags) &
SandyFlags.VERTEX_NORMAL_WORLD )
{
l_oMatrix = l_oShape.modelMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 =
l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 =
l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 =
l_oMatrix.n33;
// -- Now we transform the normals.
for each( l_oVertex in l_oShape.geometry.aVertexNormals
)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 +
(y=l_oVertex.y) * m12 + (z=l_oVertex.z) * m13;
l_oVertex.wy = x * m21 + y * m22 + z * m23;
l_oVertex.wz = x * m31 + y * m32 + z * m33;
}
}
}
}
}
else if( m_aDisplayList[int(i)] is Sprite2D )
{
var l_oSprite2D:Sprite2D = m_aDisplayList[int(i)] as Sprite2D;
l_oSprite2D.v.projected = false;
l_oSprite2D.vx.projected = false;
l_oSprite2D.vy.projected = false;
l_oVertex = l_oSprite2D.v;
l_oMatrix = l_oSprite2D.viewMatrix;
l_oVertex.wx = l_oVertex.x * l_oMatrix.n11 + l_oVertex.y *
l_oMatrix.n12 + l_oVertex.z * l_oMatrix.n13 + l_oMatrix.n14;
l_oVertex.wy = l_oVertex.x * l_oMatrix.n21 + l_oVertex.y *
l_oMatrix.n22 + l_oVertex.z * l_oMatrix.n23 + l_oMatrix.n24;
l_oVertex.wz = l_oVertex.x * l_oMatrix.n31 + l_oVertex.y *
l_oMatrix.n32 + l_oVertex.z * l_oMatrix.n33 + l_oMatrix.n34;
l_oSprite2D.depth = l_oSprite2D.enableForcedDepth ?
l_oSprite2D.forcedDepth : l_oVertex.wz;
l_oCamera.projectVertex( l_oVertex );
m_aRenderingList[int(m_nRenderingListCount++)] = l_oSprite2D;
l_oSprite2D.vx.copy (l_oVertex); l_oSprite2D.vx.wx++;
l_oCamera.projectVertex (l_oSprite2D.vx);
l_oSprite2D.vy.copy (l_oVertex); l_oSprite2D.vy.wy++;
l_oCamera.projectVertex (l_oSprite2D.vy);
}
else if( m_aDisplayList[int(i)] is Renderable )
{
(m_aDisplayList[int(i)] as Renderable).render(l_oCamera);
m_aRenderingList[int(m_nRenderingListCount++)] =
m_aDisplayList[int(i)] as Renderable;
}
}
// true because need need to refresh display
return true;
}
}
}
\ No newline at end of file
+
package sandy.core
{
import flash.display.Sprite;
import sandy.core.data.Matrix4;
import sandy.core.data.Point3D;
import sandy.core.data.Polygon;
import sandy.core.data.Pool;
import sandy.core.data.Vertex;
import sandy.core.scenegraph.Camera3D;
import sandy.core.scenegraph.IDisplayable;
import sandy.core.scenegraph.Renderable;
import sandy.core.scenegraph.Shape3D;
import sandy.core.scenegraph.Sprite2D;
import sandy.view.CullingState;
import sandy.view.Frustum;
/**
* @author thomas
*/
public class Renderer
{
protected const m_aDisplayList:Array = new Array();
protected var m_nDisplayListCount:int;
protected var m_aCamera:Camera3D;
protected const m_aRenderingList:Array = new Array();
protected var m_nRenderingListCount:int;
private var pool:Pool = new Pool();
private var m_bGlobalRedraw:Boolean;
/**
* Default renderer.
*/
public function Renderer()
{
m_nRenderingListCount = 0;
m_nDisplayListCount = 0;
}
/**
* Init the renderer internal data
*/
public function init():void
{
m_nDisplayListCount = 0;
m_bGlobalRedraw = false;
}
/**
* Process the rendering of the scene.
* The camera has all the information needed about the objects to render.
*
* The camera stores all the visible shape/polygons into an array, and
loop through it calling their display method.
* Before the display call, the container graphics is cleared.
*
* @param p_oScene The Scene3D object to render
*/
public function renderDisplayList( p_oScene:Scene3D ):void
{
const l_mcContainer:Sprite = p_oScene.container;
// --
m_aRenderingList.sortOn( "depth", Array.NUMERIC | Array.DESCENDING );
// -- This is the new list to be displayed.
var l_oFace:IDisplayable;
for( var i:int = 0; i < m_nRenderingListCount; i++ )
{
l_oFace = m_aRenderingList[int(i)];
if( l_oFace.changed || ((l_oFace.material !=
null)?l_oFace.material.modified:false) || p_oScene.camera.changed )
{
l_oFace.display();
}
// --
if( i < l_mcContainer.numChildren )
{
if( l_mcContainer.getChildAt(i) != l_oFace.container )
{
l_mcContainer.addChildAt( l_oFace.container, i );
}
}
else
{
l_mcContainer.addChildAt( l_oFace.container, i );
}
}
}
public function addToDisplayList( p_oObject:IDisplayable ):void
{
m_aDisplayList[m_nDisplayListCount++] = p_oObject;
m_bGlobalRedraw = m_bGlobalRedraw || p_oObject.changed ||
((p_oObject.material != null)?p_oObject.material.modified:false);
}
/**
* Render the given scene.
* Objects are transformed, clipped and projected into that function.
*
* @param p_bUseCache Boolean value, default to true, use a cache system
to avoid unnecessary computation
*/
public function render( p_oScene:Scene3D, p_bUseCache:Boolean = true
):Boolean
{
var m11:Number, m21:Number, m31:Number,
m12:Number, m22:Number, m32:Number,
m13:Number, m23:Number, m33:Number,
m14:Number, m24:Number, m34:Number,
x:Number, y:Number, z:Number;
var l_oCamera:Camera3D = p_oScene.camera;
var l_nZNear:Number = l_oCamera.near, l_oCamPos:Point3D =
pool.nextPoint3D, l_nPolyFlags:uint = 0,
l_oMatrix:Matrix4, l_oFrustum:Frustum = l_oCamera.frustrum,
l_oVertex:Vertex, l_aVertices:Array, l_oFace:Polygon, l_nMinZ:Number,
l_nFlags:int;
var l_nVisiblePolyCount:int = 0, i:int;
var l_bForceRedraw:Boolean = p_oScene.camera.changed || !p_bUseCache;
// -- return false because we do not even need to refresh display
if( m_bGlobalRedraw == false && l_bForceRedraw == false )
return false;
// -- Note, this is the displayed list from the previous iteration!
for each( var l_oObj:IDisplayable in m_aRenderingList )
{
if( l_oObj )
{
if( l_bForceRedraw == true || ((l_oObj.material !=
null)?l_oObj.material.modified:false) || l_oObj.changed == true )
{
l_oObj.clear();
}
}
}
// --
m_nRenderingListCount = 0;
m_aRenderingList.length = 0;
// --
for( i = 0; i < m_nDisplayListCount; i ++ )
{
if( m_aDisplayList[int(i)] is Shape3D )
{
var l_oShape:Shape3D = m_aDisplayList[int(i)] as Shape3D;
// if no change for that object, directly go to the draw level
if( l_oShape.changed == false && l_bForceRedraw == false )
{
if( l_oShape.useSingleContainer )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oShape;
else
{
for each( l_oFace in l_oShape.aVisiblePolygons )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oFace;
}
continue;
}
// --
l_nFlags = l_oShape.appearance.flags;
l_oShape.depth = 0;
l_oShape.aVisiblePolygons.length = 0;
l_oCamPos.reset(l_oCamera.modelMatrix.n14, l_oCamera.modelMatrix.n24,
l_oCamera.modelMatrix.n34);
l_oShape.invModelMatrix.transform( l_oCamPos );
// --
l_oMatrix = l_oShape.viewMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 = l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 = l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 = l_oMatrix.n33;
m14 = l_oMatrix.n14; m24 = l_oMatrix.n24; m34 = l_oMatrix.n34;
// --
var l_bClipped:Boolean = ((l_oShape.culled == CullingState.INTERSECT)
&& ( l_oShape.enableClipping || l_oShape.enableNearClipping ));
// --
for each( l_oVertex in l_oShape.geometry.aVertex )
{
l_oVertex.projected = l_oVertex.transformed = false;
}
// --
for each( l_oFace in l_oShape.aPolygons )
{
if( l_oShape.animated )
l_oFace.updateNormal();
// -- visibility test
l_oVertex = l_oFace.normal;
x = l_oFace.a.x; y = l_oFace.a.y; z = l_oFace.a.z;
l_oFace.visible = (l_oVertex.x*( l_oCamPos.x - x) +
l_oVertex.y*( l_oCamPos.y - y) + l_oVertex.z*( l_oCamPos.z - z)) > 0;
// --
if( l_oShape.enableBackFaceCulling )
{
if( l_oFace.visible == false )
continue;
}
// --
l_oVertex = l_oFace.a;
if( l_oVertex.transformed == false )// (l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x) * m11 + (y) * m12 + (z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
l_oVertex = l_oFace.b;
if( l_oVertex.transformed == false )// (l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
l_oVertex = l_oFace.c;
if( l_oVertex )
{
if( l_oVertex.transformed == false )//(l_oVertex.flags &
SandyFlags.VERTEX_CAMERA) == 0)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
//l_oVertex.flags |= SandyFlags.VERTEX_CAMERA;
l_oVertex.transformed = true;
}
}
l_oVertex = l_oFace.d;
if( l_oVertex )
{
if( l_oVertex.transformed == false )
{
l_oVertex.wx = (x=l_oVertex.x) * m11 + (y=l_oVertex.y) * m12 +
(z=l_oVertex.z) * m13 + m14;
l_oVertex.wy = x * m21 + y * m22 + z * m23 + m24;
l_oVertex.wz = x * m31 + y * m32 + z * m33 + m34;
l_oVertex.transformed = true;
}
}
// --
l_oFace.precompute();
l_nMinZ = l_oFace.minZ;
// -- culling/clipping phasis
if( l_bClipped )
{
if( l_oShape.enableClipping ) // NEED COMPLETE CLIPPING
{
l_oFace.clip( l_oFrustum );
}
else if( l_oShape.enableNearClipping && l_nMinZ < l_nZNear ) //
PARTIALLY VISIBLE
{
l_oFace.clipFrontPlane( l_oFrustum );
}
else if( l_nMinZ < l_nZNear )
{
continue;
}
}
else if( l_nMinZ < l_nZNear )
{
continue;
}
// --
l_aVertices = l_oFace.isClipped ? l_oFace.cvertices :
l_oFace.vertices;
if( l_aVertices.length > 1 )
{
l_oCamera.projectArray( l_aVertices );
if(l_oShape.enableForcedDepth)
l_oFace.depth = l_oShape.forcedDepth;
else
l_oShape.depth += l_oFace.depth;
// --
l_nVisiblePolyCount++;
l_oShape.aVisiblePolygons[int(l_oShape.aVisiblePolygons.length)] =
l_oFace;
// --
l_nPolyFlags |= l_nFlags;
// --
if( l_oShape.useSingleContainer == false )
m_aRenderingList[int(m_nRenderingListCount++)] = l_oFace;
}
}
// --
if( l_oShape.aVisiblePolygons.length > 0 )
{
if( l_oShape.useSingleContainer == true )
{
if(l_oShape.enableForcedDepth)
l_oShape.depth = l_oShape.forcedDepth;
else
l_oShape.depth /= l_oShape.aVisiblePolygons.length;
// --
m_aRenderingList[int(m_nRenderingListCount++)] = l_oShape;
}
// --
if( l_nFlags != 0 || l_nPolyFlags != 0 )
{
if( (l_nFlags | l_nPolyFlags) & SandyFlags.POLYGON_NORMAL_WORLD )
{
l_oMatrix = l_oShape.modelMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 =
l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 =
l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 =
l_oMatrix.n33;
// -- Now we transform the normals.
for each( l_oFace in l_oShape.aVisiblePolygons )
{
l_oVertex = l_oFace.normal;
l_oVertex.wx = (x=l_oVertex.x) * m11 +
(y=l_oVertex.y) * m12 + (z=l_oVertex.z) * m13;
l_oVertex.wy = x * m21 + y * m22 + z * m23;
l_oVertex.wz = x * m31 + y * m32 + z * m33;
}
}
if( (l_nFlags | l_nPolyFlags) &
SandyFlags.VERTEX_NORMAL_WORLD )
{
l_oMatrix = l_oShape.modelMatrix;
m11 = l_oMatrix.n11; m21 = l_oMatrix.n21; m31 =
l_oMatrix.n31;
m12 = l_oMatrix.n12; m22 = l_oMatrix.n22; m32 =
l_oMatrix.n32;
m13 = l_oMatrix.n13; m23 = l_oMatrix.n23; m33 =
l_oMatrix.n33;
// -- Now we transform the normals.
for each( l_oVertex in l_oShape.geometry.aVertexNormals
)
{
l_oVertex.wx = (x=l_oVertex.x) * m11 +
(y=l_oVertex.y) * m12 + (z=l_oVertex.z) * m13;
l_oVertex.wy = x * m21 + y * m22 + z * m23;
l_oVertex.wz = x * m31 + y * m32 + z * m33;
}
}
}
}
}
else if( m_aDisplayList[int(i)] is Sprite2D )
{
var l_oSprite2D:Sprite2D = m_aDisplayList[int(i)] as Sprite2D;
l_oSprite2D.v.projected = false;
l_oSprite2D.vx.projected = false;
l_oSprite2D.vy.projected = false;
l_oVertex = l_oSprite2D.v;
l_oMatrix = l_oSprite2D.viewMatrix;
l_oVertex.wx = l_oVertex.x * l_oMatrix.n11 + l_oVertex.y *
l_oMatrix.n12 + l_oVertex.z * l_oMatrix.n13 + l_oMatrix.n14;
l_oVertex.wy = l_oVertex.x * l_oMatrix.n21 + l_oVertex.y *
l_oMatrix.n22 + l_oVertex.z * l_oMatrix.n23 + l_oMatrix.n24;
l_oVertex.wz = l_oVertex.x * l_oMatrix.n31 + l_oVertex.y *
l_oMatrix.n32 + l_oVertex.z * l_oMatrix.n33 + l_oMatrix.n34;
l_oSprite2D.depth = l_oSprite2D.enableForcedDepth ?
l_oSprite2D.forcedDepth : l_oVertex.wz;
l_oCamera.projectVertex( l_oVertex );
m_aRenderingList[int(m_nRenderingListCount++)] = l_oSprite2D;
l_oSprite2D.vx.copy (l_oVertex); l_oSprite2D.vx.wx++;
l_oCamera.projectVertex (l_oSprite2D.vx);
l_oSprite2D.vy.copy (l_oVertex); l_oSprite2D.vy.wy++;
l_oCamera.projectVertex (l_oSprite2D.vy);
}
else if( m_aDisplayList[int(i)] is Renderable )
{
(m_aDisplayList[int(i)] as Renderable).render(l_oCamera);
m_aRenderingList[int(m_nRenderingListCount++)] =
m_aDisplayList[int(i)] as Renderable;
}
}
// true because need need to refresh display
return true;
}
}
}
\ No newline at end of file
Modified: trunk/sandy/as3/trunk/src/sandy/core/data/Polygon.as
==============================================================================
--- trunk/sandy/as3/trunk/src/sandy/core/data/Polygon.as (original)
+++ trunk/sandy/as3/trunk/src/sandy/core/data/Polygon.as Mon Feb 23
13:53:09 2009
@@ -1 +1 @@
-
package sandy.core.data
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import sandy.core.Scene3D;
import sandy.core.interaction.VirtualMouse;
import sandy.core.scenegraph.Geometry3D;
import sandy.core.scenegraph.IDisplayable;
import sandy.core.scenegraph.Shape3D;
import sandy.events.BubbleEventBroadcaster;
import sandy.events.SandyEvent;
import sandy.events.Shape3DEvent;
import sandy.materials.Appearance;
import sandy.materials.Material;
import sandy.math.IntersectionMath;
import sandy.math.Point3DMath;
import sandy.view.CullingState;
import sandy.view.Frustum;
/**
* Polygon's are the building blocks of visible 3D shapes.
*
* @author Thomas Pfeiffer - kiroukou
* @author Mirek Mencel
* @since 1.0
* @version 3.1
* @date 24.08.2007
*
* @see sandy.core.scenegraph.Shape3D
*/
public final class Polygon implements IDisplayable
{
// _______
// STATICS_______________________________________________________
private static var _ID_:uint = 0;
/**
* This property lists all the polygons.
* This is a helper property since it allows all polygons of a scene to
be retrieved from a single list by its unique identifier.
* A polygon's unique identifier can be retrieved useing
<code>myPolygon.id</code>.
*
* @example The examples below shows how to retrieve a ploygon from this
property.
* <listing version="3.1">
* var p:Polygon = Polygon.POLYGON_MAP[myPolygon.id];
* </listing>
*/
public static var POLYGON_MAP:Dictionary = new Dictionary(true);
// ______
// PUBLIC________________________________________________________
/**
* The unique identifier for this polygon.
*/
public const id:uint = _ID_++;
/**
* A reference to the Shape3D object this polygon belongs to.
*/
public var shape:Shape3D;
/**
* Specifies if the polygon has been clipped.
*/
public var isClipped:Boolean = false;
/**
* An array of clipped vertices. Check the <code>isClipped</code>
property first to see if this array will contain the useful data.
*/
public var cvertices:Array;
/**
* An array of the polygon's original vertices.
*/
public var vertices:Array;
/**
* An array of the polygon's vertex normals.
*/
public var vertexNormals:Array;
public var aUVCoord:Array;
/**
* An array of the polygon's edges.
*/
public var aEdges:Array;
public var caUVCoord:Array;
/**
* The texture bounds.
*/
public var uvBounds:Rectangle;
/**
* An array of polygons that share an edge with this polygon.
*/
public var aNeighboors:Array = new Array();
/**
* Specifies whether the face of the polygon is visible.
*/
public var visible:Boolean;
/**
* Minimum depth value of that polygon in the camera space
*/
public var minZ:Number;
public var a:Vertex, b:Vertex, c:Vertex, d:Vertex;
/**
* Creates a new polygon.
*
* @param p_oShape The shape the polygon belongs to.
* @param p_geometry The geometry the polygon belongs to.
* @param p_aVertexID An array of verticies of the polygon.
* @param p_aUVCoordsID An array of UV coordinates of this polygon.
* @param p_nFaceNormalID The faceNormalID of this polygon.
* @param p_nEdgesID The edgesID of this polygon.
*/
public function Polygon( p_oOwner:Shape3D, p_geometry:Geometry3D,
p_aVertexID:Array, p_aUVCoordsID:Array=null, p_nFaceNormalID:Number=0,
p_nEdgesID:uint=0 )
{
shape = p_oOwner;
m_oGeometry = p_geometry;
// --
__update( p_aVertexID, p_aUVCoordsID, p_nFaceNormalID, p_nEdgesID );
m_oContainer = new Sprite();
// --
POLYGON_MAP[id] = this;
m_oEB = new BubbleEventBroadcaster(this);
}
public function get changed():Boolean
{
return shape.changed;
}
/**
* A reference to the Scene3D object this polygon is in.
*/
public function set scene(p_oScene:Scene3D):void
{
if( p_oScene == null ) return;
if( scene != null )
{
scene.removeEventListener(SandyEvent.SCENE_RENDER_FINISH,
_finishMaterial );
scene.removeEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
}
// --
m_oScene = p_oScene;
// --
scene.addEventListener(SandyEvent.SCENE_RENDER_FINISH, _finishMaterial );
scene.addEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
}
public function get scene():Scene3D
{
return m_oScene;
}
private var m_oScene:Scene3D = null;
/**
* Updates the vertices and normals for this polygon.
*
* <p>Calling this method make the polygon gets its vertice and normals
by reference
* instead of accessing them by their ID.<br/>
* This method shall be called once the geometry created.</p>
*
* @param p_aVertexID The vertexID array of this polygon
* @param p_aUVCoordsID The UVCoordsID array of this polygon
* @param p_nFaceNormalID The faceNormalID of this polygon
* @param p_nEdgesID The edgesID of this polygon
*/
private function __update( p_aVertexID:Array, p_aUVCoordsID:Array,
p_nFaceNormalID:uint, p_nEdgeListID:uint ):void
{
var i:int=0;
// --
vertexNormals = new Array();
vertices = new Array();
for each( var o:* in p_aVertexID )
{
vertices[i] = Vertex( m_oGeometry.aVertex[ p_aVertexID[i] ] );
vertexNormals[i] = m_oGeometry.aVertexNormals[ p_aVertexID[i] ];
i++;
}
// --
a = vertices[0];
b = vertices[1];
c = vertices[2];
d = vertices[3];
// -- every polygon does not have some texture coordinates
if( p_aUVCoordsID )
{
var l_nMinU:Number = Number.POSITIVE_INFINITY, l_nMinV:Number =
Number.POSITIVE_INFINITY,
l_nMaxU:Number = Number.NEGATIVE_INFINITY, l_nMaxV:Number =
Number.NEGATIVE_INFINITY;
// --
aUVCoord = new Array();
i = 0;
if( p_aUVCoordsID )
{
for each( var p:* in p_aUVCoordsID )
{
var l_oUV:UVCoord = ( m_oGeometry.aUVCoords[ p_aUVCoordsID[i] ] as
UVCoord);
if( l_oUV == null ) l_oUV = new UVCoord(0,0);
// --
aUVCoord[i] = l_oUV;
if( l_oUV.u < l_nMinU ) l_nMinU = l_oUV.u;
else if( l_oUV.u > l_nMaxU ) l_nMaxU = l_oUV.u;
// --
if( l_oUV.v < l_nMinV ) l_nMinV = l_oUV.v;
else if( l_oUV.v > l_nMaxV ) l_nMaxV = l_oUV.v;
// --
i++;
}
// --
uvBounds = new Rectangle( l_nMinU, l_nMinV, l_nMaxU-l_nMinU,
l_nMaxV-l_nMinV );
}
else
{
aUVCoord = [new UVCoord(), new UVCoord(), new UVCoord()];
uvBounds = new Rectangle(0,0,0,0);
}
}
// --
m_nNormalId = p_nFaceNormalID;
normal = Vertex( m_oGeometry.aFacesNormals[ p_nFaceNormalID ] );
// If no normal has been given, we create it ourself.
if( normal == null )
{
var l_oNormal:Point3D = createNormal();
m_nNormalId = m_oGeometry.setFaceNormal(
m_oGeometry.getNextFaceNormalID(), l_oNormal.x, l_oNormal.y, l_oNormal.z );
}
// --
aEdges = new Array();
for each( var l_nEdgeId:uint in m_oGeometry.aFaceEdges[p_nEdgeListID] )
{
var l_oEdge:Edge3D = m_oGeometry.aEdges[ l_nEdgeId ];
l_oEdge.vertex1 = m_oGeometry.aVertex[ l_oEdge.vertexId1 ];
l_oEdge.vertex2 = m_oGeometry.aVertex[ l_oEdge.vertexId2 ];
aEdges.push( l_oEdge );
}
}
public function get normal():Vertex
{
return m_oGeometry.aFacesNormals[ m_nNormalId ];
}
public function set normal( p_oVertex:Vertex ):void
{
if( p_oVertex != null )
m_oGeometry.aFacesNormals[ m_nNormalId ].copy( p_oVertex );
}
public function updateNormal():void
{
var x:Number = ((a.y - b.y) * (c.z - b.z)) - ((a.z - b.z) * (c.y -
b.y)) ;
var y:Number = ((a.z - b.z) * (c.x - b.x)) - ((a.x - b.x) * (c.z -
b.z)) ;
var z:Number = ((a.x - b.x) * (c.y - b.y)) - ((a.y - b.y) * (c.x -
b.x)) ;
normal.reset( x, y, z );
}
/**
* The depth of the polygon.
*/
public function get depth():Number
{
return m_nDepth;
}
/**
* @private
*/
public function set depth( p_nDepth:Number ):void
{
m_nDepth = p_nDepth;
}
/**
* The broadcaster of the polygon that sends events to listeners.
*/
public function get broadcaster():BubbleEventBroadcaster
{
return m_oEB;
}
/**
* Adds an event listener to the polygon.
*
* @param p_sEvent The name of the event to add.
* @param oL The listener object.
*/
public function addEventListener(p_sEvent:String, oL:*) : void
{
m_oEB.addEventListener.apply(m_oEB, arguments);
}
/**
* Removes an event listener to the polygon.
*
* @param p_sEvent The name of the event to remove.
* @param oL The listener object.
*/
public function removeEventListener(p_sEvent:String, oL:*) : void
{
m_oEB.removeEventListener(p_sEvent, oL);
}
/**
* Computes several properties of the polygon.
* <p>The computed properties are listed below:</p>
* <ul>
* <li><code>visible</code></li>
* <li><code>minZ</code></li>
* <li><code>depth</code></li>
* </ul>
*/
public function precompute():void
{
isClipped = false;
// --
minZ = a.wz;
if (b.wz < minZ) minZ = b.wz;
m_nDepth = a.wz + b.wz;
// --
if (c != null)
{
if (c.wz < minZ) minZ = c.wz;
m_nDepth += c.wz;
}
if (d != null)
{
if (d.wz < minZ) minZ = d.wz;
m_nDepth += d.wz;
}
m_nDepth /= vertices.length;
}
/**
* Returns a Point3D (3D position) on the polygon relative to the
specified point on the 2D screen.
*
* @example Below is an example of how to get the 3D coordinate of the
polygon under the position of the mouse:
* <listing version="3.1">
* var screenPoint:Point = new Point(myPolygon.container.mouseX,
myPolygon.container.mouseY);
* var scenePosition:Point3D = myPolygon.get3DFrom2D(screenPoint);
* </listing>
*
* @return A Point3D that corresponds to the specified point.
*/
public function get3DFrom2D( p_oScreenPoint:Point ):Point3D
{
/// NEW CODE ADDED BY MAX with the help of makc ///
var m1:Matrix= new Matrix(
vertices[1].sx-vertices[0].sx,
vertices[2].sx-vertices[0].sx,
vertices[1].sy-vertices[0].sy,
vertices[2].sy-vertices[0].sy,
0,
0);
m1.invert();
var capA:Number = m1.a *(p_oScreenPoint.x-vertices[0].sx) + m1.b *
(p_oScreenPoint.y -vertices[0].sy);
var capB:Number = m1.c *(p_oScreenPoint.x-vertices[0].sx) + m1.d *
(p_oScreenPoint.y -vertices[0].sy);
var l_oPoint:Point3D = new Point3D(
vertices[0].x + capA*(vertices[1].x -vertices[0].x) + capB
*(vertices[2].x - vertices[0].x),
vertices[0].y + capA*(vertices[1].y -vertices[0].y) + capB
*(vertices[2].y - vertices[0].y),
vertices[0].z + capA*(vertices[1].z -vertices[0].z) + capB
*(vertices[2].z - vertices[0].z)
);
// transform the vertex with the model Matrix
this.shape.matrix.transform( l_oPoint );
return l_oPoint;
}
/**
* Returns a UV coordinate elative to the specified point on the 2D
screen.
*
* @example Below is an example of how to get the UV coordinate under the
position of the mouse:
* <listing version="3.1">
* var screenPoint:Point = new Point(myPolygon.container.mouseX,
myPolygon.container.mouseY);
* var scenePosition:Point3D = myPolygon.getUVFrom2D(screenPoint);
* </listing>
*
* @return A the UV coordinate that corresponds to the specified
point.
*/
public function getUVFrom2D( p_oScreenPoint:Point ):UVCoord
{
var p0:Point = new Point(vertices[0].sx, vertices[0].sy);
var p1:Point = new Point(vertices[1].sx, vertices[1].sy);
var p2:Point = new Point(vertices[2].sx, vertices[2].sy);
var u0:UVCoord = aUVCoord[0];
var u1:UVCoord = aUVCoord[1];
var u2:UVCoord = aUVCoord[2];
var v01:Point = new Point(p1.x - p0.x, p1.y - p0.y );
var vn01:Point = v01.clone();
vn01.normalize(1);
var v02:Point = new Point(p2.x - p0.x, p2.y - p0.y );
var vn02:Point = v02.clone(); vn02.normalize(1);
// sub that from click point
var v4:Point = new Point( p_oScreenPoint.x - v01.x,
p_oScreenPoint.y - v01.y );
// we now have everything to find 1 intersection
var l_oInter:Point = IntersectionMath.intersectionLine2D( p0,
p2, p_oScreenPoint, v4 );
// find Point3Ds to intersection
var vi02:Point = new Point( l_oInter.x - p0.x, l_oInter.y -
p0.y );
var vi01:Point = new Point( p_oScreenPoint.x - l_oInter.x ,
p_oScreenPoint.y - l_oInter.y );
// interpolation coeffs
var d1:Number = vi01.length / v01.length ;
var d2:Number = vi02.length / v02.length;
// -- on interpole linéairement pour trouver la position du
point dans repere de la texture (normalisé)
return new UVCoord( u0.u + d1*(u1.u - u0.u) + d2*(u2.u - u0.u),
u0.v + d1*(u1.v - u0.v) + d2*(u2.v - u0.v));
}
/**
* Clips the polygon.
*
* @return An array of vertices clipped by the camera frustum.
*/
public function clip( p_oFrustum:Frustum ):Array
{
cvertices = null;
caUVCoord = null;
// --
var l_oCull:CullingState = p_oFrustum.polygonInFrustum( this );
if( l_oCull == CullingState.INSIDE )
return vertices;
else if( l_oCull == CullingState.OUTSIDE )
return null;
// For lines we only apply front plane clipping
if( vertices.length < 3 )
{
clipFrontPlane( p_oFrustum );
}
else
{
cvertices = vertices.slice();
caUVCoord = aUVCoord.slice();
// --
isClipped = p_oFrustum.clipFrustum( cvertices, caUVCoord );
}
return cvertices;
}
/**
* Perform a clipping against the camera frustum's front plane.
*
* @return An array of vertices clipped by the camera frustum's front
plane.
*/
public function clipFrontPlane( p_oFrustum:Frustum ):Array
{
cvertices = vertices.slice();
// If line
if( vertices.length < 3 )
{
isClipped = p_oFrustum.clipLineFrontPlane( cvertices );
}
else
{
caUVCoord = aUVCoord.slice();
isClipped = p_oFrustum.clipFrontPlane( cvertices, caUVCoord );
}
return cvertices;
}
/**
* Clears the polygon's container.
*/
public function clear():void
{
if (m_oContainer != null) m_oContainer.graphics.clear();
}
/**
* Draws the polygon on its container if visible.
*
* @param p_oScene The scene this polygon is rendered in.
* @param p_oContainer The container to draw on.
*/
public function display( p_oContainer:Sprite = null ):void
{
const lCont:Sprite = (p_oContainer)?p_oContainer:m_oContainer;
if( visible )
{
m_oAppearance.frontMaterial.renderPolygon( scene, this, lCont );
}
else
{
m_oAppearance.backMaterial.renderPolygon( scene, this, lCont );
}
}
/**
* Returns the material currently used by the renderer
* @return Material the material used to render
*/
public function get material():Material
{
return ( visible ) ? m_oAppearance.frontMaterial :
m_oAppearance.backMaterial;
}
/**
* The polygon's container.
*/
public function get container():Sprite
{
return m_oContainer;
}
/**
* Returns a string representation of this object.
*
* @return The fully qualified name of this object.
*/
public function toString():String
{
return "sandy.core.data.Polygon::id=" +id+ " [Points: " +
vertices.length + "]";
}
/**
* Specifies whether mouse events are enabled for this polygon.
*
* <p>To apply events to a polygon, listeners must be added with the
<code>addEventListener()</code> method.</p>
*
* @see #addEventListener()
*/
public function get enableEvents():Boolean
{
return mouseEvents;
}
/**
* @private
*/
public function set enableEvents( b:Boolean ):void
{
if( b && !mouseEvents )
{
container.addEventListener(MouseEvent.CLICK, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_UP, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
container.addEventListener(MouseEvent.ROLL_OVER, _onInteraction);
container.addEventListener(MouseEvent.ROLL_OUT, _onInteraction);
container.addEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
}
else if( !b && mouseEvents )
{
container.removeEventListener(MouseEvent.CLICK, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_UP, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
container.removeEventListener(MouseEvent.ROLL_OVER, _onInteraction);
container.removeEventListener(MouseEvent.ROLL_OUT, _onInteraction);
container.removeEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
}
mouseEvents = b;
}
/**
* @private
*/
protected function _onInteraction( p_oEvt:Event ):void
{
var l_oClick:Point = new Point( m_oContainer.mouseX, m_oContainer.mouseY
);
var l_oUV:UVCoord = getUVFrom2D( l_oClick );
var l_oPt3d:Point3D = get3DFrom2D( l_oClick );
m_oEB.dispatchEvent( new Shape3DEvent( p_oEvt.type, shape, this, l_oUV,
l_oPt3d, p_oEvt ) );
}
/**
* @private
*/
protected function _startMouseInteraction( e : MouseEvent = null ) : void
{
container.addEventListener(MouseEvent.CLICK, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_UP, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_DOWN, _onTextureInteraction);
container.addEventListener(MouseEvent.DOUBLE_CLICK,
_onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_MOVE, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_OVER, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_OUT, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_WHEEL,
_onTextureInteraction);
container.addEventListener(KeyboardEvent.KEY_DOWN,
_onTextureInteraction);
container.addEventListener(KeyboardEvent.KEY_UP, _onTextureInteraction);
m_oContainer.addEventListener( Event.ENTER_FRAME, _onTextureInteraction
);
}
/**
* @private
*/
protected function _stopMouseInteraction( e : MouseEvent = null ) : void
{
container.removeEventListener(MouseEvent.CLICK, _onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_UP,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_DOWN,
_onTextureInteraction);
container.removeEventListener(MouseEvent.DOUBLE_CLICK,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_MOVE,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_OVER,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_OUT,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_WHEEL,
_onTextureInteraction);
m_oContainer.removeEventListener( Event.ENTER_FRAME,
_onTextureInteraction );
container.removeEventListener(KeyboardEvent.KEY_DOWN,
_onTextureInteraction);
container.removeEventListener(KeyboardEvent.KEY_UP,
_onTextureInteraction);
}
/**
* Specifies whether <code>MouseEvent.ROLL_*</code> events are
enabled for this polygon.
*
* <p>To apply events to a polygon, listeners must be added with the
<code>addEventListener()</code> method.</p>
*
* @see #addEventListener()
*/
public function get enableInteractivity():Boolean
{
return mouseInteractivity;
}
/**
* @private
*/
public function set enableInteractivity( p_bState:Boolean ):void
{
if( p_bState != mouseInteractivity )
{
if( p_bState )
{
container.addEventListener( MouseEvent.ROLL_OVER,
_startMouseInteraction, false );
container.addEventListener( MouseEvent.ROLL_OUT,
_stopMouseInteraction, false );
}
else
{
_stopMouseInteraction();
}
// --
mouseInteractivity = p_bState;
}
}
/**
* @private
*/
protected function _onTextureInteraction( p_oEvt:Event = null ) : void
{
if ( p_oEvt == null || !(p_oEvt is MouseEvent) ) p_oEvt = new
MouseEvent( MouseEvent.MOUSE_MOVE, true, false, 0, 0, null, false, false,
false, false, 0);
// get the position of the mouse on the poly
var pt2D : Point = new Point( scene.container.mouseX,
scene.container.mouseY );
var uv : UVCoord = getUVFrom2D( pt2D );
VirtualMouse.getInstance().interactWithTexture( this, uv, p_oEvt as
MouseEvent );
_onInteraction( p_oEvt );
}
/**
* Returns the transformed normal Point3D of the polygon.
*
* @return The transformed normal Point3D of the polygon.
*/
public function createTransformedNormal():Point3D
{
if( vertices.length > 2 )
{
var v:Point3D, w:Point3D;
var a:Vertex = vertices[0], b:Vertex = vertices[1], c:Vertex =
vertices[2];
v = new Point3D( b.wx - a.wx, b.wy - a.wy, b.wz - a.wz );
w = new Point3D( b.wx - c.wx, b.wy - c.wy, b.wz - c.wz );
// we compute de cross product
var l_normal:Point3D = Point3DMath.cross( v, w );
// we normalize the resulting Point3D
Point3DMath.normalize( l_normal ) ;
// we return the resulting vertex
return l_normal;
}
else
{
return new Point3D();
}
}
/**
* Returns the normal Point3D of the polygon.
*
* @return The normal Point3D of the polygon.
*/
public function createNormal():Point3D
{
if( vertices.length > 2 )
{
var v:Point3D, w:Point3D;
var a:Vertex = vertices[0], b:Vertex = vertices[1], c:Vertex =
vertices[2];
v = new Point3D( b.x - a.x, b.y - a.y, b.z - a.z );
w = new Point3D( b.x - c.x, b.y - c.y, b.z - c.z );
// we compute de cross product
var l_normal:Point3D = Point3DMath.cross( v, w );
// we normalize the resulting Point3D
Point3DMath.normalize( l_normal ) ;
// we return the resulting vertex
return l_normal;
}
else
{
return new Point3D();
}
}
/**
* The appearance of this polygon.
*/
public function get appearance():Appearance
{
return m_oAppearance;
}
/**
* @private
*/
public function set appearance( p_oApp:Appearance ):void
{
if( p_oApp != null )
{
m_oAppearance = p_oApp;
// --
m_oAppearance.frontMaterial.init( this );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.init( this );
}
}
}
private function _finishMaterial( pEvt:SandyEvent ):void
{
if( !m_oAppearance ) return;
if( !visible ) return;
// --
m_oAppearance.frontMaterial.finish( scene );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.finish( scene );
}
}
private function _beginMaterial( pEvt:SandyEvent ):void
{
if( !m_oAppearance ) return;
if( !visible ) return;
// --
m_oAppearance.frontMaterial.begin( scene );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.begin( scene );
}
}
/**
* Changes which side is the "normal" culling side.
*
* <p>This method also swaps the front and back skins.</p>
*/
public function swapCulling():void
{
normal.negate();
}
/**
* Removes the polygon's container from the stage.
*/
public function destroy():void
{
clear();
scene.removeEventListener(SandyEvent.SCENE_RENDER_FINISH,
_finishMaterial );
scene.removeEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
// --
enableEvents = false;
enableInteractivity = false;
if( appearance.backMaterial ) appearance.backMaterial.unlink( this );
if( appearance.frontMaterial ) appearance.frontMaterial.unlink( this );
appearance = null;
if( m_oContainer.parent ) m_oContainer.parent.removeChild( m_oContainer
);
if( m_oContainer ) m_oContainer = null;
// --
cvertices = null;
vertices = null;
m_oEB = null;
m_oGeometry = null;
shape = null;
scene = null;
// -- memory leak fix from nopmb on mediabox forums
delete POLYGON_MAP[id];
}
// _______
// PRIVATE_______________________________________________________
/** Reference to its owner geometry */
private var m_oGeometry:Geometry3D;
private var m_oAppearance:Appearance;
private var m_nNormalId:uint;
private var m_nDepth:Number;
/**
* @private
*/
protected var m_oContainer:Sprite;
/**
* @private
*/
protected var m_oEB:BubbleEventBroadcaster;
/** Boolean representing the state of the event activation */
private var mouseEvents:Boolean = false;
private var mouseInteractivity:Boolean = false;
}
}
\ No newline at end of file
+
package sandy.core.data
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import sandy.core.Scene3D;
import sandy.core.interaction.VirtualMouse;
import sandy.core.scenegraph.Geometry3D;
import sandy.core.scenegraph.IDisplayable;
import sandy.core.scenegraph.Shape3D;
import sandy.events.BubbleEventBroadcaster;
import sandy.events.SandyEvent;
import sandy.events.Shape3DEvent;
import sandy.materials.Appearance;
import sandy.materials.Material;
import sandy.math.IntersectionMath;
import sandy.math.Point3DMath;
import sandy.view.CullingState;
import sandy.view.Frustum;
/**
* Polygon's are the building blocks of visible 3D shapes.
*
* @author Thomas Pfeiffer - kiroukou
* @author Mirek Mencel
* @since 1.0
* @version 3.1
* @date 24.08.2007
*
* @see sandy.core.scenegraph.Shape3D
*/
public final class Polygon implements IDisplayable
{
// _______
// STATICS_______________________________________________________
private static var _ID_:uint = 0;
/**
* This property lists all the polygons.
* This is a helper property since it allows all polygons of a scene to
be retrieved from a single list by its unique identifier.
* A polygon's unique identifier can be retrieved useing
<code>myPolygon.id</code>.
*
* @example The examples below shows how to retrieve a ploygon from this
property.
* <listing version="3.1">
* var p:Polygon = Polygon.POLYGON_MAP[myPolygon.id];
* </listing>
*/
public static var POLYGON_MAP:Dictionary = new Dictionary(true);
// ______
// PUBLIC________________________________________________________
/**
* The unique identifier for this polygon.
*/
public const id:uint = _ID_++;
/**
* A reference to the Shape3D object this polygon belongs to.
*/
public var shape:Shape3D;
/**
* Specifies if the polygon has been clipped.
*/
public var isClipped:Boolean = false;
/**
* An array of clipped vertices. Check the <code>isClipped</code>
property first to see if this array will contain the useful data.
*/
public var cvertices:Array;
/**
* An array of the polygon's original vertices.
*/
public var vertices:Array;
/**
* An array of the polygon's vertex normals.
*/
public var vertexNormals:Array;
public var aUVCoord:Array;
/**
* An array of the polygon's edges.
*/
public var aEdges:Array;
public var caUVCoord:Array;
/**
* The texture bounds.
*/
public var uvBounds:Rectangle;
/**
* An array of polygons that share an edge with this polygon.
*/
public var aNeighboors:Array = new Array();
/**
* Specifies whether the face of the polygon is visible.
*/
public var visible:Boolean;
/**
* Minimum depth value of that polygon in the camera space
*/
public var minZ:Number;
public var a:Vertex, b:Vertex, c:Vertex, d:Vertex;
/**
* Creates a new polygon.
*
* @param p_oShape The shape the polygon belongs to.
* @param p_geometry The geometry the polygon belongs to.
* @param p_aVertexID An array of verticies of the polygon.
* @param p_aUVCoordsID An array of UV coordinates of this polygon.
* @param p_nFaceNormalID The faceNormalID of this polygon.
* @param p_nEdgesID The edgesID of this polygon.
*/
public function Polygon( p_oOwner:Shape3D, p_geometry:Geometry3D,
p_aVertexID:Array, p_aUVCoordsID:Array=null, p_nFaceNormalID:Number=0,
p_nEdgesID:uint=0 )
{
shape = p_oOwner;
m_oGeometry = p_geometry;
// --
__update( p_aVertexID, p_aUVCoordsID, p_nFaceNormalID, p_nEdgesID );
m_oContainer = new Sprite();
// --
POLYGON_MAP[id] = this;
m_oEB = new BubbleEventBroadcaster(this);
}
public function get changed():Boolean
{
return shape.changed;
}
/**
* A reference to the Scene3D object this polygon is in.
*/
public function set scene(p_oScene:Scene3D):void
{
if( p_oScene == null ) return;
if( m_oScene != null )
{
m_oScene.removeEventListener(SandyEvent.SCENE_RENDER_FINISH,
_finishMaterial );
m_oScene.removeEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
}
// --
m_oScene = p_oScene;
// --
m_oScene.addEventListener(SandyEvent.SCENE_RENDER_FINISH,
_finishMaterial );
m_oScene.addEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
}
public function get scene():Scene3D
{
return m_oScene;
}
private var m_oScene:Scene3D = null;
/**
* Updates the vertices and normals for this polygon.
*
* <p>Calling this method make the polygon gets its vertice and normals
by reference
* instead of accessing them by their ID.<br/>
* This method shall be called once the geometry created.</p>
*
* @param p_aVertexID The vertexID array of this polygon
* @param p_aUVCoordsID The UVCoordsID array of this polygon
* @param p_nFaceNormalID The faceNormalID of this polygon
* @param p_nEdgesID The edgesID of this polygon
*/
private function __update( p_aVertexID:Array, p_aUVCoordsID:Array,
p_nFaceNormalID:uint, p_nEdgeListID:uint ):void
{
var i:int=0;
// --
vertexNormals = new Array();
vertices = new Array();
for each( var o:* in p_aVertexID )
{
vertices[i] = Vertex( m_oGeometry.aVertex[ p_aVertexID[i] ] );
vertexNormals[i] = m_oGeometry.aVertexNormals[ p_aVertexID[i] ];
i++;
}
// --
a = vertices[0];
b = vertices[1];
c = vertices[2];
d = vertices[3];
// -- every polygon does not have some texture coordinates
if( p_aUVCoordsID )
{
var l_nMinU:Number = Number.POSITIVE_INFINITY, l_nMinV:Number =
Number.POSITIVE_INFINITY,
l_nMaxU:Number = Number.NEGATIVE_INFINITY, l_nMaxV:Number =
Number.NEGATIVE_INFINITY;
// --
aUVCoord = new Array();
i = 0;
if( p_aUVCoordsID )
{
for each( var p:* in p_aUVCoordsID )
{
var l_oUV:UVCoord = ( m_oGeometry.aUVCoords[ p_aUVCoordsID[i] ] as
UVCoord);
if( l_oUV == null ) l_oUV = new UVCoord(0,0);
// --
aUVCoord[i] = l_oUV;
if( l_oUV.u < l_nMinU ) l_nMinU = l_oUV.u;
else if( l_oUV.u > l_nMaxU ) l_nMaxU = l_oUV.u;
// --
if( l_oUV.v < l_nMinV ) l_nMinV = l_oUV.v;
else if( l_oUV.v > l_nMaxV ) l_nMaxV = l_oUV.v;
// --
i++;
}
// --
uvBounds = new Rectangle( l_nMinU, l_nMinV, l_nMaxU-l_nMinU,
l_nMaxV-l_nMinV );
}
else
{
aUVCoord = [new UVCoord(), new UVCoord(), new UVCoord()];
uvBounds = new Rectangle(0,0,0,0);
}
}
// --
m_nNormalId = p_nFaceNormalID;
normal = Vertex( m_oGeometry.aFacesNormals[ p_nFaceNormalID ] );
// If no normal has been given, we create it ourself.
if( normal == null )
{
var l_oNormal:Point3D = createNormal();
m_nNormalId = m_oGeometry.setFaceNormal(
m_oGeometry.getNextFaceNormalID(), l_oNormal.x, l_oNormal.y, l_oNormal.z );
}
// --
aEdges = new Array();
for each( var l_nEdgeId:uint in m_oGeometry.aFaceEdges[p_nEdgeListID] )
{
var l_oEdge:Edge3D = m_oGeometry.aEdges[ l_nEdgeId ];
l_oEdge.vertex1 = m_oGeometry.aVertex[ l_oEdge.vertexId1 ];
l_oEdge.vertex2 = m_oGeometry.aVertex[ l_oEdge.vertexId2 ];
aEdges.push( l_oEdge );
}
}
public function get normal():Vertex
{
return m_oGeometry.aFacesNormals[ m_nNormalId ];
}
public function set normal( p_oVertex:Vertex ):void
{
if( p_oVertex != null )
m_oGeometry.aFacesNormals[ m_nNormalId ].copy( p_oVertex );
}
public function updateNormal():void
{
var x:Number = ((a.y - b.y) * (c.z - b.z)) - ((a.z - b.z) * (c.y -
b.y)) ;
var y:Number = ((a.z - b.z) * (c.x - b.x)) - ((a.x - b.x) * (c.z -
b.z)) ;
var z:Number = ((a.x - b.x) * (c.y - b.y)) - ((a.y - b.y) * (c.x -
b.x)) ;
normal.reset( x, y, z );
}
/**
* The depth of the polygon.
*/
public function get depth():Number
{
return m_nDepth;
}
/**
* @private
*/
public function set depth( p_nDepth:Number ):void
{
m_nDepth = p_nDepth;
}
/**
* The broadcaster of the polygon that sends events to listeners.
*/
public function get broadcaster():BubbleEventBroadcaster
{
return m_oEB;
}
/**
* Adds an event listener to the polygon.
*
* @param p_sEvent The name of the event to add.
* @param oL The listener object.
*/
public function addEventListener(p_sEvent:String, oL:*) : void
{
m_oEB.addEventListener.apply(m_oEB, arguments);
}
/**
* Removes an event listener to the polygon.
*
* @param p_sEvent The name of the event to remove.
* @param oL The listener object.
*/
public function removeEventListener(p_sEvent:String, oL:*) : void
{
m_oEB.removeEventListener(p_sEvent, oL);
}
/**
* Computes several properties of the polygon.
* <p>The computed properties are listed below:</p>
* <ul>
* <li><code>visible</code></li>
* <li><code>minZ</code></li>
* <li><code>depth</code></li>
* </ul>
*/
public function precompute():void
{
isClipped = false;
// --
minZ = a.wz;
if (b.wz < minZ) minZ = b.wz;
m_nDepth = a.wz + b.wz;
// --
if (c != null)
{
if (c.wz < minZ) minZ = c.wz;
m_nDepth += c.wz;
}
if (d != null)
{
if (d.wz < minZ) minZ = d.wz;
m_nDepth += d.wz;
}
m_nDepth /= vertices.length;
}
/**
* Returns a Point3D (3D position) on the polygon relative to the
specified point on the 2D screen.
*
* @example Below is an example of how to get the 3D coordinate of the
polygon under the position of the mouse:
* <listing version="3.1">
* var screenPoint:Point = new Point(myPolygon.container.mouseX,
myPolygon.container.mouseY);
* var scenePosition:Point3D = myPolygon.get3DFrom2D(screenPoint);
* </listing>
*
* @return A Point3D that corresponds to the specified point.
*/
public function get3DFrom2D( p_oScreenPoint:Point ):Point3D
{
/// NEW CODE ADDED BY MAX with the help of makc ///
var m1:Matrix= new Matrix(
vertices[1].sx-vertices[0].sx,
vertices[2].sx-vertices[0].sx,
vertices[1].sy-vertices[0].sy,
vertices[2].sy-vertices[0].sy,
0,
0);
m1.invert();
var capA:Number = m1.a *(p_oScreenPoint.x-vertices[0].sx) + m1.b *
(p_oScreenPoint.y -vertices[0].sy);
var capB:Number = m1.c *(p_oScreenPoint.x-vertices[0].sx) + m1.d *
(p_oScreenPoint.y -vertices[0].sy);
var l_oPoint:Point3D = new Point3D(
vertices[0].x + capA*(vertices[1].x -vertices[0].x) + capB
*(vertices[2].x - vertices[0].x),
vertices[0].y + capA*(vertices[1].y -vertices[0].y) + capB
*(vertices[2].y - vertices[0].y),
vertices[0].z + capA*(vertices[1].z -vertices[0].z) + capB
*(vertices[2].z - vertices[0].z)
);
// transform the vertex with the model Matrix
this.shape.matrix.transform( l_oPoint );
return l_oPoint;
}
/**
* Returns a UV coordinate elative to the specified point on the 2D
screen.
*
* @example Below is an example of how to get the UV coordinate under the
position of the mouse:
* <listing version="3.1">
* var screenPoint:Point = new Point(myPolygon.container.mouseX,
myPolygon.container.mouseY);
* var scenePosition:Point3D = myPolygon.getUVFrom2D(screenPoint);
* </listing>
*
* @return A the UV coordinate that corresponds to the specified
point.
*/
public function getUVFrom2D( p_oScreenPoint:Point ):UVCoord
{
var p0:Point = new Point(vertices[0].sx, vertices[0].sy);
var p1:Point = new Point(vertices[1].sx, vertices[1].sy);
var p2:Point = new Point(vertices[2].sx, vertices[2].sy);
var u0:UVCoord = aUVCoord[0];
var u1:UVCoord = aUVCoord[1];
var u2:UVCoord = aUVCoord[2];
var v01:Point = new Point(p1.x - p0.x, p1.y - p0.y );
var vn01:Point = v01.clone();
vn01.normalize(1);
var v02:Point = new Point(p2.x - p0.x, p2.y - p0.y );
var vn02:Point = v02.clone(); vn02.normalize(1);
// sub that from click point
var v4:Point = new Point( p_oScreenPoint.x - v01.x,
p_oScreenPoint.y - v01.y );
// we now have everything to find 1 intersection
var l_oInter:Point = IntersectionMath.intersectionLine2D( p0,
p2, p_oScreenPoint, v4 );
// find Point3Ds to intersection
var vi02:Point = new Point( l_oInter.x - p0.x, l_oInter.y -
p0.y );
var vi01:Point = new Point( p_oScreenPoint.x - l_oInter.x ,
p_oScreenPoint.y - l_oInter.y );
// interpolation coeffs
var d1:Number = vi01.length / v01.length ;
var d2:Number = vi02.length / v02.length;
// -- on interpole linéairement pour trouver la position du
point dans repere de la texture (normalisé)
return new UVCoord( u0.u + d1*(u1.u - u0.u) + d2*(u2.u - u0.u),
u0.v + d1*(u1.v - u0.v) + d2*(u2.v - u0.v));
}
/**
* Clips the polygon.
*
* @return An array of vertices clipped by the camera frustum.
*/
public function clip( p_oFrustum:Frustum ):Array
{
cvertices = null;
caUVCoord = null;
// --
var l_oCull:CullingState = p_oFrustum.polygonInFrustum( this );
if( l_oCull == CullingState.INSIDE )
return vertices;
else if( l_oCull == CullingState.OUTSIDE )
return null;
// For lines we only apply front plane clipping
if( vertices.length < 3 )
{
clipFrontPlane( p_oFrustum );
}
else
{
cvertices = vertices.slice();
caUVCoord = aUVCoord.slice();
// --
isClipped = p_oFrustum.clipFrustum( cvertices, caUVCoord );
}
return cvertices;
}
/**
* Perform a clipping against the camera frustum's front plane.
*
* @return An array of vertices clipped by the camera frustum's front
plane.
*/
public function clipFrontPlane( p_oFrustum:Frustum ):Array
{
cvertices = vertices.slice();
// If line
if( vertices.length < 3 )
{
isClipped = p_oFrustum.clipLineFrontPlane( cvertices );
}
else
{
caUVCoord = aUVCoord.slice();
isClipped = p_oFrustum.clipFrontPlane( cvertices, caUVCoord );
}
return cvertices;
}
/**
* Clears the polygon's container.
*/
public function clear():void
{
if (m_oContainer != null) m_oContainer.graphics.clear();
}
/**
* Draws the polygon on its container if visible.
*
* @param p_oScene The scene this polygon is rendered in.
* @param p_oContainer The container to draw on.
*/
public function display( p_oContainer:Sprite = null ):void
{
const lCont:Sprite = (p_oContainer)?p_oContainer:m_oContainer;
if( visible )
{
m_oAppearance.frontMaterial.renderPolygon( scene, this, lCont );
}
else
{
m_oAppearance.backMaterial.renderPolygon( scene, this, lCont );
}
}
/**
* Returns the material currently used by the renderer
* @return Material the material used to render
*/
public function get material():Material
{
return ( visible ) ? m_oAppearance.frontMaterial :
m_oAppearance.backMaterial;
}
/**
* The polygon's container.
*/
public function get container():Sprite
{
return m_oContainer;
}
/**
* Returns a string representation of this object.
*
* @return The fully qualified name of this object.
*/
public function toString():String
{
return "sandy.core.data.Polygon::id=" +id+ " [Points: " +
vertices.length + "]";
}
/**
* Specifies whether mouse events are enabled for this polygon.
*
* <p>To apply events to a polygon, listeners must be added with the
<code>addEventListener()</code> method.</p>
*
* @see #addEventListener()
*/
public function get enableEvents():Boolean
{
return mouseEvents;
}
/**
* @private
*/
public function set enableEvents( b:Boolean ):void
{
if( b && !mouseEvents )
{
container.addEventListener(MouseEvent.CLICK, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_UP, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
container.addEventListener(MouseEvent.ROLL_OVER, _onInteraction);
container.addEventListener(MouseEvent.ROLL_OUT, _onInteraction);
container.addEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
container.addEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
}
else if( !b && mouseEvents )
{
container.removeEventListener(MouseEvent.CLICK, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_UP, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_DOWN, _onInteraction);
container.removeEventListener(MouseEvent.ROLL_OVER, _onInteraction);
container.removeEventListener(MouseEvent.ROLL_OUT, _onInteraction);
container.removeEventListener(MouseEvent.DOUBLE_CLICK, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_MOVE, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_OVER, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_OUT, _onInteraction);
container.removeEventListener(MouseEvent.MOUSE_WHEEL, _onInteraction);
}
mouseEvents = b;
}
/**
* @private
*/
protected function _onInteraction( p_oEvt:Event ):void
{
var l_oClick:Point = new Point( m_oContainer.mouseX, m_oContainer.mouseY
);
var l_oUV:UVCoord = getUVFrom2D( l_oClick );
var l_oPt3d:Point3D = get3DFrom2D( l_oClick );
m_oEB.dispatchEvent( new Shape3DEvent( p_oEvt.type, shape, this, l_oUV,
l_oPt3d, p_oEvt ) );
}
/**
* @private
*/
protected function _startMouseInteraction( e : MouseEvent = null ) : void
{
container.addEventListener(MouseEvent.CLICK, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_UP, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_DOWN, _onTextureInteraction);
container.addEventListener(MouseEvent.DOUBLE_CLICK,
_onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_MOVE, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_OVER, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_OUT, _onTextureInteraction);
container.addEventListener(MouseEvent.MOUSE_WHEEL,
_onTextureInteraction);
container.addEventListener(KeyboardEvent.KEY_DOWN,
_onTextureInteraction);
container.addEventListener(KeyboardEvent.KEY_UP, _onTextureInteraction);
m_oContainer.addEventListener( Event.ENTER_FRAME, _onTextureInteraction
);
}
/**
* @private
*/
protected function _stopMouseInteraction( e : MouseEvent = null ) : void
{
container.removeEventListener(MouseEvent.CLICK, _onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_UP,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_DOWN,
_onTextureInteraction);
container.removeEventListener(MouseEvent.DOUBLE_CLICK,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_MOVE,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_OVER,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_OUT,
_onTextureInteraction);
container.removeEventListener(MouseEvent.MOUSE_WHEEL,
_onTextureInteraction);
m_oContainer.removeEventListener( Event.ENTER_FRAME,
_onTextureInteraction );
container.removeEventListener(KeyboardEvent.KEY_DOWN,
_onTextureInteraction);
container.removeEventListener(KeyboardEvent.KEY_UP,
_onTextureInteraction);
}
/**
* Specifies whether <code>MouseEvent.ROLL_*</code> events are
enabled for this polygon.
*
* <p>To apply events to a polygon, listeners must be added with the
<code>addEventListener()</code> method.</p>
*
* @see #addEventListener()
*/
public function get enableInteractivity():Boolean
{
return mouseInteractivity;
}
/**
* @private
*/
public function set enableInteractivity( p_bState:Boolean ):void
{
if( p_bState != mouseInteractivity )
{
if( p_bState )
{
container.addEventListener( MouseEvent.ROLL_OVER,
_startMouseInteraction, false );
container.addEventListener( MouseEvent.ROLL_OUT,
_stopMouseInteraction, false );
}
else
{
_stopMouseInteraction();
}
// --
mouseInteractivity = p_bState;
}
}
/**
* @private
*/
protected function _onTextureInteraction( p_oEvt:Event = null ) : void
{
if ( p_oEvt == null || !(p_oEvt is MouseEvent) ) p_oEvt = new
MouseEvent( MouseEvent.MOUSE_MOVE, true, false, 0, 0, null, false, false,
false, false, 0);
// get the position of the mouse on the poly
var pt2D : Point = new Point( scene.container.mouseX,
scene.container.mouseY );
var uv : UVCoord = getUVFrom2D( pt2D );
VirtualMouse.getInstance().interactWithTexture( this, uv, p_oEvt as
MouseEvent );
_onInteraction( p_oEvt );
}
/**
* Returns the transformed normal Point3D of the polygon.
*
* @return The transformed normal Point3D of the polygon.
*/
public function createTransformedNormal():Point3D
{
if( vertices.length > 2 )
{
var v:Point3D, w:Point3D;
var a:Vertex = vertices[0], b:Vertex = vertices[1], c:Vertex =
vertices[2];
v = new Point3D( b.wx - a.wx, b.wy - a.wy, b.wz - a.wz );
w = new Point3D( b.wx - c.wx, b.wy - c.wy, b.wz - c.wz );
// we compute de cross product
var l_normal:Point3D = Point3DMath.cross( v, w );
// we normalize the resulting Point3D
Point3DMath.normalize( l_normal ) ;
// we return the resulting vertex
return l_normal;
}
else
{
return new Point3D();
}
}
/**
* Returns the normal Point3D of the polygon.
*
* @return The normal Point3D of the polygon.
*/
public function createNormal():Point3D
{
if( vertices.length > 2 )
{
var v:Point3D, w:Point3D;
var a:Vertex = vertices[0], b:Vertex = vertices[1], c:Vertex =
vertices[2];
v = new Point3D( b.x - a.x, b.y - a.y, b.z - a.z );
w = new Point3D( b.x - c.x, b.y - c.y, b.z - c.z );
// we compute de cross product
var l_normal:Point3D = Point3DMath.cross( v, w );
// we normalize the resulting Point3D
Point3DMath.normalize( l_normal ) ;
// we return the resulting vertex
return l_normal;
}
else
{
return new Point3D();
}
}
/**
* The appearance of this polygon.
*/
public function get appearance():Appearance
{
return m_oAppearance;
}
/**
* @private
*/
public function set appearance( p_oApp:Appearance ):void
{
if( m_oAppearance != null )
{
m_oAppearance.frontMaterial.unlink( this );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.unlink( this );
}
m_oAppearance = null;
}
// --
if( p_oApp != null )
{
m_oAppearance = p_oApp;
// --
m_oAppearance.frontMaterial.init( this );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.init( this );
}
}
}
private function _finishMaterial( pEvt:SandyEvent ):void
{
if( !m_oAppearance ) return;
//if( !visible ) return;
// --
m_oAppearance.frontMaterial.finish( m_oScene );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.finish( m_oScene );
}
}
private function _beginMaterial( pEvt:SandyEvent ):void
{
if( !m_oAppearance ) return;
//if( !visible ) return;
// --
m_oAppearance.frontMaterial.begin( m_oScene );
if( m_oAppearance.backMaterial != m_oAppearance.frontMaterial )
{
m_oAppearance.backMaterial.begin( m_oScene );
}
}
/**
* Changes which side is the "normal" culling side.
*
* <p>This method also swaps the front and back skins.</p>
*/
public function swapCulling():void
{
normal.negate();
}
/**
* Removes the polygon's container from the stage.
*/
public function destroy():void
{
clear();
scene.removeEventListener(SandyEvent.SCENE_RENDER_FINISH,
_finishMaterial );
scene.removeEventListener(SandyEvent.SCENE_RENDER_DISPLAYLIST,
_beginMaterial );
// --
enableEvents = false;
enableInteractivity = false;
if( appearance.backMaterial ) appearance.backMaterial.unlink( this );
if( appearance.frontMaterial ) appearance.frontMaterial.unlink( this );
appearance = null;
if( m_oContainer.parent ) m_oContainer.parent.removeChild( m_oContainer
);
if( m_oContainer ) m_oContainer = null;
// --
cvertices = null;
vertices = null;
m_oEB = null;
m_oGeometry = null;
shape = null;
scene = null;
// -- memory leak fix from nopmb on mediabox forums
delete POLYGON_MAP[id];
}
// _______
// PRIVATE_______________________________________________________
/** Reference to its owner geometry */
private var m_oGeometry:Geometry3D;
private var m_oAppearance:Appearance;
private var m_nNormalId:uint;
private var m_nDepth:Number;
/**
* @private
*/
protected var m_oContainer:Sprite;
/**
* @private
*/
protected var m_oEB:BubbleEventBroadcaster;
/** Boolean representing the state of the event activation */
private var mouseEvents:Boolean = false;
private var mouseInteractivity:Boolean = false;
}
}
\ No newline at end of file
Modified: trunk/sandy/as3/trunk/src/sandy/materials/BitmapMaterial.as
==============================================================================
--- trunk/sandy/as3/trunk/src/sandy/materials/BitmapMaterial.as (original)
+++ trunk/sandy/as3/trunk/src/sandy/materials/BitmapMaterial.as Mon Feb 23
13:53:09 2009
@@ -374,7 +374,8 @@
*/
public function setTransparency( p_nValue:Number ):void
{
- if (m_oTexture == null) {
+ if (m_oTexture == null)
+ {
throw new Error ("Setting transparency requires setting texture
first.");
}
@@ -382,15 +383,18 @@
if (p_nValue == 1) return;
- if (m_oTextureClone != null) {
+ if (m_oTextureClone != null)
+ {
if ((m_oTextureClone.height != m_oTexture.height) ||
- (m_oTextureClone.width != m_oTexture.width)) {
+ (m_oTextureClone.width != m_oTexture.width))
+ {
m_oTextureClone.dispose ();
m_oTextureClone = null;
}
}
- if (m_oTextureClone == null) {
+ if (m_oTextureClone == null)
+ {
m_oTextureClone = new BitmapData (m_oTexture.width, m_oTexture.height,
true, 0);
}
@@ -467,7 +471,7 @@
*/
public function toString():String
{
- return 'sandy.materials.BitmapMaterial' ;
+ return this.id+'::sandy.materials.BitmapMaterial' ;
}
/**
Modified: trunk/sandy/as3/trunk/src/sandy/materials/Material.as
==============================================================================
--- trunk/sandy/as3/trunk/src/sandy/materials/Material.as (original)
+++ trunk/sandy/as3/trunk/src/sandy/materials/Material.as Mon Feb 23
13:53:09 2009
@@ -1 +1 @@
-
package sandy.materials
{
import flash.display.Sprite;
import sandy.core.Scene3D;
import sandy.core.data.Polygon;
import sandy.core.scenegraph.Sprite2D;
import sandy.materials.attributes.MaterialAttributes;
/**
* The Material class is the base class for all materials.
*
* <p>Since the Material object is essentially a blank material, this
class can be used
* to apply attributes without any material to a 3D object.</p>
*
* @author Thomas Pfeiffer - kiroukou
* @version 3.1
* @date 26.07.2007
*
* @see Appearance
*/
public class Material
{
/**
* The attributes of this material.
*/
public var attributes:MaterialAttributes;
/**
* Specify if the material use the vertex normal information.
*
* @default false
*/
public var useVertexNormal:Boolean = false;
/**
* Specifies if the material can receive light and have light attributes
applied to it.
* Can be useful to rapidly disable light on the object when unneeded.
*/
public var lightingEnable:Boolean = false;
/**
* Creates a material.
*
* <p>This constructor is never called directly - but by sub class
constructors.</p>
* @param p_oAttr The attributes for this material.
*/
public function Material( p_oAttr:MaterialAttributes = null )
{
_filters = [];
_useLight = false;
_id = _ID_++;
attributes = (p_oAttr == null) ? new MaterialAttributes() : p_oAttr;
m_bModified = true;
m_oType = MaterialType.NONE;
}
/**
* The unique id of this material.
*/
public function get id():Number
{
return _id;
}
/**
* Calls begin method of the MaterialAttributes associated with this
material.
*
* @param p_oScene The scene.
*
* @see sandy.materials.attributes.MaterialAttributes#begin()
*/
public function begin( p_oScene:Scene3D ):void
{
if( attributes )
attributes.begin( p_oScene );
}
/**
* Calls finish method of the MaterialAttributes associated with this
material.
*
* @param p_oScene The scene.
*
* @see sandy.materials.attributes.MaterialAttributes#finish()
*/
public function finish( p_oScene:Scene3D ):void
{
if( attributes )
attributes.finish(p_oScene );
// --
m_bModified = false;
}
/**
* Renders the polygon dress in this material.
*
* <p>Implemented by sub classes.</p>
*
* @see sandy.core.Scene3D
* @see sandy.core.data.Polygon
*/
public function renderPolygon( p_oScene:Scene3D, p_oPolygon:Polygon,
p_mcContainer:Sprite ):void
{
if( attributes )
attributes.draw( p_mcContainer.graphics, p_oPolygon, this, p_oScene );
// --
if( _filters.length > 0 )
p_mcContainer.filters = _filters;
}
/**
* Renders the sprite dress in this material.
*
* <p>Basically only needed to apply attributes to sprites</p>
*
* @see sandy.core.scenegraph.Sprite2D
* @see sandy.core.Scene3D
*/
public function renderSprite( p_oSprite:Sprite2D, p_oMaterial:Material,
p_oScene:Scene3D ):void
{
if( attributes )
{
attributes.drawOnSprite( p_oSprite, p_oMaterial, p_oScene );
}
// --
if( _filters.length > 0 )
p_oSprite.content.filters = _filters;
}
/**
* Calls init method of the MaterialAttributes associated with this
material.
*
* @see sandy.materials.attributes.MaterialAttributes#init()
*/
public function init( p_oPolygon:Polygon ):void
{
if( attributes )
attributes.init( p_oPolygon );
}
/**
* Calls unlink method of the MaterialAttributes associated with this
material.
*
* @see sandy.materials.attributes.MaterialAttributes#unlink()
*/
public function unlink( p_oPolygon:Polygon ):void
{
if( attributes )
attributes.unlink( p_oPolygon );
}
/**
* The material type of this material.
*
* @default MaterialType.NONE
*
* @see MaterialType
*/
public function get type():MaterialType
{
return m_oType;
}
/**
* @private
*/
public function set filters( a:Array ):void
{
_filters = a;
m_bModified = true;
}
/**
* Contains specific material flags.
*/
public function get flags():uint
{
var l_nFlags:uint = m_nFlags;
if( attributes )
l_nFlags |= attributes.flags;
return l_nFlags;
}
/**
* The array of filters for this material.
*
* <p>You use this property to add an array of filters you want to apply
to this material<br>
* To remove the filters, just assign an empty array.</p>
*/
public function get filters():Array
{
return _filters;
}
/**
* The modified state of this material.
*
* <p>true if this material or its line attributes were modified since
last rendered, false otherwise.</p>
*/
public function get modified():Boolean
{
return (m_bModified);// && ((lineAttributes) ? lineAttributes.modified :
true));
}
/**
* The repeat property.
*
* This affects the way textured materials are mapped for U or V out of
0-1 range.
*/
public var repeat:Boolean = true;
//////////////////
// PROPERTIES
//////////////////
/**
* DO NOT TOUCH THIS PROPERTY UNLESS YOU PERFECTLY KNOW WHAT YOU ARE
DOING.
* this flag property contains the specific material flags.
*
* @private
*/
protected var m_nFlags:uint = 0;
/**
* @private
*/
protected var m_bModified:Boolean;
/**
* @private
*/
protected var _useLight : Boolean = false;
/**
* @private
*/
protected var m_oType:MaterialType;
private var _filters:Array;
private var _id:Number;
private static var _ID_:Number = 0;
private static var create:Boolean;
}
}
\ No newline at end of file
+
package sandy.materials
{
import flash.display.Sprite;
import sandy.core.Scene3D;
import sandy.core.data.Polygon;
import sandy.core.scenegraph.Sprite2D;
import sandy.materials.attributes.MaterialAttributes;
/**
* The Material class is the base class for all materials.
*
* <p>Since the Material object is essentially a blank material, this
class can be used
* to apply attributes without any material to a 3D object.</p>
*
* @author Thomas Pfeiffer - kiroukou
* @version 3.1
* @date 26.07.2007
*
* @see Appearance
*/
public class Material
{
/**
* The attributes of this material.
*/
public var attributes:MaterialAttributes;
/**
* Specify if the material use the vertex normal information.
*
* @default false
*/
public var useVertexNormal:Boolean = false;
/**
* Specifies if the material can receive light and have light attributes
applied to it.
* Can be useful to rapidly disable light on the object when unneeded.
*/
public var lightingEnable:Boolean = false;
/**
* Creates a material.
*
* <p>This constructor is never called directly - but by sub class
constructors.</p>
* @param p_oAttr The attributes for this material.
*/
public function Material( p_oAttr:MaterialAttributes = null )
{
_filters = [];
_useLight = false;
_id = _ID_++;
attributes = (p_oAttr == null) ? new MaterialAttributes() : p_oAttr;
m_bModified = true;
m_oType = MaterialType.NONE;
}
/**
* The unique id of this material.
*/
public function get id():Number
{
return _id;
}
/**
* Calls begin method of the MaterialAttributes associated with this
material.
*
* @param p_oScene The scene.
*
* @see sandy.materials.attributes.MaterialAttributes#begin()
*/
public function begin( p_oScene:Scene3D ):void
{
if( attributes )
attributes.begin( p_oScene );
}
/**
* Calls finish method of the MaterialAttributes associated with this
material.
*
* @param p_oScene The scene.
*
* @see sandy.materials.attributes.MaterialAttributes#finish()
*/
public function finish( p_oScene:Scene3D ):void
{
if( attributes )
attributes.finish(p_oScene );
// --
m_bModified = false;
}
/**
* Renders the polygon dress in this material.
*
* <p>Implemented by sub classes.</p>
*
* @see sandy.core.Scene3D
* @see sandy.core.data.Polygon
*/
public function renderPolygon( p_oScene:Scene3D, p_oPolygon:Polygon,
p_mcContainer:Sprite ):void
{
if( attributes )
attributes.draw( p_mcContainer.graphics, p_oPolygon, this, p_oScene );
// --
if( _filters.length > 0 )
p_mcContainer.filters = _filters;
}
/**
* Renders the sprite dress in this material.
*
* <p>Basically only needed to apply attributes to sprites</p>
*
* @see sandy.core.scenegraph.Sprite2D
* @see sandy.core.Scene3D
*/
public function renderSprite( p_oSprite:Sprite2D, p_oMaterial:Material,
p_oScene:Scene3D ):void
{
if( attributes )
{
attributes.drawOnSprite( p_oSprite, p_oMaterial, p_oScene );
}
// --
if( _filters.length > 0 )
p_oSprite.content.filters = _filters;
}
/**
* Calls init method of the MaterialAttributes associated with this
material.
*
* @see sandy.materials.attributes.MaterialAttributes#init()
*/
public function init( p_oPolygon:Polygon ):void
{
if( attributes )
attributes.init( p_oPolygon );
}
/**
* Calls unlink method of the MaterialAttributes associated with this
material.
*
* @see sandy.materials.attributes.MaterialAttributes#unlink()
*/
public function unlink( p_oPolygon:Polygon ):void
{
if( attributes )
attributes.unlink( p_oPolygon );
}
/**
* The material type of this material.
*
* @default MaterialType.NONE
*
* @see MaterialType
*/
public function get type():MaterialType
{
return m_oType;
}
/**
* @private
*/
public function set filters( a:Array ):void
{
if( a != _filters )
{
_filters = a;
m_bModified = true;
}
}
/**
* Contains specific material flags.
*/
public function get flags():uint
{
var l_nFlags:uint = m_nFlags;
if( attributes )
l_nFlags |= attributes.flags;
return l_nFlags;
}
/**
* The array of filters for this material.
*
* <p>You use this property to add an array of filters you want to apply
to this material<br>
* To remove the filters, just assign an empty array.</p>
*/
public function get filters():Array
{
return _filters;
}
/**
* The modified state of this material.
*
* <p>true if this material or its line attributes were modified since
last rendered, false otherwise.</p>
*/
public function get modified():Boolean
{
return m_bModified;// && ((lineAttributes) ? lineAttributes.modified :
true));
}
/**
* The repeat property.
*
* This affects the way textured materials are mapped for U or V out of
0-1 range.
*/
public var repeat:Boolean = true;
//////////////////
// PROPERTIES
//////////////////
/**
* DO NOT TOUCH THIS PROPERTY UNLESS YOU PERFECTLY KNOW WHAT YOU ARE
DOING.
* this flag property contains the specific material flags.
*
* @private
*/
protected var m_nFlags:uint = 0;
/**
* @private
*/
protected var m_bModified:Boolean;
/**
* @private
*/
protected var _useLight : Boolean = false;
/**
* @private
*/
protected var m_oType:MaterialType;
private var _filters:Array;
private var _id:Number;
private static var _ID_:Number = 0;
private static var create:Boolean;
}
}
\ No newline at end of file
Added: trunk/sandy/as3/trunk/src/sandy/view/BasicView.as
==============================================================================
--- (empty file)
+++ trunk/sandy/as3/trunk/src/sandy/view/BasicView.as Mon Feb 23 13:53:09
2009
@@ -0,0 +1,151 @@
+package sandy.view
+{
+ import flash.display.BitmapData;
+ import flash.display.Sprite;
+ import flash.events.Event;
+
+ import sandy.core.Scene3D;
+ import sandy.core.data.Point3D;
+ import sandy.core.scenegraph.Camera3D;
+ import sandy.core.scenegraph.Group;
+ import sandy.materials.Appearance;
+ import sandy.materials.BitmapMaterial;
+ import sandy.materials.ColorMaterial;
+ import sandy.materials.MovieMaterial;
+ import sandy.materials.attributes.MaterialAttributes;
+ import sandy.primitive.Box;
+ import sandy.primitive.Plane3D;
+ import sandy.primitive.Sphere;
+
+ /**
+ * Basic view to simplify Sandy scene setup.
+ * You just have to extends it, and call init method with your settings.
+ * Right after that you can use some utils methods to improve workflow.
+ */
+ public class BasicView extends Sprite
+ {
+ public var useRenderingCache:Boolean = true;
+ public var camera:Camera3D;
+ public var scene:Scene3D;
+ public var rootNode:Group;
+
+ public function BasicView()
+ {
+ super();
+ }
+
+ public function init( p_nWidth:Number = 640, p_nHeight:Number = 480
):void
+ {
+ rootNode = new Group("root");
+ camera = new Camera3D(p_nWidth, p_nHeight );
+ scene = new Scene3D("mainScene", this, camera, rootNode);
+ }
+
+ public function render():void
+ {
+ this.addEventListener(Event.ENTER_FRAME, simpleRender );
+ }
+
+ public function stop():void
+ {
+ this.removeEventListener(Event.ENTER_FRAME, simpleRender );
+ }
+
+ public function simpleRender( pEvt:Event = null ):void
+ {
+ scene.render( useRenderingCache );
+ }
+
+ public function makeBitmapAppearance( p_oTexture:BitmapData,
p_oAttr:MaterialAttributes = null, p_nPrecision:Number = 0.0 ):Appearance
+ {
+ return new Appearance( new BitmapMaterial( p_oTexture, p_oAttr,
p_nPrecision ) );
+ }
+
+ public function makeMovieAppearance( p_oTexture:Sprite,
p_oAttr:MaterialAttributes = null, p_nPrecision:Number = 0.0 ):Appearance
+ {
+ return new Appearance( new MovieMaterial( p_oTexture, 30, p_oAttr, true
) );
+ }
+
+ public function makeColorAppearance( p_nColor:uint = 0xFF,
p_nAlpha:Number = 1.0, p_oAttr:MaterialAttributes = null ):Appearance
+ {
+ return new Appearance( new ColorMaterial(p_nColor, p_nAlpha, p_oAttr )
);
+ }
+
+ public function addBox( p_nWidth:Number=100, p_nHeight:Number=100,
p_nDepth:Number=100, p_nQuality:uint = 1, p_oPosition:Point3D = null,
p_oRotation:Point3D = null ):Box
+ {
+ var l_oBox:Box = new Box( null, p_nWidth, p_nHeight, p_nDepth, "tri",
p_nQuality );
+ if( p_oPosition )
+ {
+ l_oBox.x = p_oPosition.x;
+ l_oBox.y = p_oPosition.y;
+ l_oBox.z = p_oPosition.z;
+ }
+ if( p_oRotation )
+ {
+ l_oBox.rotateX = p_oRotation.x;
+ l_oBox.rotateY = p_oRotation.y;
+ l_oBox.rotateZ = p_oRotation.z;
+ }
+ rootNode.addChild( l_oBox );
+ return l_oBox;
+ }
+
+ public function addSphere( p_nRadius:Number=100, p_nQualityW:uint = 8,
p_nQualityH:uint = 8, p_oPosition:Point3D = null, p_oRotation:Point3D =
null ):Sphere
+ {
+ var l_oMesh:Sphere = new Sphere( null, p_nRadius, p_nQualityW,
p_nQualityH );
+ if( p_oPosition )
+ {
+ l_oMesh.x = p_oPosition.x;
+ l_oMesh.y = p_oPosition.y;
+ l_oMesh.z = p_oPosition.z;
+ }
+ if( p_oRotation )
+ {
+ l_oMesh.rotateX = p_oRotation.x;
+ l_oMesh.rotateY = p_oRotation.y;
+ l_oMesh.rotateZ = p_oRotation.z;
+ }
+ rootNode.addChild( l_oMesh );
+ return l_oMesh;
+ }
+
+ public function addHorizontalPlane( p_nWidth:Number=100,
p_nHeight:Number=100, p_nQuality:uint = 3, p_oPosition:Point3D = null,
p_oRotation:Point3D = null ):Plane3D
+ {
+ var l_oMesh:Plane3D = new Plane3D( null, p_nHeight, p_nWidth,
p_nQuality, p_nQuality, Plane3D.ZX_ALIGNED, "tri" );
+ if( p_oPosition )
+ {
+ l_oMesh.x = p_oPosition.x;
+ l_oMesh.y = p_oPosition.y;
+ l_oMesh.z = p_oPosition.z;
+ }
+ if( p_oRotation )
+ {
+ l_oMesh.rotateX = p_oRotation.x;
+ l_oMesh.rotateY = p_oRotation.y;
+ l_oMesh.rotateZ = p_oRotation.z;
+ }
+ rootNode.addChild( l_oMesh );
+ return l_oMesh;
+ }
+
+ public function addVerticalPlane( p_nWidth:Number=100,
p_nHeight:Number=100, p_nQuality:uint = 3, p_oPosition:Point3D = null,
p_oRotation:Point3D = null ):Plane3D
+ {
+ var l_oMesh:Plane3D = new Plane3D( null, p_nHeight, p_nWidth,
p_nQuality, p_nQuality, Plane3D.XY_ALIGNED, "tri" );
+ if( p_oPosition )
+ {
+ l_oMesh.x = p_oPosition.x;
+ l_oMesh.y = p_oPosition.y;
+ l_oMesh.z = p_oPosition.z;
+ }
+ if( p_oRotation )
+ {
+ l_oMesh.rotateX = p_oRotation.x;
+ l_oMesh.rotateY = p_oRotation.y;
+ l_oMesh.rotateZ = p_oRotation.z;
+ }
+ rootNode.addChild( l_oMesh );
+ return l_oMesh;
+ }
+
+ }
+}
\ No newline at end of file
_______________________________________________
Sandy mailing list
Sandy@osflash.org
http://osflash.org/mailman/listinfo/sandy_osflash.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic