📄 bitmapmaterial.as
字号:
package org.papervision3d.materials {
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import org.papervision3d.Papervision3D;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3DInstance;
import org.papervision3d.core.material.TriangleMaterial;
import org.papervision3d.core.math.util.FastRectangleTools;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.core.render.data.RenderSessionData;
import org.papervision3d.core.render.draw.ITriangleDrawer;
import org.papervision3d.materials.utils.RenderRecStorage;
/**
* The BitmapMaterial class creates a texture from a BitmapData object.
*
* Materials collect data about how objects appear when rendered.
*
*/
public class BitmapMaterial extends TriangleMaterial implements ITriangleDrawer
{
protected static const DEFAULT_FOCUS:Number = 200;
protected static var hitRect:Rectangle = new Rectangle();
protected var renderRecStorage:Array;
protected var focus:Number = 200;
protected var _precise:Boolean;
protected var _precision:int = 8;
protected var _perPixelPrecision:int = 8;
public var minimumRenderSize:Number = 4;
protected var _texture :Object;
/**
* Indicates if mip mapping is forced.
*/
public static var AUTO_MIP_MAPPING :Boolean = false;
/**
* Levels of mip mapping to force.
*/
public static var MIP_MAP_DEPTH :Number = 8;
public var uvMatrices:Dictionary = new Dictionary();
/**
* @private
*/
protected static var _triMatrix:Matrix = new Matrix();
protected static var _triMap:Matrix;
/**
* @private
*/
protected static var _localMatrix:Matrix = new Matrix();
/**
* The BitmapMaterial class creates a texture from a BitmapData object.
*
* @param asset A BitmapData object.
*/
public function BitmapMaterial( asset:BitmapData=null, precise:Boolean = false)
{
// texture calls createBitmap. That's where all the init happens. This allows to reinit when changing texture. -C4RL05
// if we have an asset passed in, this means we're the subclass, not the super. Set the texture, let the fun begin.
if( asset ) texture = asset;
this.precise = precise;
createRenderRecStorage();
}
protected function createRenderRecStorage():void
{
this.renderRecStorage = new Array();
for(var a:int = 0; a<=100; a++){
this.renderRecStorage[a] = new RenderRecStorage();
}
}
/**
* Resets the mapping coordinates. Use when the texture has been resized.
*/
public function resetMapping():void
{
uvMatrices = new Dictionary();
}
//Local storage. Avoid var's in high usage functions.
private var x0:Number;
private var y0:Number;
private var x1:Number;
private var y1:Number;
private var x2:Number;
private var y2:Number;
/**
* drawTriangle
*/
override public function drawTriangle(face3D:Triangle3D, graphics:Graphics, renderSessionData:RenderSessionData, altBitmap:BitmapData = null, altUV:Matrix = null):void
{
if(!_precise){
if( lineAlpha )
graphics.lineStyle( lineThickness, lineColor, lineAlpha );
if( bitmap )
{
_triMap = altUV ? altUV : (uvMatrices[face3D] || transformUV(face3D));
x0 = face3D.v0.vertex3DInstance.x;
y0 = face3D.v0.vertex3DInstance.y;
x1 = face3D.v1.vertex3DInstance.x;
y1 = face3D.v1.vertex3DInstance.y;
x2 = face3D.v2.vertex3DInstance.x;
y2 = face3D.v2.vertex3DInstance.y;
_triMatrix.a = x1 - x0;
_triMatrix.b = y1 - y0;
_triMatrix.c = x2 - x0;
_triMatrix.d = y2 - y0;
_triMatrix.tx = x0;
_triMatrix.ty = y0;
_localMatrix.a = _triMap.a;
_localMatrix.b = _triMap.b;
_localMatrix.c = _triMap.c;
_localMatrix.d = _triMap.d;
_localMatrix.tx = _triMap.tx;
_localMatrix.ty = _triMap.ty;
_localMatrix.concat(_triMatrix);
graphics.beginBitmapFill( altBitmap ? altBitmap : bitmap, _localMatrix, tiled, smooth);
}
graphics.moveTo( x0, y0 );
graphics.lineTo( x1, y1 );
graphics.lineTo( x2, y2 );
graphics.lineTo( x0, y0 );
if( bitmap )
graphics.endFill();
if( lineAlpha )
graphics.lineStyle();
renderSessionData.renderStatistics.triangles++;
}else{
_triMap = altUV ? altUV : (uvMatrices[face3D] || transformUV(face3D));
focus = renderSessionData.camera.focus;
renderRec(graphics, _triMap, face3D.v0.vertex3DInstance, face3D.v1.vertex3DInstance, face3D.v2.vertex3DInstance, 0, renderSessionData, altBitmap ? altBitmap : bitmap);
}
}
/**
* Applies the updated UV texture mapping values to the triangle. This is required to speed up rendering.
*
*/
public function transformUV(face3D:Triangle3D):Matrix
{
if( ! face3D.uv )
{
Papervision3D.log( "MaterialObject3D: transformUV() uv not found!" );
}
else if( bitmap )
{
var uv :Array = face3D.uv;
var w :Number = bitmap.width * maxU;
var h :Number = bitmap.height * maxV;
var u0 :Number = w * face3D.uv0.u;
var v0 :Number = h * ( 1 - face3D.uv0.v );
var u1 :Number = w * face3D.uv1.u;
var v1 :Number = h * ( 1 - face3D.uv1.v);
var u2 :Number = w * face3D.uv2.u;
var v2 :Number = h * ( 1 - face3D.uv2.v );
// Fix perpendicular projections
if( (u0 == u1 && v0 == v1) || (u0 == u2 && v0 == v2) )
{
u0 -= (u0 > 0.05)? 0.05 : -0.05;
v0 -= (v0 > 0.07)? 0.07 : -0.07;
}
if( u2 == u1 && v2 == v1 )
{
u2 -= (u2 > 0.05)? 0.04 : -0.04;
v2 -= (v2 > 0.06)? 0.06 : -0.06;
}
// Precalculate matrix & correct for mip mapping
var at :Number = ( u1 - u0 );
var bt :Number = ( v1 - v0 );
var ct :Number = ( u2 - u0 );
var dt :Number = ( v2 - v0 );
var m :Matrix = new Matrix( at, bt, ct, dt, u0, v0 );
// Need to mirror over X-axis when righthanded
if(Papervision3D.useRIGHTHANDED)
{
m.scale(-1, 1);
m.translate(w, 0);
}
m.invert();
var mapping:Matrix = uvMatrices[face3D] ? uvMatrices[face3D] : uvMatrices[face3D] = m.clone();
mapping.a = m.a;
mapping.b = m.b;
mapping.c = m.c;
mapping.d = m.d;
mapping.tx = m.tx;
mapping.ty = m.ty;
}
else Papervision3D.log( "MaterialObject3D: transformUV() material.bitmap not found!" );
return mapping;
}
protected var ax:Number;
protected var ay:Number;
protected var az:Number;
protected var bx:Number;
protected var by:Number;
protected var bz:Number;
protected var cx:Number;
protected var cy:Number;
protected var cz:Number;
protected var faz:Number;
protected var fbz:Number;
protected var fcz:Number;
protected var mabz:Number;
protected var mbcz:Number;
protected var mcaz:Number;
protected var mabx:Number;
protected var maby:Number;
protected var mbcx:Number;
protected var mbcy:Number;
protected var mcax:Number;
protected var mcay:Number;
protected var dabx:Number;
protected var daby:Number;
protected var dbcx:Number;
protected var dbcy:Number;
protected var dcax:Number;
protected var dcay:Number;
protected var dsab:Number;
protected var dsbc:Number;
protected var dsca:Number;
protected function renderRec(graphics:Graphics, emMap:Matrix, v0:Vertex3DInstance, v1:Vertex3DInstance, v2:Vertex3DInstance, index:Number, renderSessionData:RenderSessionData, bitmap:BitmapData):void
{
az = v0.z;
bz = v1.z;
cz = v2.z;
//Cull if a vertex behind near.
if ((az <= 0) && (bz <= 0) && (cz <= 0))
return;
cx = v2.x;
cy = v2.y;
bx = v1.x;
by = v1.y;
ax = v0.x;
ay = v0.y;
//Cull if outside of viewport.
if(renderSessionData.viewPort.cullingRectangle){
hitRect.x = Math.min(cx, Math.min(bx, ax));
hitRect.width = Math.max(cx, Math.max(bx, ax)) + Math.abs(hitRect.x);
hitRect.y = Math.min(cy, Math.min(by, ay));
hitRect.height = Math.max(cy, Math.max(by, ay)) + Math.abs(hitRect.y);
if(!FastRectangleTools.intersects(hitRect, renderSessionData.viewPort.cullingRectangle)){
return;
}
}
//cull if max iterations is reached, focus is invalid or if tesselation is to small.
if (index >= 100 || (hitRect.width < minimumRenderSize) || (hitRect.height < minimumRenderSize) || (focus == Infinity))
{
renderTriangleBitmap(graphics,emMap,v0,v1,v2,smooth,tiled,bitmap);
renderSessionData.renderStatistics.triangles++;
return;
}
faz = focus + az;
fbz = focus + bz;
fcz = focus + cz;
mabz = 2 / (faz + fbz);
mbcz = 2 / (fbz + fcz);
mcaz = 2 / (fcz + faz);
mabx = (ax*faz + bx*fbz)*mabz;
maby = (ay*faz + by*fbz)*mabz;
mbcx = (bx*fbz + cx*fcz)*mbcz;
mbcy = (by*fbz + cy*fcz)*mbcz;
mcax = (cx*fcz + ax*faz)*mcaz;
mcay = (cy*fcz + ay*faz)*mcaz;
dabx = ax + bx - mabx;
daby = ay + by - maby;
dbcx = bx + cx - mbcx;
dbcy = by + cy - mbcy;
dcax = cx + ax - mcax;
dcay = cy + ay - mcay;
dsab = (dabx*dabx + daby*daby);
dsbc = (dbcx*dbcx + dbcy*dbcy);
dsca = (dcax*dcax + dcay*dcay);
var nIndex:int = index+1;
var nRss:RenderRecStorage = RenderRecStorage(renderRecStorage[int(index)]);
var renderRecMap:Matrix = nRss.mat;
if ((dsab <= _precision) && (dsca <= _precision) && (dsbc <= _precision)){
renderTriangleBitmap(graphics, emMap, v0,v1,v2, smooth, tiled,bitmap);
renderSessionData.renderStatistics.triangles++;
return;
}
if ((dsab > _precision) && (dsca > _precision) && (dsbc > _precision)){
renderRecMap.a = emMap.a*2;
renderRecMap.b = emMap.b*2;
renderRecMap.c = emMap.c*2;
renderRecMap.d = emMap.d*2;
renderRecMap.tx = emMap.tx*2;
renderRecMap.ty = emMap.ty*2;
nRss.v0.x = mabx * 0.5;
nRss.v0.y = maby * 0.5;
nRss.v0.z = (az+bz) * 0.5;
nRss.v1.x = mbcx * 0.5;
nRss.v1.y = mbcy * 0.5;
nRss.v1.z = (bz+cz) * 0.5;
nRss.v2.x = mcax * 0.5;
nRss.v2.y = mcay * 0.5;
nRss.v2.z = (cz+az) * 0.5;
renderRec(graphics, renderRecMap, v0, nRss.v0, nRss.v2, nIndex, renderSessionData, bitmap);
renderRecMap.tx -=1;
renderRec(graphics, renderRecMap, nRss.v0, v1, nRss.v1, nIndex, renderSessionData, bitmap);
renderRecMap.ty -=1;
renderRecMap.tx = emMap.tx*2;
renderRec(graphics, renderRecMap, nRss.v2, nRss.v1, v2, nIndex, renderSessionData, bitmap);
renderRecMap.a = -emMap.a*2;
renderRecMap.b = -emMap.b*2;
renderRecMap.c = -emMap.c*2;
renderRecMap.d = -emMap.d*2;
renderRecMap.tx = -emMap.tx*2+1;
renderRecMap.ty = -emMap.ty*2+1;
renderRec(graphics, renderRecMap, nRss.v1, nRss.v2, nRss.v0, nIndex, renderSessionData, bitmap);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -