mirror of
https://github.com/MapMakersAndProgrammers/TankiOnline2.0DemoClient.git
synced 2025-10-26 09:59:07 -07:00
Dirty patch to force Alternativa3D 8.32 into the game, definitely broken
This commit is contained in:
@@ -25,7 +25,7 @@ package
|
||||
import alternativa.tanks.game.entities.tank.graphics.materials.TankMaterial;
|
||||
import alternativa.tanks.game.entities.tank.graphics.materials.TankMaterial2;
|
||||
import alternativa.tanks.game.entities.tank.graphics.materials.TracksMaterial2;
|
||||
import alternativa.tanks.game.entities.tank.graphics.materials.TreesMaterial;
|
||||
import alternativa.engine3d.materials.StandardMaterial;
|
||||
import alternativa.tanks.game.subsystems.rendersystem.RenderSystem;
|
||||
import alternativa.utils.Properties;
|
||||
import flash.display.DisplayObject;
|
||||
@@ -42,7 +42,11 @@ package
|
||||
import platform.client.formats.a3d.osgi.Activator;
|
||||
import platform.clients.fp10.libraries.alternativaprotocol.Activator;
|
||||
import tankshudDemo.TanksHudDemo;
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
// This is so this class can access fog mode settings on materials
|
||||
use namespace alternativa3d;
|
||||
|
||||
[SWF(backgroundColor="#333333",frameRate="100",width="1024",height="768")]
|
||||
public class TanksTestingTool extends Sprite
|
||||
{
|
||||
@@ -81,13 +85,13 @@ package
|
||||
{
|
||||
switch(A3DUtils.getSupportedTextureFormat(this.stage3D.context3D))
|
||||
{
|
||||
case TextureFormat.DXT1:
|
||||
case A3DUtils.DXT1:
|
||||
this.loadConfig("cfg.dxt1.xml");
|
||||
break;
|
||||
case TextureFormat.ETC1:
|
||||
case A3DUtils.ETC1:
|
||||
this.loadConfig("cfg.etc1.xml");
|
||||
break;
|
||||
case TextureFormat.PVRTC:
|
||||
case A3DUtils.PVRTC:
|
||||
this.loadConfig("cfg.pvrtc.xml");
|
||||
}
|
||||
}
|
||||
@@ -108,12 +112,9 @@ package
|
||||
new ConsoleVarFloat("beam_fallof",170,0,180,this.onLightSettingsChange);
|
||||
new ConsoleVarFloat("beam_fallof",170,0,180,this.onLightSettingsChange);
|
||||
new ConsoleVarFloat("camera_smoothing",20,0,200,this.onControllerSettingsChange);
|
||||
MapMaterial.fogMode = MapMaterial.DISABLED;
|
||||
TreesMaterial.fogMode = TreesMaterial.DISABLED;
|
||||
StandardMaterial.fogMode = StandardMaterial.DISABLED;
|
||||
TankMaterial.fogMode = TankMaterial.DISABLED;
|
||||
TankMaterial2.fogMode = TankMaterial.DISABLED;
|
||||
GiShadowMaterial.fogMode = FogMode.DISABLED;
|
||||
TracksMaterial2.fogMode = FogMode.DISABLED;
|
||||
}
|
||||
|
||||
private function onControllerSettingsChange(param1:ConsoleVarFloat) : void
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package alternativa.engine3d
|
||||
{
|
||||
public namespace alternativa3d = "http://alternativaplatform.com/en/alternativa3d";
|
||||
}
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
package alternativa.engine3d.animation
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.keys.Track;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AnimationClip extends AnimationNode
|
||||
{
|
||||
alternativa3d var name_Kq:Array;
|
||||
|
||||
public var name:String;
|
||||
|
||||
public var loop:Boolean = true;
|
||||
|
||||
public var length:Number = 0;
|
||||
|
||||
public var animated:Boolean = true;
|
||||
|
||||
private var name_qC:Number = 0;
|
||||
|
||||
private var name_Iv:int = 0;
|
||||
|
||||
private var name_cT:Vector.<Track> = new Vector.<Track>();
|
||||
|
||||
private var name_Ci:AnimationNotify;
|
||||
|
||||
public function AnimationClip(name:String = null)
|
||||
{
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public function get objects() : Array
|
||||
{
|
||||
return this.name_Kq == null ? null : [].concat(this.name_Kq);
|
||||
}
|
||||
|
||||
public function set objects(value:Array) : void
|
||||
{
|
||||
this.updateObjects(this.name_Kq,alternativa3d::controller,value,alternativa3d::controller);
|
||||
this.name_Kq = value == null ? null : [].concat(value);
|
||||
}
|
||||
|
||||
override alternativa3d function setController(value:AnimationController) : void
|
||||
{
|
||||
this.updateObjects(this.name_Kq,alternativa3d::controller,this.name_Kq,value);
|
||||
this.alternativa3d::controller = value;
|
||||
}
|
||||
|
||||
private function addObject(object:Object) : void
|
||||
{
|
||||
if(this.name_Kq == null)
|
||||
{
|
||||
this.name_Kq = [object];
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_Kq.push(object);
|
||||
}
|
||||
if(alternativa3d::controller != null)
|
||||
{
|
||||
alternativa3d::controller.alternativa3d::addObject(object);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateObjects(oldObjects:Array, oldController:AnimationController, newObjects:Array, newController:AnimationController) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
if(oldController != null && oldObjects != null)
|
||||
{
|
||||
for(i = 0,count = int(this.name_Kq.length); i < count; i++)
|
||||
{
|
||||
oldController.alternativa3d::removeObject(oldObjects[i]);
|
||||
}
|
||||
}
|
||||
if(newController != null && newObjects != null)
|
||||
{
|
||||
for(i = 0,count = int(newObjects.length); i < count; i++)
|
||||
{
|
||||
newController.alternativa3d::addObject(newObjects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function updateLength() : void
|
||||
{
|
||||
var track:Track = null;
|
||||
var len:Number = NaN;
|
||||
for(var i:int = 0; i < this.name_Iv; )
|
||||
{
|
||||
track = this.name_cT[i];
|
||||
len = track.length;
|
||||
if(len > this.length)
|
||||
{
|
||||
this.length = len;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public function addTrack(track:Track) : Track
|
||||
{
|
||||
if(track == null)
|
||||
{
|
||||
throw new Error("Track can not be null");
|
||||
}
|
||||
var _loc2_:* = this.name_Iv++;
|
||||
this.name_cT[_loc2_] = track;
|
||||
if(track.length > this.length)
|
||||
{
|
||||
this.length = track.length;
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
public function removeTrack(track:Track) : Track
|
||||
{
|
||||
var t:Track = null;
|
||||
var index:int = int(this.name_cT.indexOf(track));
|
||||
if(index < 0)
|
||||
{
|
||||
throw new ArgumentError("Track not found");
|
||||
}
|
||||
--this.name_Iv;
|
||||
for(var j:int = index + 1; index < this.name_Iv; )
|
||||
{
|
||||
this.name_cT[index] = this.name_cT[j];
|
||||
index++;
|
||||
j++;
|
||||
}
|
||||
this.name_cT.length = this.name_Iv;
|
||||
this.length = 0;
|
||||
for(var i:int = 0; i < this.name_Iv; )
|
||||
{
|
||||
t = this.name_cT[i];
|
||||
if(t.length > this.length)
|
||||
{
|
||||
this.length = t.length;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
public function getTrackAt(index:int) : Track
|
||||
{
|
||||
return this.name_cT[index];
|
||||
}
|
||||
|
||||
public function get numTracks() : int
|
||||
{
|
||||
return this.name_Iv;
|
||||
}
|
||||
|
||||
override alternativa3d function update(interval:Number, weight:Number) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var track:Track = null;
|
||||
var state:AnimationState = null;
|
||||
var oldTime:Number = this.name_qC;
|
||||
if(this.animated)
|
||||
{
|
||||
this.name_qC += interval * speed;
|
||||
if(this.loop)
|
||||
{
|
||||
if(this.name_qC < 0)
|
||||
{
|
||||
this.name_qC = 0;
|
||||
}
|
||||
else if(this.name_qC >= this.length)
|
||||
{
|
||||
this.alternativa3d::collectNotifiers(oldTime,this.length);
|
||||
this.name_qC = this.length <= 0 ? 0 : this.name_qC % this.length;
|
||||
this.alternativa3d::collectNotifiers(0,this.name_qC);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::collectNotifiers(oldTime,this.name_qC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.name_qC < 0)
|
||||
{
|
||||
this.name_qC = 0;
|
||||
}
|
||||
else if(this.name_qC >= this.length)
|
||||
{
|
||||
this.name_qC = this.length;
|
||||
}
|
||||
this.alternativa3d::collectNotifiers(oldTime,this.name_qC);
|
||||
}
|
||||
}
|
||||
if(weight > 0)
|
||||
{
|
||||
for(i = 0; i < this.name_Iv; )
|
||||
{
|
||||
track = this.name_cT[i];
|
||||
if(track.object != null)
|
||||
{
|
||||
state = alternativa3d::controller.alternativa3d::getState(track.object);
|
||||
if(state != null)
|
||||
{
|
||||
track.alternativa3d::blend(this.name_qC,weight,state);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get time() : Number
|
||||
{
|
||||
return this.name_qC;
|
||||
}
|
||||
|
||||
public function set time(value:Number) : void
|
||||
{
|
||||
this.name_qC = value;
|
||||
}
|
||||
|
||||
public function get normalizedTime() : Number
|
||||
{
|
||||
return this.length == 0 ? 0 : this.name_qC / this.length;
|
||||
}
|
||||
|
||||
public function set normalizedTime(value:Number) : void
|
||||
{
|
||||
this.name_qC = value * this.length;
|
||||
}
|
||||
|
||||
private function getNumChildren(object:Object) : int
|
||||
{
|
||||
if(object is Object3D)
|
||||
{
|
||||
return Object3D(object).numChildren;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function getChildAt(object:Object, index:int) : Object
|
||||
{
|
||||
if(object is Object3D)
|
||||
{
|
||||
return Object3D(object).getChildAt(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function addChildren(object:Object) : void
|
||||
{
|
||||
var child:Object = null;
|
||||
for(var i:int = 0, numChildren:int = this.getNumChildren(object); i < numChildren; i++)
|
||||
{
|
||||
child = this.getChildAt(object,i);
|
||||
this.addObject(child);
|
||||
this.addChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
public function attach(object:Object, includeDescendants:Boolean) : void
|
||||
{
|
||||
this.updateObjects(this.name_Kq,alternativa3d::controller,null,alternativa3d::controller);
|
||||
this.name_Kq = null;
|
||||
this.addObject(object);
|
||||
if(includeDescendants)
|
||||
{
|
||||
this.addChildren(object);
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function collectNotifiers(start:Number, end:Number) : void
|
||||
{
|
||||
for(var notify:AnimationNotify = this.name_Ci; notify != null; )
|
||||
{
|
||||
if(notify.name_qC > start)
|
||||
{
|
||||
if(notify.name_qC > end)
|
||||
{
|
||||
notify = notify.alternativa3d::next;
|
||||
continue;
|
||||
}
|
||||
notify.name_XY = alternativa3d::controller.alternativa3d::nearestNotifyers;
|
||||
alternativa3d::controller.alternativa3d::nearestNotifyers = notify;
|
||||
}
|
||||
notify = notify.alternativa3d::next;
|
||||
}
|
||||
}
|
||||
|
||||
public function addNotify(time:Number, name:String = null) : AnimationNotify
|
||||
{
|
||||
var _loc4_:AnimationNotify = null;
|
||||
time = time <= 0 ? 0 : (time >= this.length ? this.length : time);
|
||||
var notify:AnimationNotify = new AnimationNotify(name);
|
||||
notify.name_qC = time;
|
||||
if(this.name_Ci == null)
|
||||
{
|
||||
this.name_Ci = notify;
|
||||
return notify;
|
||||
}
|
||||
if(this.name_Ci.name_qC > time)
|
||||
{
|
||||
notify.alternativa3d::next = this.name_Ci;
|
||||
this.name_Ci = notify;
|
||||
return notify;
|
||||
}
|
||||
_loc4_ = this.name_Ci;
|
||||
while(_loc4_.alternativa3d::next != null && _loc4_.alternativa3d::next.name_qC <= time)
|
||||
{
|
||||
_loc4_ = _loc4_.alternativa3d::next;
|
||||
}
|
||||
if(_loc4_.alternativa3d::next == null)
|
||||
{
|
||||
_loc4_.alternativa3d::next = notify;
|
||||
}
|
||||
else
|
||||
{
|
||||
notify.alternativa3d::next = _loc4_.alternativa3d::next;
|
||||
_loc4_.alternativa3d::next = notify;
|
||||
}
|
||||
return notify;
|
||||
}
|
||||
|
||||
public function addNotifyAtEnd(offsetFromEnd:Number = 0, name:String = null) : AnimationNotify
|
||||
{
|
||||
return this.addNotify(this.length - offsetFromEnd,name);
|
||||
}
|
||||
|
||||
public function removeNotify(notify:AnimationNotify) : AnimationNotify
|
||||
{
|
||||
var n:AnimationNotify = null;
|
||||
if(this.name_Ci != null)
|
||||
{
|
||||
if(this.name_Ci == notify)
|
||||
{
|
||||
this.name_Ci = this.name_Ci.alternativa3d::next;
|
||||
return notify;
|
||||
}
|
||||
n = this.name_Ci;
|
||||
while(n.alternativa3d::next != null && n.alternativa3d::next != notify)
|
||||
{
|
||||
n = n.alternativa3d::next;
|
||||
}
|
||||
if(n.alternativa3d::next == notify)
|
||||
{
|
||||
n.alternativa3d::next = notify.alternativa3d::next;
|
||||
return notify;
|
||||
}
|
||||
}
|
||||
throw new Error("Notify not found");
|
||||
}
|
||||
|
||||
public function get notifiers() : Vector.<AnimationNotify>
|
||||
{
|
||||
var result:Vector.<AnimationNotify> = new Vector.<AnimationNotify>();
|
||||
var i:int = 0;
|
||||
for(var notify:AnimationNotify = this.name_Ci; notify != null; notify = notify.alternativa3d::next)
|
||||
{
|
||||
result[i] = notify;
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public function slice(start:Number, end:Number = 1.7976931348623157e+308) : AnimationClip
|
||||
{
|
||||
var sliced:AnimationClip = new AnimationClip(this.name);
|
||||
sliced.name_Kq = this.name_Kq == null ? null : [].concat(this.name_Kq);
|
||||
for(var i:int = 0; i < this.name_Iv; i++)
|
||||
{
|
||||
sliced.addTrack(this.name_cT[i].slice(start,end));
|
||||
}
|
||||
return sliced;
|
||||
}
|
||||
|
||||
public function clone() : AnimationClip
|
||||
{
|
||||
var cloned:AnimationClip = new AnimationClip(this.name);
|
||||
cloned.name_Kq = this.name_Kq == null ? null : [].concat(this.name_Kq);
|
||||
for(var i:int = 0; i < this.name_Iv; i++)
|
||||
{
|
||||
cloned.addTrack(this.name_cT[i]);
|
||||
}
|
||||
cloned.length = this.length;
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
package alternativa.engine3d.animation
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.events.NotifyEvent;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getTimer;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AnimationController
|
||||
{
|
||||
private var name_cn:AnimationNode;
|
||||
|
||||
private var name_Kq:Vector.<Object>;
|
||||
|
||||
private var name_62:Vector.<Object3D> = new Vector.<Object3D>();
|
||||
|
||||
private var name_oX:Dictionary = new Dictionary();
|
||||
|
||||
private var name_eB:Object = new Object();
|
||||
|
||||
private var name_Jl:int = -1;
|
||||
|
||||
alternativa3d var nearestNotifyers:AnimationNotify;
|
||||
|
||||
public function AnimationController()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function get root() : AnimationNode
|
||||
{
|
||||
return this.name_cn;
|
||||
}
|
||||
|
||||
public function set root(value:AnimationNode) : void
|
||||
{
|
||||
if(this.name_cn != value)
|
||||
{
|
||||
if(this.name_cn != null)
|
||||
{
|
||||
this.name_cn.alternativa3d::setController(null);
|
||||
this.name_cn.name_Eo = false;
|
||||
}
|
||||
if(value != null)
|
||||
{
|
||||
value.alternativa3d::setController(this);
|
||||
value.name_Eo = true;
|
||||
}
|
||||
this.name_cn = value;
|
||||
}
|
||||
}
|
||||
|
||||
public function update() : void
|
||||
{
|
||||
var interval:Number = NaN;
|
||||
var data:AnimationState = null;
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var _loc6_:int = 0;
|
||||
var object:Object3D = null;
|
||||
if(this.name_Jl < 0)
|
||||
{
|
||||
this.name_Jl = getTimer();
|
||||
interval = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc6_ = int(getTimer());
|
||||
interval = 0.001 * (_loc6_ - this.name_Jl);
|
||||
this.name_Jl = _loc6_;
|
||||
}
|
||||
if(this.name_cn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for each(data in this.name_eB)
|
||||
{
|
||||
data.reset();
|
||||
}
|
||||
this.name_cn.alternativa3d::update(interval,1);
|
||||
for(i = 0,count = int(this.name_62.length); i < count; )
|
||||
{
|
||||
object = this.name_62[i];
|
||||
data = this.name_eB[object.name];
|
||||
if(data != null)
|
||||
{
|
||||
data.apply(object);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for(var notify:AnimationNotify = this.alternativa3d::nearestNotifyers; notify != null; )
|
||||
{
|
||||
if(notify.willTrigger(NotifyEvent.NOTIFY))
|
||||
{
|
||||
notify.dispatchEvent(new NotifyEvent(notify));
|
||||
}
|
||||
notify = notify.name_XY;
|
||||
}
|
||||
this.alternativa3d::nearestNotifyers = null;
|
||||
}
|
||||
|
||||
alternativa3d function addObject(object:Object) : void
|
||||
{
|
||||
if(object in this.name_oX)
|
||||
{
|
||||
this.name_oX[object]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(object is Object3D)
|
||||
{
|
||||
this.name_62.push(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_Kq.push(object);
|
||||
}
|
||||
this.name_oX[object] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function removeObject(object:Object) : void
|
||||
{
|
||||
var index:int = 0;
|
||||
var j:int = 0;
|
||||
var count:int = 0;
|
||||
var used:int = int(this.name_oX[object]);
|
||||
used--;
|
||||
if(used <= 0)
|
||||
{
|
||||
if(object is Object3D)
|
||||
{
|
||||
index = int(this.name_62.indexOf(object as Object3D));
|
||||
count = this.name_62.length - 1;
|
||||
for(j = index + 1; index < count; )
|
||||
{
|
||||
this.name_62[index] = this.name_62[j];
|
||||
index++;
|
||||
j++;
|
||||
}
|
||||
this.name_62.length = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = int(this.name_Kq.indexOf(object));
|
||||
count = this.name_Kq.length - 1;
|
||||
for(j = index + 1; index < count; )
|
||||
{
|
||||
this.name_Kq[index] = this.name_Kq[j];
|
||||
index++;
|
||||
j++;
|
||||
}
|
||||
this.name_Kq.length = count;
|
||||
}
|
||||
delete this.name_oX[object];
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_oX[object] = used;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function getState(name:String) : AnimationState
|
||||
{
|
||||
var state:AnimationState = this.name_eB[name];
|
||||
if(state == null)
|
||||
{
|
||||
state = new AnimationState();
|
||||
this.name_eB[name] = state;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public function freeze() : void
|
||||
{
|
||||
this.name_Jl = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package alternativa.engine3d.animation
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AnimationNode
|
||||
{
|
||||
alternativa3d var name_Eo:Boolean = false;
|
||||
|
||||
alternativa3d var _parent:AnimationNode;
|
||||
|
||||
alternativa3d var controller:AnimationController;
|
||||
|
||||
public var speed:Number = 1;
|
||||
|
||||
public function AnimationNode()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function get isActive() : Boolean
|
||||
{
|
||||
return this.name_Eo && this.alternativa3d::controller != null;
|
||||
}
|
||||
|
||||
public function get parent() : AnimationNode
|
||||
{
|
||||
return this.alternativa3d::_parent;
|
||||
}
|
||||
|
||||
alternativa3d function update(elapsed:Number, weight:Number) : void
|
||||
{
|
||||
}
|
||||
|
||||
alternativa3d function setController(value:AnimationController) : void
|
||||
{
|
||||
this.alternativa3d::controller = value;
|
||||
}
|
||||
|
||||
alternativa3d function addNode(node:AnimationNode) : void
|
||||
{
|
||||
if(node.alternativa3d::_parent != null)
|
||||
{
|
||||
node.alternativa3d::_parent.alternativa3d::removeNode(node);
|
||||
}
|
||||
node.alternativa3d::_parent = this;
|
||||
node.alternativa3d::setController(this.alternativa3d::controller);
|
||||
}
|
||||
|
||||
alternativa3d function removeNode(node:AnimationNode) : void
|
||||
{
|
||||
node.alternativa3d::setController(null);
|
||||
node.name_Eo = false;
|
||||
node.alternativa3d::_parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package alternativa.engine3d.animation
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.events.EventDispatcher;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AnimationNotify extends EventDispatcher
|
||||
{
|
||||
public var name:String;
|
||||
|
||||
alternativa3d var name_qC:Number = 0;
|
||||
|
||||
alternativa3d var next:AnimationNotify;
|
||||
|
||||
alternativa3d var name_1n:Number;
|
||||
|
||||
alternativa3d var name_XY:AnimationNotify;
|
||||
|
||||
public function AnimationNotify(name:String)
|
||||
{
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public function get time() : Number
|
||||
{
|
||||
return this.name_qC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
package alternativa.engine3d.animation
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.keys.TransformKey;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AnimationState
|
||||
{
|
||||
public var name_6V:int = 0;
|
||||
|
||||
public var transform:TransformKey = new TransformKey();
|
||||
|
||||
public var name_H1:Number = 0;
|
||||
|
||||
public var numbers:Object = new Object();
|
||||
|
||||
public var name_NT:Object = new Object();
|
||||
|
||||
public function AnimationState()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function reset() : void
|
||||
{
|
||||
var key:String = null;
|
||||
this.name_H1 = 0;
|
||||
for(key in this.numbers)
|
||||
{
|
||||
delete this.numbers[key];
|
||||
delete this.name_NT[key];
|
||||
}
|
||||
}
|
||||
|
||||
public function addWeightedTransform(key:TransformKey, weight:Number) : void
|
||||
{
|
||||
this.name_H1 += weight;
|
||||
this.transform.interpolate(this.transform,key,weight / this.name_H1);
|
||||
}
|
||||
|
||||
public function addWeightedNumber(property:String, value:Number, weight:Number) : void
|
||||
{
|
||||
var current:Number = NaN;
|
||||
var sum:Number = Number(this.name_NT[property]);
|
||||
if(sum == sum)
|
||||
{
|
||||
sum += weight;
|
||||
weight /= sum;
|
||||
current = Number(this.numbers[property]);
|
||||
this.numbers[property] = (1 - weight) * current + weight * value;
|
||||
this.name_NT[property] = sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.numbers[property] = value;
|
||||
this.name_NT[property] = weight;
|
||||
}
|
||||
}
|
||||
|
||||
public function apply(object:Object3D) : void
|
||||
{
|
||||
var sum:Number = NaN;
|
||||
var weight:Number = NaN;
|
||||
var key:String = null;
|
||||
if(this.name_H1 > 0)
|
||||
{
|
||||
object.x = this.transform.alternativa3d::x;
|
||||
object.y = this.transform.alternativa3d::y;
|
||||
object.z = this.transform.alternativa3d::z;
|
||||
this.setEulerAngles(this.transform.alternativa3d::rotation,object);
|
||||
object.scaleX = this.transform.alternativa3d::scaleX;
|
||||
object.scaleY = this.transform.alternativa3d::scaleY;
|
||||
object.scaleZ = this.transform.alternativa3d::scaleZ;
|
||||
}
|
||||
for(key in this.numbers)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case "x":
|
||||
sum = Number(this.name_NT["x"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.x = (1 - weight) * object.x + weight * this.numbers["x"];
|
||||
break;
|
||||
case "y":
|
||||
sum = Number(this.name_NT["y"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.y = (1 - weight) * object.y + weight * this.numbers["y"];
|
||||
break;
|
||||
case "z":
|
||||
sum = Number(this.name_NT["z"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.z = (1 - weight) * object.z + weight * this.numbers["z"];
|
||||
break;
|
||||
case "rotationX":
|
||||
sum = Number(this.name_NT["rotationX"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationX = (1 - weight) * object.rotationX + weight * this.numbers["rotationX"];
|
||||
break;
|
||||
case "rotationY":
|
||||
sum = Number(this.name_NT["rotationY"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationY = (1 - weight) * object.rotationY + weight * this.numbers["rotationY"];
|
||||
break;
|
||||
case "rotationZ":
|
||||
sum = Number(this.name_NT["rotationZ"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationZ = (1 - weight) * object.rotationZ + weight * this.numbers["rotationZ"];
|
||||
break;
|
||||
case "scaleX":
|
||||
sum = Number(this.name_NT["scaleX"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleX = (1 - weight) * object.scaleX + weight * this.numbers["scaleX"];
|
||||
break;
|
||||
case "scaleY":
|
||||
sum = Number(this.name_NT["scaleY"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleY = (1 - weight) * object.scaleY + weight * this.numbers["scaleY"];
|
||||
break;
|
||||
case "scaleZ":
|
||||
sum = Number(this.name_NT["scaleZ"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleZ = (1 - weight) * object.scaleZ + weight * this.numbers["scaleZ"];
|
||||
break;
|
||||
default:
|
||||
object[key] = this.numbers[key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function applyObject(object:Object) : void
|
||||
{
|
||||
var sum:Number = NaN;
|
||||
var weight:Number = NaN;
|
||||
var key:String = null;
|
||||
if(this.name_H1 > 0)
|
||||
{
|
||||
object.x = this.transform.alternativa3d::x;
|
||||
object.y = this.transform.alternativa3d::y;
|
||||
object.z = this.transform.alternativa3d::z;
|
||||
this.setEulerAnglesObject(this.transform.alternativa3d::rotation,object);
|
||||
object.scaleX = this.transform.alternativa3d::scaleX;
|
||||
object.scaleY = this.transform.alternativa3d::scaleY;
|
||||
object.scaleZ = this.transform.alternativa3d::scaleZ;
|
||||
}
|
||||
for(key in this.numbers)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case "x":
|
||||
sum = Number(this.name_NT["x"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.x = (1 - weight) * object.x + weight * this.numbers["x"];
|
||||
break;
|
||||
case "y":
|
||||
sum = Number(this.name_NT["y"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.y = (1 - weight) * object.y + weight * this.numbers["y"];
|
||||
break;
|
||||
case "z":
|
||||
sum = Number(this.name_NT["z"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.z = (1 - weight) * object.z + weight * this.numbers["z"];
|
||||
break;
|
||||
case "rotationX":
|
||||
sum = Number(this.name_NT["rotationX"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationX = (1 - weight) * object.rotationX + weight * this.numbers["rotationX"];
|
||||
break;
|
||||
case "rotationY":
|
||||
sum = Number(this.name_NT["rotationY"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationY = (1 - weight) * object.rotationY + weight * this.numbers["rotationY"];
|
||||
break;
|
||||
case "rotationZ":
|
||||
sum = Number(this.name_NT["rotationZ"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.rotationZ = (1 - weight) * object.rotationZ + weight * this.numbers["rotationZ"];
|
||||
break;
|
||||
case "scaleX":
|
||||
sum = Number(this.name_NT["scaleX"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleX = (1 - weight) * object.scaleX + weight * this.numbers["scaleX"];
|
||||
break;
|
||||
case "scaleY":
|
||||
sum = Number(this.name_NT["scaleY"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleY = (1 - weight) * object.scaleY + weight * this.numbers["scaleY"];
|
||||
break;
|
||||
case "scaleZ":
|
||||
sum = Number(this.name_NT["scaleZ"]);
|
||||
weight = sum / (sum + this.name_H1);
|
||||
object.scaleZ = (1 - weight) * object.scaleZ + weight * this.numbers["scaleZ"];
|
||||
break;
|
||||
default:
|
||||
object[key] = this.numbers[key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setEulerAngles(quat:Vector3D, object:Object3D) : void
|
||||
{
|
||||
var qi2:Number = 2 * quat.x * quat.x;
|
||||
var qj2:Number = 2 * quat.y * quat.y;
|
||||
var qk2:Number = 2 * quat.z * quat.z;
|
||||
var qij:Number = 2 * quat.x * quat.y;
|
||||
var qjk:Number = 2 * quat.y * quat.z;
|
||||
var qki:Number = 2 * quat.z * quat.x;
|
||||
var qri:Number = 2 * quat.w * quat.x;
|
||||
var qrj:Number = 2 * quat.w * quat.y;
|
||||
var qrk:Number = 2 * quat.w * quat.z;
|
||||
var aa:Number = 1 - qj2 - qk2;
|
||||
var bb:Number = qij - qrk;
|
||||
var ee:Number = qij + qrk;
|
||||
var ff:Number = 1 - qi2 - qk2;
|
||||
var ii:Number = qki - qrj;
|
||||
var jj:Number = qjk + qri;
|
||||
var kk:Number = 1 - qi2 - qj2;
|
||||
if(-1 < ii && ii < 1)
|
||||
{
|
||||
object.rotationX = Math.atan2(jj,kk);
|
||||
object.rotationY = -Math.asin(ii);
|
||||
object.rotationZ = Math.atan2(ee,aa);
|
||||
}
|
||||
else
|
||||
{
|
||||
object.rotationX = 0;
|
||||
object.rotationY = ii <= -1 ? Number(Math.PI) : -Math.PI;
|
||||
object.rotationY *= 0.5;
|
||||
object.rotationZ = Math.atan2(-bb,ff);
|
||||
}
|
||||
}
|
||||
|
||||
private function setEulerAnglesObject(quat:Vector3D, object:Object) : void
|
||||
{
|
||||
var qi2:Number = 2 * quat.x * quat.x;
|
||||
var qj2:Number = 2 * quat.y * quat.y;
|
||||
var qk2:Number = 2 * quat.z * quat.z;
|
||||
var qij:Number = 2 * quat.x * quat.y;
|
||||
var qjk:Number = 2 * quat.y * quat.z;
|
||||
var qki:Number = 2 * quat.z * quat.x;
|
||||
var qri:Number = 2 * quat.w * quat.x;
|
||||
var qrj:Number = 2 * quat.w * quat.y;
|
||||
var qrk:Number = 2 * quat.w * quat.z;
|
||||
var aa:Number = 1 - qj2 - qk2;
|
||||
var bb:Number = qij - qrk;
|
||||
var ee:Number = qij + qrk;
|
||||
var ff:Number = 1 - qi2 - qk2;
|
||||
var ii:Number = qki - qrj;
|
||||
var jj:Number = qjk + qri;
|
||||
var kk:Number = 1 - qi2 - qj2;
|
||||
if(-1 < ii && ii < 1)
|
||||
{
|
||||
object.rotationX = Math.atan2(jj,kk);
|
||||
object.rotationY = -Math.asin(ii);
|
||||
object.rotationZ = Math.atan2(ee,aa);
|
||||
}
|
||||
else
|
||||
{
|
||||
object.rotationX = 0;
|
||||
object.rotationY = ii <= -1 ? Math.PI : -Math.PI;
|
||||
object.rotationY *= 0.5;
|
||||
object.rotationZ = Math.atan2(-bb,ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package alternativa.engine3d.animation.events
|
||||
{
|
||||
import alternativa.engine3d.animation.AnimationNotify;
|
||||
import flash.events.Event;
|
||||
|
||||
public class NotifyEvent extends Event
|
||||
{
|
||||
public static const NOTIFY:String = "notify";
|
||||
|
||||
public function NotifyEvent(notify:AnimationNotify)
|
||||
{
|
||||
super(NOTIFY);
|
||||
}
|
||||
|
||||
public function get notify() : AnimationNotify
|
||||
{
|
||||
return AnimationNotify(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Keyframe
|
||||
{
|
||||
alternativa3d var name_qC:Number = 0;
|
||||
|
||||
public function Keyframe()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function get time() : Number
|
||||
{
|
||||
return this.name_qC;
|
||||
}
|
||||
|
||||
public function get value() : Object
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function set value(v:Object) : void
|
||||
{
|
||||
}
|
||||
|
||||
alternativa3d function get nextKeyFrame() : Keyframe
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
alternativa3d function set nextKeyFrame(value:Keyframe) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[Keyframe time = " + this.name_qC.toFixed(2) + " value = " + this.value + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class NumberKey extends Keyframe
|
||||
{
|
||||
alternativa3d var name_4O:Number = 0;
|
||||
|
||||
alternativa3d var next:NumberKey;
|
||||
|
||||
public function NumberKey()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function interpolate(a:NumberKey, b:NumberKey, c:Number) : void
|
||||
{
|
||||
this.name_4O = (1 - c) * a.name_4O + c * b.name_4O;
|
||||
}
|
||||
|
||||
override public function get value() : Object
|
||||
{
|
||||
return this.name_4O;
|
||||
}
|
||||
|
||||
override public function set value(v:Object) : void
|
||||
{
|
||||
this.name_4O = Number(v);
|
||||
}
|
||||
|
||||
override alternativa3d function get nextKeyFrame() : Keyframe
|
||||
{
|
||||
return this.alternativa3d::next;
|
||||
}
|
||||
|
||||
override alternativa3d function set nextKeyFrame(value:Keyframe) : void
|
||||
{
|
||||
this.alternativa3d::next = NumberKey(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.AnimationState;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class NumberTrack extends Track
|
||||
{
|
||||
private static var temp:NumberKey = new NumberKey();
|
||||
|
||||
alternativa3d var name_ku:NumberKey;
|
||||
|
||||
public var property:String;
|
||||
|
||||
public function NumberTrack(object:String, property:String)
|
||||
{
|
||||
super();
|
||||
this.property = property;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
override alternativa3d function get keyFramesList() : Keyframe
|
||||
{
|
||||
return this.name_ku;
|
||||
}
|
||||
|
||||
override alternativa3d function set keyFramesList(value:Keyframe) : void
|
||||
{
|
||||
this.name_ku = NumberKey(value);
|
||||
}
|
||||
|
||||
public function addKey(time:Number, value:Number = 0) : Keyframe
|
||||
{
|
||||
var key:NumberKey = new NumberKey();
|
||||
key.name_qC = time;
|
||||
key.value = value;
|
||||
alternativa3d::addKeyToList(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
override alternativa3d function blend(time:Number, weight:Number, state:AnimationState) : void
|
||||
{
|
||||
var prev:NumberKey = null;
|
||||
if(this.property == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var next:NumberKey = this.name_ku;
|
||||
while(next != null && next.name_qC < time)
|
||||
{
|
||||
prev = next;
|
||||
next = next.alternativa3d::next;
|
||||
}
|
||||
if(prev != null)
|
||||
{
|
||||
if(next != null)
|
||||
{
|
||||
temp.interpolate(prev,next,(time - prev.name_qC) / (next.name_qC - prev.name_qC));
|
||||
state.addWeightedNumber(this.property,temp.name_4O,weight);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.addWeightedNumber(this.property,prev.name_4O,weight);
|
||||
}
|
||||
}
|
||||
else if(next != null)
|
||||
{
|
||||
state.addWeightedNumber(this.property,next.name_4O,weight);
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function createKeyFrame() : Keyframe
|
||||
{
|
||||
return new NumberKey();
|
||||
}
|
||||
|
||||
override alternativa3d function interpolateKeyFrame(dest:Keyframe, a:Keyframe, b:Keyframe, value:Number) : void
|
||||
{
|
||||
NumberKey(dest).interpolate(NumberKey(a),NumberKey(b),value);
|
||||
}
|
||||
|
||||
override public function slice(start:Number, end:Number = 1.7976931348623157e+308) : Track
|
||||
{
|
||||
var track:NumberTrack = new NumberTrack(object,this.property);
|
||||
alternativa3d::sliceImplementation(track,start,end);
|
||||
return track;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.AnimationState;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Track
|
||||
{
|
||||
public var object:String;
|
||||
|
||||
alternativa3d var name_YC:Number = 0;
|
||||
|
||||
public function Track()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function get length() : Number
|
||||
{
|
||||
return this.name_YC;
|
||||
}
|
||||
|
||||
alternativa3d function get keyFramesList() : Keyframe
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
alternativa3d function set keyFramesList(value:Keyframe) : void
|
||||
{
|
||||
}
|
||||
|
||||
alternativa3d function addKeyToList(key:Keyframe) : void
|
||||
{
|
||||
var _loc3_:Keyframe = null;
|
||||
var time:Number = key.name_qC;
|
||||
if(this.alternativa3d::keyFramesList == null)
|
||||
{
|
||||
this.alternativa3d::keyFramesList = key;
|
||||
this.name_YC = time <= 0 ? 0 : time;
|
||||
return;
|
||||
}
|
||||
if(this.alternativa3d::keyFramesList.name_qC > time)
|
||||
{
|
||||
key.alternativa3d::nextKeyFrame = this.alternativa3d::keyFramesList;
|
||||
this.alternativa3d::keyFramesList = key;
|
||||
return;
|
||||
}
|
||||
_loc3_ = this.alternativa3d::keyFramesList;
|
||||
while(_loc3_.alternativa3d::nextKeyFrame != null && _loc3_.alternativa3d::nextKeyFrame.name_qC <= time)
|
||||
{
|
||||
_loc3_ = _loc3_.alternativa3d::nextKeyFrame;
|
||||
}
|
||||
if(_loc3_.alternativa3d::nextKeyFrame == null)
|
||||
{
|
||||
_loc3_.alternativa3d::nextKeyFrame = key;
|
||||
this.name_YC = time <= 0 ? 0 : time;
|
||||
}
|
||||
else
|
||||
{
|
||||
key.alternativa3d::nextKeyFrame = _loc3_.alternativa3d::nextKeyFrame;
|
||||
_loc3_.alternativa3d::nextKeyFrame = key;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeKey(key:Keyframe) : Keyframe
|
||||
{
|
||||
var k:Keyframe = null;
|
||||
if(this.alternativa3d::keyFramesList != null)
|
||||
{
|
||||
if(this.alternativa3d::keyFramesList == key)
|
||||
{
|
||||
this.alternativa3d::keyFramesList = this.alternativa3d::keyFramesList.alternativa3d::nextKeyFrame;
|
||||
if(this.alternativa3d::keyFramesList == null)
|
||||
{
|
||||
this.name_YC = 0;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
k = this.alternativa3d::keyFramesList;
|
||||
while(k.alternativa3d::nextKeyFrame != null && k.alternativa3d::nextKeyFrame != key)
|
||||
{
|
||||
k = k.alternativa3d::nextKeyFrame;
|
||||
}
|
||||
if(k.alternativa3d::nextKeyFrame == key)
|
||||
{
|
||||
if(key.alternativa3d::nextKeyFrame == null)
|
||||
{
|
||||
this.name_YC = k.name_qC <= 0 ? 0 : k.name_qC;
|
||||
}
|
||||
k.alternativa3d::nextKeyFrame = key.alternativa3d::nextKeyFrame;
|
||||
return key;
|
||||
}
|
||||
}
|
||||
throw new Error("Key not found");
|
||||
}
|
||||
|
||||
public function get keys() : Vector.<Keyframe>
|
||||
{
|
||||
var result:Vector.<Keyframe> = new Vector.<Keyframe>();
|
||||
var i:int = 0;
|
||||
for(var key:Keyframe = this.alternativa3d::keyFramesList; key != null; key = key.alternativa3d::nextKeyFrame)
|
||||
{
|
||||
result[i] = key;
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
alternativa3d function blend(time:Number, weight:Number, state:AnimationState) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function slice(start:Number, end:Number = 1.7976931348623157e+308) : Track
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
alternativa3d function createKeyFrame() : Keyframe
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
alternativa3d function interpolateKeyFrame(dest:Keyframe, a:Keyframe, b:Keyframe, value:Number) : void
|
||||
{
|
||||
}
|
||||
|
||||
alternativa3d function sliceImplementation(dest:Track, start:Number, end:Number) : void
|
||||
{
|
||||
var prev:Keyframe = null;
|
||||
var nextKey:Keyframe = null;
|
||||
var shiftTime:Number = start > 0 ? start : 0;
|
||||
var next:Keyframe = this.alternativa3d::keyFramesList;
|
||||
var key:Keyframe = this.alternativa3d::createKeyFrame();
|
||||
while(next != null && next.name_qC <= start)
|
||||
{
|
||||
prev = next;
|
||||
next = next.alternativa3d::nextKeyFrame;
|
||||
}
|
||||
if(prev != null)
|
||||
{
|
||||
if(next != null)
|
||||
{
|
||||
this.alternativa3d::interpolateKeyFrame(key,prev,next,(start - prev.name_qC) / (next.name_qC - prev.name_qC));
|
||||
key.name_qC = start - shiftTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::interpolateKeyFrame(key,key,prev,1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(next == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.alternativa3d::interpolateKeyFrame(key,key,next,1);
|
||||
key.name_qC = next.name_qC - shiftTime;
|
||||
prev = next;
|
||||
next = next.alternativa3d::nextKeyFrame;
|
||||
}
|
||||
dest.alternativa3d::keyFramesList = key;
|
||||
if(next == null || end <= start)
|
||||
{
|
||||
dest.name_YC = key.name_qC <= 0 ? 0 : key.name_qC;
|
||||
return;
|
||||
}
|
||||
while(next != null && next.name_qC <= end)
|
||||
{
|
||||
nextKey = this.alternativa3d::createKeyFrame();
|
||||
this.alternativa3d::interpolateKeyFrame(nextKey,nextKey,next,1);
|
||||
nextKey.name_qC = next.name_qC - shiftTime;
|
||||
key.alternativa3d::nextKeyFrame = nextKey;
|
||||
key = nextKey;
|
||||
prev = next;
|
||||
next = next.alternativa3d::nextKeyFrame;
|
||||
}
|
||||
if(next != null)
|
||||
{
|
||||
nextKey = this.alternativa3d::createKeyFrame();
|
||||
this.alternativa3d::interpolateKeyFrame(nextKey,prev,next,(end - prev.name_qC) / (next.name_qC - prev.name_qC));
|
||||
nextKey.name_qC = end - shiftTime;
|
||||
key.alternativa3d::nextKeyFrame = nextKey;
|
||||
}
|
||||
if(nextKey != null)
|
||||
{
|
||||
dest.name_YC = nextKey.name_qC <= 0 ? 0 : nextKey.name_qC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.geom.Matrix3D;
|
||||
import flash.geom.Orientation3D;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class TransformKey extends Keyframe
|
||||
{
|
||||
alternativa3d var x:Number = 0;
|
||||
|
||||
alternativa3d var y:Number = 0;
|
||||
|
||||
alternativa3d var z:Number = 0;
|
||||
|
||||
alternativa3d var rotation:Vector3D = new Vector3D(0,0,0,1);
|
||||
|
||||
alternativa3d var scaleX:Number = 1;
|
||||
|
||||
alternativa3d var scaleY:Number = 1;
|
||||
|
||||
alternativa3d var scaleZ:Number = 1;
|
||||
|
||||
alternativa3d var next:TransformKey;
|
||||
|
||||
public function TransformKey()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
override public function get value() : Object
|
||||
{
|
||||
var m:Matrix3D = new Matrix3D();
|
||||
m.recompose(Vector.<Vector3D>([new Vector3D(this.alternativa3d::x,this.alternativa3d::y,this.alternativa3d::z),this.alternativa3d::rotation,new Vector3D(this.alternativa3d::scaleX,this.alternativa3d::scaleY,this.alternativa3d::scaleZ)]),Orientation3D.QUATERNION);
|
||||
return m;
|
||||
}
|
||||
|
||||
override public function set value(v:Object) : void
|
||||
{
|
||||
var m:Matrix3D = Matrix3D(v);
|
||||
var components:Vector.<Vector3D> = m.decompose(Orientation3D.QUATERNION);
|
||||
this.alternativa3d::x = components[0].x;
|
||||
this.alternativa3d::y = components[0].y;
|
||||
this.alternativa3d::z = components[0].z;
|
||||
this.alternativa3d::rotation = components[1];
|
||||
this.alternativa3d::scaleX = components[2].x;
|
||||
this.alternativa3d::scaleY = components[2].y;
|
||||
this.alternativa3d::scaleZ = components[2].z;
|
||||
}
|
||||
|
||||
public function interpolate(a:TransformKey, b:TransformKey, c:Number) : void
|
||||
{
|
||||
var c2:Number = 1 - c;
|
||||
this.alternativa3d::x = c2 * a.alternativa3d::x + c * b.alternativa3d::x;
|
||||
this.alternativa3d::y = c2 * a.alternativa3d::y + c * b.alternativa3d::y;
|
||||
this.alternativa3d::z = c2 * a.alternativa3d::z + c * b.alternativa3d::z;
|
||||
this.slerp(a.alternativa3d::rotation,b.alternativa3d::rotation,c,this.alternativa3d::rotation);
|
||||
this.alternativa3d::scaleX = c2 * a.alternativa3d::scaleX + c * b.alternativa3d::scaleX;
|
||||
this.alternativa3d::scaleY = c2 * a.alternativa3d::scaleY + c * b.alternativa3d::scaleY;
|
||||
this.alternativa3d::scaleZ = c2 * a.alternativa3d::scaleZ + c * b.alternativa3d::scaleZ;
|
||||
}
|
||||
|
||||
private function slerp(a:Vector3D, b:Vector3D, t:Number, result:Vector3D) : void
|
||||
{
|
||||
var k1:Number = NaN;
|
||||
var k2:Number = NaN;
|
||||
var d:Number = NaN;
|
||||
var _loc10_:Number = NaN;
|
||||
var _loc11_:Number = NaN;
|
||||
var _loc12_:Number = NaN;
|
||||
var _loc13_:Number = NaN;
|
||||
var flip:Number = 1;
|
||||
var cosine:Number = a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
if(cosine < 0)
|
||||
{
|
||||
cosine = -cosine;
|
||||
flip = -1;
|
||||
}
|
||||
if(1 - cosine < 0.001)
|
||||
{
|
||||
k1 = 1 - t;
|
||||
k2 = t * flip;
|
||||
result.w = a.w * k1 + b.w * k2;
|
||||
result.x = a.x * k1 + b.x * k2;
|
||||
result.y = a.y * k1 + b.y * k2;
|
||||
result.z = a.z * k1 + b.z * k2;
|
||||
d = result.w * result.w + result.x * result.x + result.y * result.y + result.z * result.z;
|
||||
if(d == 0)
|
||||
{
|
||||
result.w = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.scaleBy(1 / Math.sqrt(d));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc10_ = Number(Math.acos(cosine));
|
||||
_loc11_ = Number(Math.sin(_loc10_));
|
||||
_loc12_ = Math.sin((1 - t) * _loc10_) / _loc11_;
|
||||
_loc13_ = Math.sin(t * _loc10_) / _loc11_ * flip;
|
||||
result.w = a.w * _loc12_ + b.w * _loc13_;
|
||||
result.x = a.x * _loc12_ + b.x * _loc13_;
|
||||
result.y = a.y * _loc12_ + b.y * _loc13_;
|
||||
result.z = a.z * _loc12_ + b.z * _loc13_;
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function get nextKeyFrame() : Keyframe
|
||||
{
|
||||
return this.alternativa3d::next;
|
||||
}
|
||||
|
||||
override alternativa3d function set nextKeyFrame(value:Keyframe) : void
|
||||
{
|
||||
this.alternativa3d::next = TransformKey(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
package alternativa.engine3d.animation.keys
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.AnimationState;
|
||||
import flash.geom.Matrix3D;
|
||||
import flash.geom.Orientation3D;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class TransformTrack extends Track
|
||||
{
|
||||
private static var tempQuat:Vector3D = new Vector3D();
|
||||
|
||||
private static var temp:TransformKey = new TransformKey();
|
||||
|
||||
private var name_ku:TransformKey;
|
||||
|
||||
public function TransformTrack(object:String)
|
||||
{
|
||||
super();
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
override alternativa3d function get keyFramesList() : Keyframe
|
||||
{
|
||||
return this.name_ku;
|
||||
}
|
||||
|
||||
override alternativa3d function set keyFramesList(value:Keyframe) : void
|
||||
{
|
||||
this.name_ku = TransformKey(value);
|
||||
}
|
||||
|
||||
public function addKey(time:Number, matrix:Matrix3D) : TransformKey
|
||||
{
|
||||
var key:TransformKey = null;
|
||||
key = new TransformKey();
|
||||
key.name_qC = time;
|
||||
var components:Vector.<Vector3D> = matrix.decompose(Orientation3D.QUATERNION);
|
||||
key.alternativa3d::x = components[0].x;
|
||||
key.alternativa3d::y = components[0].y;
|
||||
key.alternativa3d::z = components[0].z;
|
||||
key.alternativa3d::rotation = components[1];
|
||||
key.alternativa3d::scaleX = components[2].x;
|
||||
key.alternativa3d::scaleY = components[2].y;
|
||||
key.alternativa3d::scaleZ = components[2].z;
|
||||
alternativa3d::addKeyToList(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
public function addKeyComponents(time:Number, x:Number = 0, y:Number = 0, z:Number = 0, rotationX:Number = 0, rotationY:Number = 0, rotationZ:Number = 0, scaleX:Number = 1, scaleY:Number = 1, scaleZ:Number = 1) : TransformKey
|
||||
{
|
||||
var key:TransformKey = new TransformKey();
|
||||
key.name_qC = time;
|
||||
key.alternativa3d::x = x;
|
||||
key.alternativa3d::y = y;
|
||||
key.alternativa3d::z = z;
|
||||
key.alternativa3d::rotation = this.createQuatFromEuler(rotationX,rotationY,rotationZ);
|
||||
key.alternativa3d::scaleX = scaleX;
|
||||
key.alternativa3d::scaleY = scaleY;
|
||||
key.alternativa3d::scaleZ = scaleZ;
|
||||
alternativa3d::addKeyToList(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
private function appendQuat(quat:Vector3D, additive:Vector3D) : void
|
||||
{
|
||||
var ww:Number = additive.w * quat.w - additive.x * quat.x - additive.y * quat.y - additive.z * quat.z;
|
||||
var xx:Number = additive.w * quat.x + additive.x * quat.w + additive.y * quat.z - additive.z * quat.y;
|
||||
var yy:Number = additive.w * quat.y + additive.y * quat.w + additive.z * quat.x - additive.x * quat.z;
|
||||
var zz:Number = additive.w * quat.z + additive.z * quat.w + additive.x * quat.y - additive.y * quat.x;
|
||||
quat.w = ww;
|
||||
quat.x = xx;
|
||||
quat.y = yy;
|
||||
quat.z = zz;
|
||||
}
|
||||
|
||||
private function normalizeQuat(quat:Vector3D) : void
|
||||
{
|
||||
var d:Number = quat.w * quat.w + quat.x * quat.x + quat.y * quat.y + quat.z * quat.z;
|
||||
if(d == 0)
|
||||
{
|
||||
quat.w = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = 1 / Math.sqrt(d);
|
||||
quat.w *= d;
|
||||
quat.x *= d;
|
||||
quat.y *= d;
|
||||
quat.z *= d;
|
||||
}
|
||||
}
|
||||
|
||||
private function setQuatFromAxisAngle(quat:Vector3D, x:Number, y:Number, z:Number, angle:Number) : void
|
||||
{
|
||||
quat.w = Math.cos(0.5 * angle);
|
||||
var k:Number = Math.sin(0.5 * angle) / Math.sqrt(x * x + y * y + z * z);
|
||||
quat.x = x * k;
|
||||
quat.y = y * k;
|
||||
quat.z = z * k;
|
||||
}
|
||||
|
||||
private function createQuatFromEuler(x:Number, y:Number, z:Number) : Vector3D
|
||||
{
|
||||
var result:Vector3D = new Vector3D();
|
||||
this.setQuatFromAxisAngle(result,1,0,0,x);
|
||||
this.setQuatFromAxisAngle(tempQuat,0,1,0,y);
|
||||
this.appendQuat(result,tempQuat);
|
||||
this.normalizeQuat(result);
|
||||
this.setQuatFromAxisAngle(tempQuat,0,0,1,z);
|
||||
this.appendQuat(result,tempQuat);
|
||||
this.normalizeQuat(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
override alternativa3d function blend(time:Number, weight:Number, state:AnimationState) : void
|
||||
{
|
||||
var prev:TransformKey = null;
|
||||
var next:TransformKey = this.name_ku;
|
||||
while(next != null && next.name_qC < time)
|
||||
{
|
||||
prev = next;
|
||||
next = next.alternativa3d::next;
|
||||
}
|
||||
if(prev != null)
|
||||
{
|
||||
if(next != null)
|
||||
{
|
||||
temp.interpolate(prev,next,(time - prev.name_qC) / (next.name_qC - prev.name_qC));
|
||||
state.addWeightedTransform(temp,weight);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.addWeightedTransform(prev,weight);
|
||||
}
|
||||
}
|
||||
else if(next != null)
|
||||
{
|
||||
state.addWeightedTransform(next,weight);
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function createKeyFrame() : Keyframe
|
||||
{
|
||||
return new TransformKey();
|
||||
}
|
||||
|
||||
override alternativa3d function interpolateKeyFrame(dest:Keyframe, a:Keyframe, b:Keyframe, value:Number) : void
|
||||
{
|
||||
TransformKey(dest).interpolate(TransformKey(a),TransformKey(b),value);
|
||||
}
|
||||
|
||||
override public function slice(start:Number, end:Number = 1.7976931348623157e+308) : Track
|
||||
{
|
||||
var track:TransformTrack = new TransformTrack(object);
|
||||
alternativa3d::sliceImplementation(track,start,end);
|
||||
return track;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,679 +0,0 @@
|
||||
package alternativa.engine3d.collisions
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.*;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class EllipsoidCollider
|
||||
{
|
||||
public var radiusX:Number;
|
||||
|
||||
public var radiusY:Number;
|
||||
|
||||
public var radiusZ:Number;
|
||||
|
||||
public var threshold:Number = 0.001;
|
||||
|
||||
private var matrix:Transform3D = new Transform3D();
|
||||
|
||||
private var name_jX:Transform3D = new Transform3D();
|
||||
|
||||
alternativa3d var geometries:Vector.<Geometry> = new Vector.<Geometry>();
|
||||
|
||||
alternativa3d var name_QK:Vector.<Transform3D> = new Vector.<Transform3D>();
|
||||
|
||||
private var vertices:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_g0:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var indices:Vector.<int> = new Vector.<int>();
|
||||
|
||||
private var numTriangles:int;
|
||||
|
||||
private var radius:Number;
|
||||
|
||||
private var src:Vector3D = new Vector3D();
|
||||
|
||||
private var name_o5:Vector3D = new Vector3D();
|
||||
|
||||
private var dest:Vector3D = new Vector3D();
|
||||
|
||||
private var name_SE:Vector3D = new Vector3D();
|
||||
|
||||
private var name_pU:Vector3D = new Vector3D();
|
||||
|
||||
alternativa3d var sphere:Vector3D = new Vector3D();
|
||||
|
||||
private var name_SZ:Vector3D = new Vector3D();
|
||||
|
||||
private var name_1v:Vector3D = new Vector3D();
|
||||
|
||||
private var name_L9:Vector3D = new Vector3D();
|
||||
|
||||
private var name_8B:Vector3D = new Vector3D();
|
||||
|
||||
public function EllipsoidCollider(radiusX:Number, radiusY:Number, radiusZ:Number)
|
||||
{
|
||||
super();
|
||||
this.radiusX = radiusX;
|
||||
this.radiusY = radiusY;
|
||||
this.radiusZ = radiusZ;
|
||||
}
|
||||
|
||||
alternativa3d function calculateSphere(transform:Transform3D) : void
|
||||
{
|
||||
this.alternativa3d::sphere.x = transform.d;
|
||||
this.alternativa3d::sphere.y = transform.h;
|
||||
this.alternativa3d::sphere.z = transform.l;
|
||||
var sax:Number = transform.a * this.name_SZ.x + transform.b * this.name_SZ.y + transform.c * this.name_SZ.z + transform.d;
|
||||
var say:Number = transform.e * this.name_SZ.x + transform.f * this.name_SZ.y + transform.g * this.name_SZ.z + transform.h;
|
||||
var saz:Number = transform.i * this.name_SZ.x + transform.j * this.name_SZ.y + transform.k * this.name_SZ.z + transform.l;
|
||||
var sbx:Number = transform.a * this.name_1v.x + transform.b * this.name_1v.y + transform.c * this.name_1v.z + transform.d;
|
||||
var sby:Number = transform.e * this.name_1v.x + transform.f * this.name_1v.y + transform.g * this.name_1v.z + transform.h;
|
||||
var sbz:Number = transform.i * this.name_1v.x + transform.j * this.name_1v.y + transform.k * this.name_1v.z + transform.l;
|
||||
var scx:Number = transform.a * this.name_L9.x + transform.b * this.name_L9.y + transform.c * this.name_L9.z + transform.d;
|
||||
var scy:Number = transform.e * this.name_L9.x + transform.f * this.name_L9.y + transform.g * this.name_L9.z + transform.h;
|
||||
var scz:Number = transform.i * this.name_L9.x + transform.j * this.name_L9.y + transform.k * this.name_L9.z + transform.l;
|
||||
var sdx:Number = transform.a * this.name_8B.x + transform.b * this.name_8B.y + transform.c * this.name_8B.z + transform.d;
|
||||
var sdy:Number = transform.e * this.name_8B.x + transform.f * this.name_8B.y + transform.g * this.name_8B.z + transform.h;
|
||||
var sdz:Number = transform.i * this.name_8B.x + transform.j * this.name_8B.y + transform.k * this.name_8B.z + transform.l;
|
||||
var dx:Number = sax - this.alternativa3d::sphere.x;
|
||||
var dy:Number = say - this.alternativa3d::sphere.y;
|
||||
var dz:Number = saz - this.alternativa3d::sphere.z;
|
||||
this.alternativa3d::sphere.w = dx * dx + dy * dy + dz * dz;
|
||||
dx = sbx - this.alternativa3d::sphere.x;
|
||||
dy = sby - this.alternativa3d::sphere.y;
|
||||
dz = sbz - this.alternativa3d::sphere.z;
|
||||
var dxyz:Number = dx * dx + dy * dy + dz * dz;
|
||||
if(dxyz > this.alternativa3d::sphere.w)
|
||||
{
|
||||
this.alternativa3d::sphere.w = dxyz;
|
||||
}
|
||||
dx = scx - this.alternativa3d::sphere.x;
|
||||
dy = scy - this.alternativa3d::sphere.y;
|
||||
dz = scz - this.alternativa3d::sphere.z;
|
||||
dxyz = dx * dx + dy * dy + dz * dz;
|
||||
if(dxyz > this.alternativa3d::sphere.w)
|
||||
{
|
||||
this.alternativa3d::sphere.w = dxyz;
|
||||
}
|
||||
dx = sdx - this.alternativa3d::sphere.x;
|
||||
dy = sdy - this.alternativa3d::sphere.y;
|
||||
dz = sdz - this.alternativa3d::sphere.z;
|
||||
dxyz = dx * dx + dy * dy + dz * dz;
|
||||
if(dxyz > this.alternativa3d::sphere.w)
|
||||
{
|
||||
this.alternativa3d::sphere.w = dxyz;
|
||||
}
|
||||
this.alternativa3d::sphere.w = Math.sqrt(this.alternativa3d::sphere.w);
|
||||
}
|
||||
|
||||
private function prepare(source:Vector3D, displacement:Vector3D, object:Object3D, excludedObjects:Dictionary) : void
|
||||
{
|
||||
var j:int = 0;
|
||||
var intersects:Boolean = false;
|
||||
var geometry:Geometry = null;
|
||||
var transform:Transform3D = null;
|
||||
var geometryIndicesLength:int = 0;
|
||||
var vBuffer:VertexStream = null;
|
||||
var geometryIndices:Vector.<uint> = null;
|
||||
var attributesOffset:int = 0;
|
||||
var numMappings:int = 0;
|
||||
var data:ByteArray = null;
|
||||
var vx:Number = NaN;
|
||||
var vy:Number = NaN;
|
||||
var vz:Number = NaN;
|
||||
var a:int = 0;
|
||||
var index:int = 0;
|
||||
var ax:Number = NaN;
|
||||
var ay:Number = NaN;
|
||||
var az:Number = NaN;
|
||||
var b:int = 0;
|
||||
var bx:Number = NaN;
|
||||
var by:Number = NaN;
|
||||
var bz:Number = NaN;
|
||||
var c:int = 0;
|
||||
var cx:Number = NaN;
|
||||
var cy:Number = NaN;
|
||||
var cz:Number = NaN;
|
||||
var abx:Number = NaN;
|
||||
var aby:Number = NaN;
|
||||
var abz:Number = NaN;
|
||||
var acx:Number = NaN;
|
||||
var acy:Number = NaN;
|
||||
var acz:Number = NaN;
|
||||
var normalX:Number = NaN;
|
||||
var normalY:Number = NaN;
|
||||
var normalZ:Number = NaN;
|
||||
var len:Number = NaN;
|
||||
var offset:Number = NaN;
|
||||
this.radius = this.radiusX;
|
||||
if(this.radiusY > this.radius)
|
||||
{
|
||||
this.radius = this.radiusY;
|
||||
}
|
||||
if(this.radiusZ > this.radius)
|
||||
{
|
||||
this.radius = this.radiusZ;
|
||||
}
|
||||
this.matrix.compose(source.x,source.y,source.z,0,0,0,this.radiusX / this.radius,this.radiusY / this.radius,this.radiusZ / this.radius);
|
||||
this.name_jX.copy(this.matrix);
|
||||
this.name_jX.invert();
|
||||
this.src.x = 0;
|
||||
this.src.y = 0;
|
||||
this.src.z = 0;
|
||||
this.name_o5.x = this.name_jX.a * displacement.x + this.name_jX.b * displacement.y + this.name_jX.c * displacement.z;
|
||||
this.name_o5.y = this.name_jX.e * displacement.x + this.name_jX.f * displacement.y + this.name_jX.g * displacement.z;
|
||||
this.name_o5.z = this.name_jX.i * displacement.x + this.name_jX.j * displacement.y + this.name_jX.k * displacement.z;
|
||||
this.dest.x = this.src.x + this.name_o5.x;
|
||||
this.dest.y = this.src.y + this.name_o5.y;
|
||||
this.dest.z = this.src.z + this.name_o5.z;
|
||||
var rad:Number = this.radius + this.name_o5.length;
|
||||
this.name_SZ.x = -rad;
|
||||
this.name_SZ.y = -rad;
|
||||
this.name_SZ.z = -rad;
|
||||
this.name_1v.x = rad;
|
||||
this.name_1v.y = -rad;
|
||||
this.name_1v.z = -rad;
|
||||
this.name_L9.x = rad;
|
||||
this.name_L9.y = rad;
|
||||
this.name_L9.z = -rad;
|
||||
this.name_8B.x = -rad;
|
||||
this.name_8B.y = rad;
|
||||
this.name_8B.z = -rad;
|
||||
if(excludedObjects == null || !excludedObjects[object])
|
||||
{
|
||||
if(object.alternativa3d::transformChanged)
|
||||
{
|
||||
object.alternativa3d::composeTransforms();
|
||||
}
|
||||
object.alternativa3d::globalToLocalTransform.combine(object.alternativa3d::inverseTransform,this.matrix);
|
||||
intersects = true;
|
||||
if(object.boundBox != null)
|
||||
{
|
||||
this.alternativa3d::calculateSphere(object.alternativa3d::globalToLocalTransform);
|
||||
intersects = object.boundBox.alternativa3d::checkSphere(this.alternativa3d::sphere);
|
||||
}
|
||||
if(intersects)
|
||||
{
|
||||
object.alternativa3d::localToGlobalTransform.combine(this.name_jX,object.alternativa3d::transform);
|
||||
object.alternativa3d::collectGeometry(this,excludedObjects);
|
||||
}
|
||||
if(object.alternativa3d::childrenList != null)
|
||||
{
|
||||
object.alternativa3d::collectChildrenGeometry(this,excludedObjects);
|
||||
}
|
||||
}
|
||||
this.numTriangles = 0;
|
||||
var indicesLength:int = 0;
|
||||
var normalsLength:int = 0;
|
||||
var mapOffset:int = 0;
|
||||
var verticesLength:int = 0;
|
||||
var geometriesLength:int = int(this.alternativa3d::geometries.length);
|
||||
for(var i:int = 0; i < geometriesLength; i++)
|
||||
{
|
||||
geometry = this.alternativa3d::geometries[i];
|
||||
transform = this.name_QK[i];
|
||||
geometryIndicesLength = int(geometry.alternativa3d::_indices.length);
|
||||
if(!(geometry.alternativa3d::_numVertices == 0 || geometryIndicesLength == 0))
|
||||
{
|
||||
vBuffer = VertexAttributes.POSITION < geometry.name_GM.length ? geometry.name_GM[VertexAttributes.POSITION] : null;
|
||||
if(vBuffer != null)
|
||||
{
|
||||
attributesOffset = int(geometry.alternativa3d::_attributesOffsets[VertexAttributes.POSITION]);
|
||||
numMappings = int(vBuffer.attributes.length);
|
||||
data = vBuffer.data;
|
||||
for(j = 0; j < geometry.alternativa3d::_numVertices; j++)
|
||||
{
|
||||
data.position = 4 * (numMappings * j + attributesOffset);
|
||||
vx = Number(data.readFloat());
|
||||
vy = Number(data.readFloat());
|
||||
vz = Number(data.readFloat());
|
||||
this.vertices[verticesLength] = transform.a * vx + transform.b * vy + transform.c * vz + transform.d;
|
||||
verticesLength++;
|
||||
this.vertices[verticesLength] = transform.e * vx + transform.f * vy + transform.g * vz + transform.h;
|
||||
verticesLength++;
|
||||
this.vertices[verticesLength] = transform.i * vx + transform.j * vy + transform.k * vz + transform.l;
|
||||
verticesLength++;
|
||||
}
|
||||
}
|
||||
geometryIndices = geometry.alternativa3d::_indices;
|
||||
for(j = 0; j < geometryIndicesLength; )
|
||||
{
|
||||
a = geometryIndices[j] + mapOffset;
|
||||
j++;
|
||||
index = a * 3;
|
||||
ax = this.vertices[index];
|
||||
index++;
|
||||
ay = this.vertices[index];
|
||||
index++;
|
||||
az = this.vertices[index];
|
||||
b = geometryIndices[j] + mapOffset;
|
||||
j++;
|
||||
index = b * 3;
|
||||
bx = this.vertices[index];
|
||||
index++;
|
||||
by = this.vertices[index];
|
||||
index++;
|
||||
bz = this.vertices[index];
|
||||
c = geometryIndices[j] + mapOffset;
|
||||
j++;
|
||||
index = c * 3;
|
||||
cx = this.vertices[index];
|
||||
index++;
|
||||
cy = this.vertices[index];
|
||||
index++;
|
||||
cz = this.vertices[index];
|
||||
if(!(ax > rad && bx > rad && cx > rad || ax < -rad && bx < -rad && cx < -rad))
|
||||
{
|
||||
if(!(ay > rad && by > rad && cy > rad || ay < -rad && by < -rad && cy < -rad))
|
||||
{
|
||||
if(!(az > rad && bz > rad && cz > rad || az < -rad && bz < -rad && cz < -rad))
|
||||
{
|
||||
abx = bx - ax;
|
||||
aby = by - ay;
|
||||
abz = bz - az;
|
||||
acx = cx - ax;
|
||||
acy = cy - ay;
|
||||
acz = cz - az;
|
||||
normalX = acz * aby - acy * abz;
|
||||
normalY = acx * abz - acz * abx;
|
||||
normalZ = acy * abx - acx * aby;
|
||||
len = normalX * normalX + normalY * normalY + normalZ * normalZ;
|
||||
if(len >= 0.001)
|
||||
{
|
||||
len = 1 / Math.sqrt(len);
|
||||
normalX *= len;
|
||||
normalY *= len;
|
||||
normalZ *= len;
|
||||
offset = ax * normalX + ay * normalY + az * normalZ;
|
||||
if(!(offset > rad || offset < -rad))
|
||||
{
|
||||
this.indices[indicesLength] = a;
|
||||
indicesLength++;
|
||||
this.indices[indicesLength] = b;
|
||||
indicesLength++;
|
||||
this.indices[indicesLength] = c;
|
||||
indicesLength++;
|
||||
this.name_g0[normalsLength] = normalX;
|
||||
normalsLength++;
|
||||
this.name_g0[normalsLength] = normalY;
|
||||
normalsLength++;
|
||||
this.name_g0[normalsLength] = normalZ;
|
||||
normalsLength++;
|
||||
this.name_g0[normalsLength] = offset;
|
||||
normalsLength++;
|
||||
++this.numTriangles;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mapOffset += geometry.alternativa3d::_numVertices;
|
||||
}
|
||||
}
|
||||
this.alternativa3d::geometries.length = 0;
|
||||
this.name_QK.length = 0;
|
||||
}
|
||||
|
||||
public function calculateDestination(source:Vector3D, displacement:Vector3D, object:Object3D, excludedObjects:Dictionary = null) : Vector3D
|
||||
{
|
||||
var limit:int = 0;
|
||||
var i:int = 0;
|
||||
var offset:Number = NaN;
|
||||
if(displacement.length <= this.threshold)
|
||||
{
|
||||
return source.clone();
|
||||
}
|
||||
this.prepare(source,displacement,object,excludedObjects);
|
||||
if(this.numTriangles > 0)
|
||||
{
|
||||
limit = 50;
|
||||
for(i = 0; i < limit; )
|
||||
{
|
||||
if(!this.checkCollision())
|
||||
{
|
||||
break;
|
||||
}
|
||||
offset = this.radius + this.threshold + this.name_pU.w - this.dest.x * this.name_pU.x - this.dest.y * this.name_pU.y - this.dest.z * this.name_pU.z;
|
||||
this.dest.x += this.name_pU.x * offset;
|
||||
this.dest.y += this.name_pU.y * offset;
|
||||
this.dest.z += this.name_pU.z * offset;
|
||||
this.src.x = this.name_SE.x + this.name_pU.x * (this.radius + this.threshold);
|
||||
this.src.y = this.name_SE.y + this.name_pU.y * (this.radius + this.threshold);
|
||||
this.src.z = this.name_SE.z + this.name_pU.z * (this.radius + this.threshold);
|
||||
this.name_o5.x = this.dest.x - this.src.x;
|
||||
this.name_o5.y = this.dest.y - this.src.y;
|
||||
this.name_o5.z = this.dest.z - this.src.z;
|
||||
if(this.name_o5.length < this.threshold)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return new Vector3D(this.matrix.a * this.dest.x + this.matrix.b * this.dest.y + this.matrix.c * this.dest.z + this.matrix.d,this.matrix.e * this.dest.x + this.matrix.f * this.dest.y + this.matrix.g * this.dest.z + this.matrix.h,this.matrix.i * this.dest.x + this.matrix.j * this.dest.y + this.matrix.k * this.dest.z + this.matrix.l);
|
||||
}
|
||||
return new Vector3D(source.x + displacement.x,source.y + displacement.y,source.z + displacement.z);
|
||||
}
|
||||
|
||||
public function getCollision(source:Vector3D, displacement:Vector3D, resCollisionPoint:Vector3D, resCollisionPlane:Vector3D, object:Object3D, excludedObjects:Dictionary = null) : Boolean
|
||||
{
|
||||
var abx:Number = NaN;
|
||||
var aby:Number = NaN;
|
||||
var abz:Number = NaN;
|
||||
var acx:Number = NaN;
|
||||
var acy:Number = NaN;
|
||||
var acz:Number = NaN;
|
||||
var abx2:Number = NaN;
|
||||
var aby2:Number = NaN;
|
||||
var abz2:Number = NaN;
|
||||
var acx2:Number = NaN;
|
||||
var acy2:Number = NaN;
|
||||
var acz2:Number = NaN;
|
||||
if(displacement.length <= this.threshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.prepare(source,displacement,object,excludedObjects);
|
||||
if(this.numTriangles > 0)
|
||||
{
|
||||
if(this.checkCollision())
|
||||
{
|
||||
resCollisionPoint.x = this.matrix.a * this.name_SE.x + this.matrix.b * this.name_SE.y + this.matrix.c * this.name_SE.z + this.matrix.d;
|
||||
resCollisionPoint.y = this.matrix.e * this.name_SE.x + this.matrix.f * this.name_SE.y + this.matrix.g * this.name_SE.z + this.matrix.h;
|
||||
resCollisionPoint.z = this.matrix.i * this.name_SE.x + this.matrix.j * this.name_SE.y + this.matrix.k * this.name_SE.z + this.matrix.l;
|
||||
if(this.name_pU.x < this.name_pU.y)
|
||||
{
|
||||
if(this.name_pU.x < this.name_pU.z)
|
||||
{
|
||||
abx = 0;
|
||||
aby = -this.name_pU.z;
|
||||
abz = Number(this.name_pU.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
abx = -this.name_pU.y;
|
||||
aby = Number(this.name_pU.x);
|
||||
abz = 0;
|
||||
}
|
||||
}
|
||||
else if(this.name_pU.y < this.name_pU.z)
|
||||
{
|
||||
abx = Number(this.name_pU.z);
|
||||
aby = 0;
|
||||
abz = -this.name_pU.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
abx = -this.name_pU.y;
|
||||
aby = Number(this.name_pU.x);
|
||||
abz = 0;
|
||||
}
|
||||
acx = this.name_pU.z * aby - this.name_pU.y * abz;
|
||||
acy = this.name_pU.x * abz - this.name_pU.z * abx;
|
||||
acz = this.name_pU.y * abx - this.name_pU.x * aby;
|
||||
abx2 = this.matrix.a * abx + this.matrix.b * aby + this.matrix.c * abz;
|
||||
aby2 = this.matrix.e * abx + this.matrix.f * aby + this.matrix.g * abz;
|
||||
abz2 = this.matrix.i * abx + this.matrix.j * aby + this.matrix.k * abz;
|
||||
acx2 = this.matrix.a * acx + this.matrix.b * acy + this.matrix.c * acz;
|
||||
acy2 = this.matrix.e * acx + this.matrix.f * acy + this.matrix.g * acz;
|
||||
acz2 = this.matrix.i * acx + this.matrix.j * acy + this.matrix.k * acz;
|
||||
resCollisionPlane.x = abz2 * acy2 - aby2 * acz2;
|
||||
resCollisionPlane.y = abx2 * acz2 - abz2 * acx2;
|
||||
resCollisionPlane.z = aby2 * acx2 - abx2 * acy2;
|
||||
resCollisionPlane.normalize();
|
||||
resCollisionPlane.w = resCollisionPoint.x * resCollisionPlane.x + resCollisionPoint.y * resCollisionPlane.y + resCollisionPoint.z * resCollisionPlane.z;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkCollision() : Boolean
|
||||
{
|
||||
var index:int = 0;
|
||||
var ax:Number = NaN;
|
||||
var ay:Number = NaN;
|
||||
var az:Number = NaN;
|
||||
var bx:Number = NaN;
|
||||
var by:Number = NaN;
|
||||
var bz:Number = NaN;
|
||||
var cx:Number = NaN;
|
||||
var cy:Number = NaN;
|
||||
var cz:Number = NaN;
|
||||
var normalX:Number = NaN;
|
||||
var normalY:Number = NaN;
|
||||
var normalZ:Number = NaN;
|
||||
var offset:Number = NaN;
|
||||
var distance:Number = NaN;
|
||||
var pointX:Number = NaN;
|
||||
var pointY:Number = NaN;
|
||||
var pointZ:Number = NaN;
|
||||
var faceX:Number = NaN;
|
||||
var faceY:Number = NaN;
|
||||
var faceZ:Number = NaN;
|
||||
var min:Number = NaN;
|
||||
var inside:Boolean = false;
|
||||
var k:int = 0;
|
||||
var deltaX:Number = NaN;
|
||||
var deltaY:Number = NaN;
|
||||
var deltaZ:Number = NaN;
|
||||
var _loc33_:Number = NaN;
|
||||
var p1x:Number = NaN;
|
||||
var p1y:Number = NaN;
|
||||
var p1z:Number = NaN;
|
||||
var p2x:Number = NaN;
|
||||
var p2y:Number = NaN;
|
||||
var p2z:Number = NaN;
|
||||
var abx:Number = NaN;
|
||||
var aby:Number = NaN;
|
||||
var abz:Number = NaN;
|
||||
var acx:Number = NaN;
|
||||
var acy:Number = NaN;
|
||||
var acz:Number = NaN;
|
||||
var crx:Number = NaN;
|
||||
var cry:Number = NaN;
|
||||
var crz:Number = NaN;
|
||||
var edgeLength:Number = NaN;
|
||||
var edgeDistanceSqr:Number = NaN;
|
||||
var acLen:Number = NaN;
|
||||
var backX:Number = NaN;
|
||||
var backY:Number = NaN;
|
||||
var backZ:Number = NaN;
|
||||
var deltaLength:Number = NaN;
|
||||
var projectionLength:Number = NaN;
|
||||
var projectionInsideLength:Number = NaN;
|
||||
var time:Number = NaN;
|
||||
var minTime:Number = 1;
|
||||
var displacementLength:Number = Number(this.name_o5.length);
|
||||
var indicesLength:int = this.numTriangles * 3;
|
||||
for(var i:int = 0, j:int = 0; i < indicesLength; )
|
||||
{
|
||||
index = this.indices[i] * 3;
|
||||
i++;
|
||||
ax = this.vertices[index];
|
||||
index++;
|
||||
ay = this.vertices[index];
|
||||
index++;
|
||||
az = this.vertices[index];
|
||||
index = this.indices[i] * 3;
|
||||
i++;
|
||||
bx = this.vertices[index];
|
||||
index++;
|
||||
by = this.vertices[index];
|
||||
index++;
|
||||
bz = this.vertices[index];
|
||||
index = this.indices[i] * 3;
|
||||
i++;
|
||||
cx = this.vertices[index];
|
||||
index++;
|
||||
cy = this.vertices[index];
|
||||
index++;
|
||||
cz = this.vertices[index];
|
||||
normalX = this.name_g0[j];
|
||||
j++;
|
||||
normalY = this.name_g0[j];
|
||||
j++;
|
||||
normalZ = this.name_g0[j];
|
||||
j++;
|
||||
offset = this.name_g0[j];
|
||||
j++;
|
||||
distance = this.src.x * normalX + this.src.y * normalY + this.src.z * normalZ - offset;
|
||||
if(distance < this.radius)
|
||||
{
|
||||
pointX = this.src.x - normalX * distance;
|
||||
pointY = this.src.y - normalY * distance;
|
||||
pointZ = this.src.z - normalZ * distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc33_ = (distance - this.radius) / (distance - this.dest.x * normalX - this.dest.y * normalY - this.dest.z * normalZ + offset);
|
||||
pointX = this.src.x + this.name_o5.x * _loc33_ - normalX * this.radius;
|
||||
pointY = this.src.y + this.name_o5.y * _loc33_ - normalY * this.radius;
|
||||
pointZ = this.src.z + this.name_o5.z * _loc33_ - normalZ * this.radius;
|
||||
}
|
||||
min = 1e+22;
|
||||
inside = true;
|
||||
for(k = 0; k < 3; )
|
||||
{
|
||||
if(k == 0)
|
||||
{
|
||||
p1x = ax;
|
||||
p1y = ay;
|
||||
p1z = az;
|
||||
p2x = bx;
|
||||
p2y = by;
|
||||
p2z = bz;
|
||||
}
|
||||
else if(k == 1)
|
||||
{
|
||||
p1x = bx;
|
||||
p1y = by;
|
||||
p1z = bz;
|
||||
p2x = cx;
|
||||
p2y = cy;
|
||||
p2z = cz;
|
||||
}
|
||||
else
|
||||
{
|
||||
p1x = cx;
|
||||
p1y = cy;
|
||||
p1z = cz;
|
||||
p2x = ax;
|
||||
p2y = ay;
|
||||
p2z = az;
|
||||
}
|
||||
abx = p2x - p1x;
|
||||
aby = p2y - p1y;
|
||||
abz = p2z - p1z;
|
||||
acx = pointX - p1x;
|
||||
acy = pointY - p1y;
|
||||
acz = pointZ - p1z;
|
||||
crx = acz * aby - acy * abz;
|
||||
cry = acx * abz - acz * abx;
|
||||
crz = acy * abx - acx * aby;
|
||||
if(crx * normalX + cry * normalY + crz * normalZ < 0)
|
||||
{
|
||||
edgeLength = abx * abx + aby * aby + abz * abz;
|
||||
edgeDistanceSqr = (crx * crx + cry * cry + crz * crz) / edgeLength;
|
||||
if(edgeDistanceSqr < min)
|
||||
{
|
||||
edgeLength = Number(Math.sqrt(edgeLength));
|
||||
abx /= edgeLength;
|
||||
aby /= edgeLength;
|
||||
abz /= edgeLength;
|
||||
_loc33_ = abx * acx + aby * acy + abz * acz;
|
||||
if(_loc33_ < 0)
|
||||
{
|
||||
acLen = acx * acx + acy * acy + acz * acz;
|
||||
if(acLen < min)
|
||||
{
|
||||
min = acLen;
|
||||
faceX = p1x;
|
||||
faceY = p1y;
|
||||
faceZ = p1z;
|
||||
}
|
||||
}
|
||||
else if(_loc33_ > edgeLength)
|
||||
{
|
||||
acx = pointX - p2x;
|
||||
acy = pointY - p2y;
|
||||
acz = pointZ - p2z;
|
||||
acLen = acx * acx + acy * acy + acz * acz;
|
||||
if(acLen < min)
|
||||
{
|
||||
min = acLen;
|
||||
faceX = p2x;
|
||||
faceY = p2y;
|
||||
faceZ = p2z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
min = edgeDistanceSqr;
|
||||
faceX = p1x + abx * _loc33_;
|
||||
faceY = p1y + aby * _loc33_;
|
||||
faceZ = p1z + abz * _loc33_;
|
||||
}
|
||||
}
|
||||
inside = false;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
if(inside)
|
||||
{
|
||||
faceX = pointX;
|
||||
faceY = pointY;
|
||||
faceZ = pointZ;
|
||||
}
|
||||
deltaX = this.src.x - faceX;
|
||||
deltaY = this.src.y - faceY;
|
||||
deltaZ = this.src.z - faceZ;
|
||||
if(deltaX * this.name_o5.x + deltaY * this.name_o5.y + deltaZ * this.name_o5.z <= 0)
|
||||
{
|
||||
backX = -this.name_o5.x / displacementLength;
|
||||
backY = -this.name_o5.y / displacementLength;
|
||||
backZ = -this.name_o5.z / displacementLength;
|
||||
deltaLength = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
|
||||
projectionLength = deltaX * backX + deltaY * backY + deltaZ * backZ;
|
||||
projectionInsideLength = this.radius * this.radius - deltaLength + projectionLength * projectionLength;
|
||||
if(projectionInsideLength > 0)
|
||||
{
|
||||
time = (projectionLength - Math.sqrt(projectionInsideLength)) / displacementLength;
|
||||
if(time < minTime)
|
||||
{
|
||||
minTime = time;
|
||||
this.name_SE.x = faceX;
|
||||
this.name_SE.y = faceY;
|
||||
this.name_SE.z = faceZ;
|
||||
if(inside)
|
||||
{
|
||||
this.name_pU.x = normalX;
|
||||
this.name_pU.y = normalY;
|
||||
this.name_pU.z = normalZ;
|
||||
this.name_pU.w = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
deltaLength = Number(Math.sqrt(deltaLength));
|
||||
this.name_pU.x = deltaX / deltaLength;
|
||||
this.name_pU.y = deltaY / deltaLength;
|
||||
this.name_pU.z = deltaZ / deltaLength;
|
||||
this.name_pU.w = this.name_SE.x * this.name_pU.x + this.name_SE.y * this.name_pU.y + this.name_SE.z * this.name_pU.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return minTime < 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,373 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class BoundBox
|
||||
{
|
||||
public var minX:Number = 1e+22;
|
||||
|
||||
public var minY:Number = 1e+22;
|
||||
|
||||
public var minZ:Number = 1e+22;
|
||||
|
||||
public var maxX:Number = -1e+22;
|
||||
|
||||
public var maxY:Number = -1e+22;
|
||||
|
||||
public var maxZ:Number = -1e+22;
|
||||
|
||||
public function BoundBox()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function reset() : void
|
||||
{
|
||||
this.minX = 1e+22;
|
||||
this.minY = 1e+22;
|
||||
this.minZ = 1e+22;
|
||||
this.maxX = -1e+22;
|
||||
this.maxY = -1e+22;
|
||||
this.maxZ = -1e+22;
|
||||
}
|
||||
|
||||
alternativa3d function checkFrustumCulling(frustum:CullingPlane, culling:int) : int
|
||||
{
|
||||
var side:int = 1;
|
||||
for(var plane:CullingPlane = frustum; plane != null; plane = plane.next)
|
||||
{
|
||||
if(Boolean(culling & side))
|
||||
{
|
||||
if(plane.x >= 0)
|
||||
{
|
||||
if(plane.y >= 0)
|
||||
{
|
||||
if(plane.z >= 0)
|
||||
{
|
||||
if(this.maxX * plane.x + this.maxY * plane.y + this.maxZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.minX * plane.x + this.minY * plane.y + this.minZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.maxX * plane.x + this.maxY * plane.y + this.minZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.minX * plane.x + this.minY * plane.y + this.maxZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(plane.z >= 0)
|
||||
{
|
||||
if(this.maxX * plane.x + this.minY * plane.y + this.maxZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.minX * plane.x + this.maxY * plane.y + this.minZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.maxX * plane.x + this.minY * plane.y + this.minZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.minX * plane.x + this.maxY * plane.y + this.maxZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(plane.y >= 0)
|
||||
{
|
||||
if(plane.z >= 0)
|
||||
{
|
||||
if(this.minX * plane.x + this.maxY * plane.y + this.maxZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.maxX * plane.x + this.minY * plane.y + this.minZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.minX * plane.x + this.maxY * plane.y + this.minZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.maxX * plane.x + this.minY * plane.y + this.maxZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(plane.z >= 0)
|
||||
{
|
||||
if(this.minX * plane.x + this.minY * plane.y + this.maxZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.maxX * plane.x + this.maxY * plane.y + this.minZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.minX * plane.x + this.minY * plane.y + this.minZ * plane.z <= plane.offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(this.maxX * plane.x + this.maxY * plane.y + this.maxZ * plane.z > plane.offset)
|
||||
{
|
||||
culling &= 0x3F & ~side;
|
||||
}
|
||||
}
|
||||
}
|
||||
side <<= 1;
|
||||
}
|
||||
return culling;
|
||||
}
|
||||
|
||||
alternativa3d function checkOcclusionCulling(camera:Camera3D, object:Object3D, occlusion:CullingPlane = null) : Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
alternativa3d function checkRays(origins:Vector.<Vector3D>, directions:Vector.<Vector3D>, raysLength:int) : Boolean
|
||||
{
|
||||
var origin:Vector3D = null;
|
||||
var direction:Vector3D = null;
|
||||
var a:Number = NaN;
|
||||
var b:Number = NaN;
|
||||
var c:Number = NaN;
|
||||
var d:Number = NaN;
|
||||
var threshold:Number = NaN;
|
||||
for(var i:int = 0; i < raysLength; )
|
||||
{
|
||||
origin = origins[i];
|
||||
direction = directions[i];
|
||||
if(origin.x >= this.minX && origin.x <= this.maxX && origin.y >= this.minY && origin.y <= this.maxY && origin.z >= this.minZ && origin.z <= this.maxZ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!(origin.x < this.minX && direction.x <= 0 || origin.x > this.maxX && direction.x >= 0 || origin.y < this.minY && direction.y <= 0 || origin.y > this.maxY && direction.y >= 0 || origin.z < this.minZ && direction.z <= 0 || origin.z > this.maxZ && direction.z >= 0))
|
||||
{
|
||||
threshold = 0.000001;
|
||||
if(direction.x > threshold)
|
||||
{
|
||||
a = (this.minX - origin.x) / direction.x;
|
||||
b = (this.maxX - origin.x) / direction.x;
|
||||
}
|
||||
else if(direction.x < -threshold)
|
||||
{
|
||||
a = (this.maxX - origin.x) / direction.x;
|
||||
b = (this.minX - origin.x) / direction.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 0;
|
||||
b = 1e+22;
|
||||
}
|
||||
if(direction.y > threshold)
|
||||
{
|
||||
c = (this.minY - origin.y) / direction.y;
|
||||
d = (this.maxY - origin.y) / direction.y;
|
||||
}
|
||||
else if(direction.y < -threshold)
|
||||
{
|
||||
c = (this.maxY - origin.y) / direction.y;
|
||||
d = (this.minY - origin.y) / direction.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = 0;
|
||||
d = 1e+22;
|
||||
}
|
||||
if(!(c >= b || d <= a))
|
||||
{
|
||||
if(c < a)
|
||||
{
|
||||
if(d < b)
|
||||
{
|
||||
b = d;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = c;
|
||||
if(d < b)
|
||||
{
|
||||
b = d;
|
||||
}
|
||||
}
|
||||
if(direction.z > threshold)
|
||||
{
|
||||
c = (this.minZ - origin.z) / direction.z;
|
||||
d = (this.maxZ - origin.z) / direction.z;
|
||||
}
|
||||
else if(direction.z < -threshold)
|
||||
{
|
||||
c = (this.maxZ - origin.z) / direction.z;
|
||||
d = (this.minZ - origin.z) / direction.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = 0;
|
||||
d = 1e+22;
|
||||
}
|
||||
if(!(c >= b || d <= a))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
alternativa3d function checkSphere(sphere:Vector3D) : Boolean
|
||||
{
|
||||
return sphere.x + sphere.w > this.minX && sphere.x - sphere.w < this.maxX && sphere.y + sphere.w > this.minY && sphere.y - sphere.w < this.maxY && sphere.z + sphere.w > this.minZ && sphere.z - sphere.w < this.maxZ;
|
||||
}
|
||||
|
||||
public function intersectRay(origin:Vector3D, direction:Vector3D) : Boolean
|
||||
{
|
||||
var a:Number = NaN;
|
||||
var b:Number = NaN;
|
||||
var c:Number = NaN;
|
||||
var d:Number = NaN;
|
||||
if(origin.x >= this.minX && origin.x <= this.maxX && origin.y >= this.minY && origin.y <= this.maxY && origin.z >= this.minZ && origin.z <= this.maxZ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(origin.x < this.minX && direction.x <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(origin.x > this.maxX && direction.x >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(origin.y < this.minY && direction.y <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(origin.y > this.maxY && direction.y >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(origin.z < this.minZ && direction.z <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(origin.z > this.maxZ && direction.z >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(direction.x > 0.000001)
|
||||
{
|
||||
a = (this.minX - origin.x) / direction.x;
|
||||
b = (this.maxX - origin.x) / direction.x;
|
||||
}
|
||||
else if(direction.x < -0.000001)
|
||||
{
|
||||
a = (this.maxX - origin.x) / direction.x;
|
||||
b = (this.minX - origin.x) / direction.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = -1e+22;
|
||||
b = 1e+22;
|
||||
}
|
||||
if(direction.y > 0.000001)
|
||||
{
|
||||
c = (this.minY - origin.y) / direction.y;
|
||||
d = (this.maxY - origin.y) / direction.y;
|
||||
}
|
||||
else if(direction.y < -0.000001)
|
||||
{
|
||||
c = (this.maxY - origin.y) / direction.y;
|
||||
d = (this.minY - origin.y) / direction.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = -1e+22;
|
||||
d = 1e+22;
|
||||
}
|
||||
if(c >= b || d <= a)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(c < a)
|
||||
{
|
||||
if(d < b)
|
||||
{
|
||||
b = d;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = c;
|
||||
if(d < b)
|
||||
{
|
||||
b = d;
|
||||
}
|
||||
}
|
||||
if(direction.z > 0.000001)
|
||||
{
|
||||
c = (this.minZ - origin.z) / direction.z;
|
||||
d = (this.maxZ - origin.z) / direction.z;
|
||||
}
|
||||
else if(direction.z < -0.000001)
|
||||
{
|
||||
c = (this.maxZ - origin.z) / direction.z;
|
||||
d = (this.minZ - origin.z) / direction.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = -1e+22;
|
||||
d = 1e+22;
|
||||
}
|
||||
if(c >= b || d <= a)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function clone() : BoundBox
|
||||
{
|
||||
var res:BoundBox = new BoundBox();
|
||||
res.minX = this.minX;
|
||||
res.minY = this.minY;
|
||||
res.minZ = this.minZ;
|
||||
res.maxX = this.maxX;
|
||||
res.maxY = this.maxY;
|
||||
res.maxZ = this.maxZ;
|
||||
return res;
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[BoundBox " + "X:[" + this.minX.toFixed(2) + ", " + this.maxX.toFixed(2) + "] Y:[" + this.minY.toFixed(2) + ", " + this.maxY.toFixed(2) + "] Z:[" + this.minZ.toFixed(2) + ", " + this.maxZ.toFixed(2) + "]]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,908 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.DisplayObject;
|
||||
import flash.display.Sprite;
|
||||
import flash.display.Stage3D;
|
||||
import flash.display.StageAlign;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.events.Event;
|
||||
import flash.geom.Point;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.system.System;
|
||||
import flash.text.TextField;
|
||||
import flash.text.TextFieldAutoSize;
|
||||
import flash.text.TextFormat;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
import flash.utils.getQualifiedClassName;
|
||||
import flash.utils.getQualifiedSuperclassName;
|
||||
import flash.utils.getTimer;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Camera3D extends Object3D
|
||||
{
|
||||
public var view:View;
|
||||
|
||||
public var fov:Number = 1.5707963267948966;
|
||||
|
||||
public var nearClipping:Number;
|
||||
|
||||
public var farClipping:Number;
|
||||
|
||||
public var orthographic:Boolean = false;
|
||||
|
||||
alternativa3d var focalLength:Number;
|
||||
|
||||
alternativa3d var m0:Number;
|
||||
|
||||
alternativa3d var m5:Number;
|
||||
|
||||
alternativa3d var m10:Number;
|
||||
|
||||
alternativa3d var m14:Number;
|
||||
|
||||
alternativa3d var correctionX:Number;
|
||||
|
||||
alternativa3d var correctionY:Number;
|
||||
|
||||
alternativa3d var lights:Vector.<Light3D> = new Vector.<Light3D>();
|
||||
|
||||
alternativa3d var lightsLength:int = 0;
|
||||
|
||||
alternativa3d var ambient:Vector.<Number> = new Vector.<Number>(4);
|
||||
|
||||
alternativa3d var childLights:Vector.<Light3D> = new Vector.<Light3D>();
|
||||
|
||||
alternativa3d var frustum:CullingPlane;
|
||||
|
||||
alternativa3d var origins:Vector.<Vector3D> = new Vector.<Vector3D>();
|
||||
|
||||
alternativa3d var directions:Vector.<Vector3D> = new Vector.<Vector3D>();
|
||||
|
||||
alternativa3d var raysLength:int = 0;
|
||||
|
||||
alternativa3d var occluders:Vector.<Occluder> = new Vector.<Occluder>();
|
||||
|
||||
alternativa3d var occludersLength:int = 0;
|
||||
|
||||
alternativa3d var context3D:Context3D;
|
||||
|
||||
alternativa3d var renderer:Renderer;
|
||||
|
||||
alternativa3d var numDraws:int;
|
||||
|
||||
alternativa3d var numTriangles:int;
|
||||
|
||||
public var debug:Boolean = false;
|
||||
|
||||
private var debugSet:Object = new Object();
|
||||
|
||||
private var _diagram:Sprite = createDiagram();
|
||||
|
||||
public var fpsUpdatePeriod:int = 10;
|
||||
|
||||
public var timerUpdatePeriod:int = 10;
|
||||
|
||||
private var fpsTextField:TextField;
|
||||
|
||||
private var memoryTextField:TextField;
|
||||
|
||||
private var drawsTextField:TextField;
|
||||
|
||||
private var trianglesTextField:TextField;
|
||||
|
||||
private var timerTextField:TextField;
|
||||
|
||||
private var graph:Bitmap;
|
||||
|
||||
private var rect:Rectangle;
|
||||
|
||||
private var _diagramAlign:String = "TR";
|
||||
|
||||
private var _diagramHorizontalMargin:Number = 2;
|
||||
|
||||
private var _diagramVerticalMargin:Number = 2;
|
||||
|
||||
private var fpsUpdateCounter:int;
|
||||
|
||||
private var previousFrameTime:int;
|
||||
|
||||
private var previousPeriodTime:int;
|
||||
|
||||
private var maxMemory:int;
|
||||
|
||||
private var timerUpdateCounter:int;
|
||||
|
||||
private var timeSum:int;
|
||||
|
||||
private var timeCount:int;
|
||||
|
||||
private var timer:int;
|
||||
|
||||
public function Camera3D(nearClipping:Number, farClipping:Number)
|
||||
{
|
||||
super();
|
||||
this.nearClipping = nearClipping;
|
||||
this.farClipping = farClipping;
|
||||
this.alternativa3d::renderer = new Renderer();
|
||||
this.alternativa3d::frustum = new CullingPlane();
|
||||
this.alternativa3d::frustum.next = new CullingPlane();
|
||||
this.alternativa3d::frustum.next.next = new CullingPlane();
|
||||
this.alternativa3d::frustum.next.next.next = new CullingPlane();
|
||||
this.alternativa3d::frustum.next.next.next.next = new CullingPlane();
|
||||
this.alternativa3d::frustum.next.next.next.next.next = new CullingPlane();
|
||||
}
|
||||
|
||||
public function render(stage3D:Stage3D) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var light:Light3D = null;
|
||||
var root:Object3D = null;
|
||||
var childLightsLength:int = 0;
|
||||
if(stage3D == null)
|
||||
{
|
||||
throw new TypeError("Parameter stage3D must be non-null.");
|
||||
}
|
||||
this.alternativa3d::numDraws = 0;
|
||||
this.alternativa3d::numTriangles = 0;
|
||||
this.alternativa3d::occludersLength = 0;
|
||||
this.alternativa3d::lightsLength = 0;
|
||||
this.alternativa3d::ambient[0] = 0;
|
||||
this.alternativa3d::ambient[1] = 0;
|
||||
this.alternativa3d::ambient[2] = 0;
|
||||
this.alternativa3d::ambient[3] = 1;
|
||||
this.alternativa3d::context3D = stage3D.context3D;
|
||||
if(this.alternativa3d::context3D != null && this.view != null && this.alternativa3d::renderer != null && (this.view.stage != null || this.view.name_gJ != null))
|
||||
{
|
||||
this.alternativa3d::renderer.alternativa3d::camera = this;
|
||||
this.alternativa3d::calculateProjection(this.view.name_qj,this.view.alternativa3d::_height);
|
||||
this.view.alternativa3d::prepareToRender(stage3D,this.alternativa3d::context3D);
|
||||
if(alternativa3d::transformChanged)
|
||||
{
|
||||
alternativa3d::composeTransforms();
|
||||
}
|
||||
alternativa3d::localToGlobalTransform.copy(alternativa3d::transform);
|
||||
alternativa3d::globalToLocalTransform.copy(alternativa3d::inverseTransform);
|
||||
for(root = this; root.parent != null; )
|
||||
{
|
||||
root = root.parent;
|
||||
if(root.alternativa3d::transformChanged)
|
||||
{
|
||||
root.alternativa3d::composeTransforms();
|
||||
}
|
||||
alternativa3d::localToGlobalTransform.append(root.alternativa3d::transform);
|
||||
alternativa3d::globalToLocalTransform.prepend(root.alternativa3d::inverseTransform);
|
||||
}
|
||||
this.view.alternativa3d::calculateRays(this);
|
||||
for(i = int(this.alternativa3d::origins.length); i < this.view.alternativa3d::raysLength; i++)
|
||||
{
|
||||
this.alternativa3d::origins[i] = new Vector3D();
|
||||
this.alternativa3d::directions[i] = new Vector3D();
|
||||
}
|
||||
this.alternativa3d::raysLength = this.view.alternativa3d::raysLength;
|
||||
if(root.visible)
|
||||
{
|
||||
root.alternativa3d::cameraToLocalTransform.combine(root.alternativa3d::inverseTransform,alternativa3d::localToGlobalTransform);
|
||||
root.alternativa3d::listening = root.alternativa3d::bubbleListeners != null || root.alternativa3d::captureListeners != null;
|
||||
if(root.boundBox != null)
|
||||
{
|
||||
this.alternativa3d::calculateFrustum(root.alternativa3d::cameraToLocalTransform);
|
||||
root.alternativa3d::culling = root.boundBox.alternativa3d::checkFrustumCulling(this.alternativa3d::frustum,63);
|
||||
}
|
||||
else
|
||||
{
|
||||
root.alternativa3d::culling = 63;
|
||||
}
|
||||
if(root.alternativa3d::culling >= 0)
|
||||
{
|
||||
root.alternativa3d::calculateVisibility(this);
|
||||
}
|
||||
root.alternativa3d::calculateChildrenVisibility(this);
|
||||
for(i = 0; i < this.alternativa3d::lightsLength; i++)
|
||||
{
|
||||
light = this.alternativa3d::lights[i];
|
||||
light.alternativa3d::localToCameraTransform.calculateInversion(light.alternativa3d::cameraToLocalTransform);
|
||||
light.alternativa3d::red = (light.color >> 16 & 0xFF) * light.intensity / 255;
|
||||
light.alternativa3d::green = (light.color >> 8 & 0xFF) * light.intensity / 255;
|
||||
light.alternativa3d::blue = (light.color & 0xFF) * light.intensity / 255;
|
||||
}
|
||||
root.alternativa3d::localToCameraTransform.combine(alternativa3d::globalToLocalTransform,root.alternativa3d::transform);
|
||||
if(root.alternativa3d::culling >= 0 && (root.boundBox == null || this.alternativa3d::occludersLength == 0 || Boolean(root.boundBox.alternativa3d::checkOcclusionCulling(this,root))))
|
||||
{
|
||||
if(root.alternativa3d::listening && root.boundBox != null)
|
||||
{
|
||||
this.alternativa3d::calculateRays(root.alternativa3d::cameraToLocalTransform);
|
||||
root.alternativa3d::listening = root.boundBox.alternativa3d::checkRays(this.alternativa3d::origins,this.alternativa3d::directions,this.alternativa3d::raysLength);
|
||||
}
|
||||
if(this.alternativa3d::lightsLength > 0 && root.alternativa3d::useLights)
|
||||
{
|
||||
if(root.boundBox != null)
|
||||
{
|
||||
childLightsLength = 0;
|
||||
for(i = 0; i < this.alternativa3d::lightsLength; )
|
||||
{
|
||||
light = this.alternativa3d::lights[i];
|
||||
light.name_cl.combine(root.alternativa3d::cameraToLocalTransform,light.alternativa3d::localToCameraTransform);
|
||||
if(light.boundBox == null || light.alternativa3d::checkBound(root))
|
||||
{
|
||||
this.alternativa3d::childLights[childLightsLength] = light;
|
||||
childLightsLength++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
root.alternativa3d::collectDraws(this,this.alternativa3d::childLights,childLightsLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < this.alternativa3d::lightsLength; )
|
||||
{
|
||||
light = this.alternativa3d::lights[i];
|
||||
light.name_cl.combine(root.alternativa3d::cameraToLocalTransform,light.alternativa3d::localToCameraTransform);
|
||||
i++;
|
||||
}
|
||||
root.alternativa3d::collectDraws(this,this.alternativa3d::lights,this.alternativa3d::lightsLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
root.alternativa3d::collectDraws(this,null,0);
|
||||
}
|
||||
}
|
||||
root.alternativa3d::collectChildrenDraws(this,this.alternativa3d::lights,this.alternativa3d::lightsLength);
|
||||
}
|
||||
this.view.alternativa3d::processMouseEvents(this.alternativa3d::context3D,this);
|
||||
this.alternativa3d::renderer.alternativa3d::render(this.alternativa3d::context3D);
|
||||
if(this.view.name_gJ == null)
|
||||
{
|
||||
this.alternativa3d::context3D.present();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::context3D.drawToBitmapData(this.view.name_gJ);
|
||||
this.alternativa3d::context3D.present();
|
||||
}
|
||||
}
|
||||
this.alternativa3d::lights.length = 0;
|
||||
this.alternativa3d::childLights.length = 0;
|
||||
this.alternativa3d::occluders.length = 0;
|
||||
this.alternativa3d::context3D = null;
|
||||
}
|
||||
|
||||
public function projectGlobal(point:Vector3D) : Vector3D
|
||||
{
|
||||
if(this.view == null)
|
||||
{
|
||||
throw new Error("It is necessary to have view set.");
|
||||
}
|
||||
var viewSizeX:Number = this.view.name_qj * 0.5;
|
||||
var viewSizeY:Number = this.view.alternativa3d::_height * 0.5;
|
||||
var focalLength:Number = Math.sqrt(viewSizeX * viewSizeX + viewSizeY * viewSizeY) / Math.tan(this.fov * 0.5);
|
||||
var res:Vector3D = globalToLocal(point);
|
||||
res.x = res.x * focalLength / res.z + viewSizeX;
|
||||
res.y = res.y * focalLength / res.z + viewSizeY;
|
||||
return res;
|
||||
}
|
||||
|
||||
public function calculateRay(origin:Vector3D, direction:Vector3D, viewX:Number, viewY:Number) : void
|
||||
{
|
||||
if(this.view == null)
|
||||
{
|
||||
throw new Error("It is necessary to have view set.");
|
||||
}
|
||||
var viewSizeX:Number = this.view.name_qj * 0.5;
|
||||
var viewSizeY:Number = this.view.alternativa3d::_height * 0.5;
|
||||
var focalLength:Number = Math.sqrt(viewSizeX * viewSizeX + viewSizeY * viewSizeY) / Math.tan(this.fov * 0.5);
|
||||
var dx:Number = viewX - viewSizeX;
|
||||
var dy:Number = viewY - viewSizeY;
|
||||
var ox:Number = dx * this.nearClipping / focalLength;
|
||||
var oy:Number = dy * this.nearClipping / focalLength;
|
||||
var oz:Number = this.nearClipping;
|
||||
if(alternativa3d::transformChanged)
|
||||
{
|
||||
alternativa3d::composeTransforms();
|
||||
}
|
||||
trm.copy(alternativa3d::transform);
|
||||
for(var root:Object3D = this; root.parent != null; )
|
||||
{
|
||||
root = root.parent;
|
||||
if(root.alternativa3d::transformChanged)
|
||||
{
|
||||
root.alternativa3d::composeTransforms();
|
||||
}
|
||||
trm.append(root.alternativa3d::transform);
|
||||
}
|
||||
origin.x = trm.a * ox + trm.b * oy + trm.c * oz + trm.d;
|
||||
origin.y = trm.e * ox + trm.f * oy + trm.g * oz + trm.h;
|
||||
origin.z = trm.i * ox + trm.j * oy + trm.k * oz + trm.l;
|
||||
direction.x = trm.a * dx + trm.b * dy + trm.c * focalLength;
|
||||
direction.y = trm.e * dx + trm.f * dy + trm.g * focalLength;
|
||||
direction.z = trm.i * dx + trm.j * dy + trm.k * focalLength;
|
||||
var directionL:Number = 1 / Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);
|
||||
direction.x *= directionL;
|
||||
direction.y *= directionL;
|
||||
direction.z *= directionL;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Camera3D = new Camera3D(this.nearClipping,this.farClipping);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
this.view = (source as Camera3D).view;
|
||||
}
|
||||
|
||||
alternativa3d function calculateProjection(width:Number, height:Number) : void
|
||||
{
|
||||
var viewSizeX:Number = width * 0.5;
|
||||
var viewSizeY:Number = height * 0.5;
|
||||
this.alternativa3d::focalLength = Math.sqrt(viewSizeX * viewSizeX + viewSizeY * viewSizeY) / Math.tan(this.fov * 0.5);
|
||||
if(!this.orthographic)
|
||||
{
|
||||
this.alternativa3d::m0 = this.alternativa3d::focalLength / viewSizeX;
|
||||
this.alternativa3d::m5 = -this.alternativa3d::focalLength / viewSizeY;
|
||||
this.alternativa3d::m10 = this.farClipping / (this.farClipping - this.nearClipping);
|
||||
this.alternativa3d::m14 = -this.nearClipping * this.alternativa3d::m10;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::m0 = 1 / viewSizeX;
|
||||
this.alternativa3d::m5 = -1 / viewSizeY;
|
||||
this.alternativa3d::m10 = 1 / (this.farClipping - this.nearClipping);
|
||||
this.alternativa3d::m14 = -this.nearClipping * this.alternativa3d::m10;
|
||||
}
|
||||
this.alternativa3d::correctionX = viewSizeX / this.alternativa3d::focalLength;
|
||||
this.alternativa3d::correctionY = viewSizeY / this.alternativa3d::focalLength;
|
||||
}
|
||||
|
||||
alternativa3d function calculateFrustum(transform:Transform3D) : void
|
||||
{
|
||||
var fa:Number = NaN;
|
||||
var fe:Number = NaN;
|
||||
var fi:Number = NaN;
|
||||
var fb:Number = NaN;
|
||||
var ff:Number = NaN;
|
||||
var fj:Number = NaN;
|
||||
var ax:Number = NaN;
|
||||
var ay:Number = NaN;
|
||||
var az:Number = NaN;
|
||||
var bx:Number = NaN;
|
||||
var by:Number = NaN;
|
||||
var bz:Number = NaN;
|
||||
var _loc20_:Number = NaN;
|
||||
var _loc21_:Number = NaN;
|
||||
var nearPlane:CullingPlane = this.alternativa3d::frustum;
|
||||
var farPlane:CullingPlane = nearPlane.next;
|
||||
var leftPlane:CullingPlane = farPlane.next;
|
||||
var rightPlane:CullingPlane = leftPlane.next;
|
||||
var topPlane:CullingPlane = rightPlane.next;
|
||||
var bottomPlane:CullingPlane = topPlane.next;
|
||||
if(!this.orthographic)
|
||||
{
|
||||
fa = transform.a * this.alternativa3d::correctionX;
|
||||
fe = transform.e * this.alternativa3d::correctionX;
|
||||
fi = transform.i * this.alternativa3d::correctionX;
|
||||
fb = transform.b * this.alternativa3d::correctionY;
|
||||
ff = transform.f * this.alternativa3d::correctionY;
|
||||
fj = transform.j * this.alternativa3d::correctionY;
|
||||
nearPlane.x = fj * fe - ff * fi;
|
||||
nearPlane.y = fb * fi - fj * fa;
|
||||
nearPlane.z = ff * fa - fb * fe;
|
||||
nearPlane.offset = (transform.d + transform.c * this.nearClipping) * nearPlane.x + (transform.h + transform.g * this.nearClipping) * nearPlane.y + (transform.l + transform.k * this.nearClipping) * nearPlane.z;
|
||||
farPlane.x = -nearPlane.x;
|
||||
farPlane.y = -nearPlane.y;
|
||||
farPlane.z = -nearPlane.z;
|
||||
farPlane.offset = (transform.d + transform.c * this.farClipping) * farPlane.x + (transform.h + transform.g * this.farClipping) * farPlane.y + (transform.l + transform.k * this.farClipping) * farPlane.z;
|
||||
ax = -fa - fb + transform.c;
|
||||
ay = -fe - ff + transform.g;
|
||||
az = -fi - fj + transform.k;
|
||||
bx = fa - fb + transform.c;
|
||||
by = fe - ff + transform.g;
|
||||
bz = fi - fj + transform.k;
|
||||
topPlane.x = bz * ay - by * az;
|
||||
topPlane.y = bx * az - bz * ax;
|
||||
topPlane.z = by * ax - bx * ay;
|
||||
topPlane.offset = transform.d * topPlane.x + transform.h * topPlane.y + transform.l * topPlane.z;
|
||||
ax = bx;
|
||||
ay = by;
|
||||
az = bz;
|
||||
bx = fa + fb + transform.c;
|
||||
by = fe + ff + transform.g;
|
||||
bz = fi + fj + transform.k;
|
||||
rightPlane.x = bz * ay - by * az;
|
||||
rightPlane.y = bx * az - bz * ax;
|
||||
rightPlane.z = by * ax - bx * ay;
|
||||
rightPlane.offset = transform.d * rightPlane.x + transform.h * rightPlane.y + transform.l * rightPlane.z;
|
||||
ax = bx;
|
||||
ay = by;
|
||||
az = bz;
|
||||
bx = -fa + fb + transform.c;
|
||||
by = -fe + ff + transform.g;
|
||||
bz = -fi + fj + transform.k;
|
||||
bottomPlane.x = bz * ay - by * az;
|
||||
bottomPlane.y = bx * az - bz * ax;
|
||||
bottomPlane.z = by * ax - bx * ay;
|
||||
bottomPlane.offset = transform.d * bottomPlane.x + transform.h * bottomPlane.y + transform.l * bottomPlane.z;
|
||||
ax = bx;
|
||||
ay = by;
|
||||
az = bz;
|
||||
bx = -fa - fb + transform.c;
|
||||
by = -fe - ff + transform.g;
|
||||
bz = -fi - fj + transform.k;
|
||||
leftPlane.x = bz * ay - by * az;
|
||||
leftPlane.y = bx * az - bz * ax;
|
||||
leftPlane.z = by * ax - bx * ay;
|
||||
leftPlane.offset = transform.d * leftPlane.x + transform.h * leftPlane.y + transform.l * leftPlane.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc20_ = this.view.name_qj * 0.5;
|
||||
_loc21_ = this.view.alternativa3d::_height * 0.5;
|
||||
nearPlane.x = transform.j * transform.e - transform.f * transform.i;
|
||||
nearPlane.y = transform.b * transform.i - transform.j * transform.a;
|
||||
nearPlane.z = transform.f * transform.a - transform.b * transform.e;
|
||||
nearPlane.offset = (transform.d + transform.c * this.nearClipping) * nearPlane.x + (transform.h + transform.g * this.nearClipping) * nearPlane.y + (transform.l + transform.k * this.nearClipping) * nearPlane.z;
|
||||
farPlane.x = -nearPlane.x;
|
||||
farPlane.y = -nearPlane.y;
|
||||
farPlane.z = -nearPlane.z;
|
||||
farPlane.offset = (transform.d + transform.c * this.farClipping) * farPlane.x + (transform.h + transform.g * this.farClipping) * farPlane.y + (transform.l + transform.k * this.farClipping) * farPlane.z;
|
||||
topPlane.x = transform.i * transform.g - transform.e * transform.k;
|
||||
topPlane.y = transform.a * transform.k - transform.i * transform.c;
|
||||
topPlane.z = transform.e * transform.c - transform.a * transform.g;
|
||||
topPlane.offset = (transform.d - transform.b * _loc21_) * topPlane.x + (transform.h - transform.f * _loc21_) * topPlane.y + (transform.l - transform.j * _loc21_) * topPlane.z;
|
||||
bottomPlane.x = -topPlane.x;
|
||||
bottomPlane.y = -topPlane.y;
|
||||
bottomPlane.z = -topPlane.z;
|
||||
bottomPlane.offset = (transform.d + transform.b * _loc21_) * bottomPlane.x + (transform.h + transform.f * _loc21_) * bottomPlane.y + (transform.l + transform.j * _loc21_) * bottomPlane.z;
|
||||
leftPlane.x = transform.k * transform.f - transform.g * transform.j;
|
||||
leftPlane.y = transform.c * transform.j - transform.k * transform.b;
|
||||
leftPlane.z = transform.g * transform.b - transform.c * transform.f;
|
||||
leftPlane.offset = (transform.d - transform.a * _loc20_) * leftPlane.x + (transform.h - transform.e * _loc20_) * leftPlane.y + (transform.l - transform.i * _loc20_) * leftPlane.z;
|
||||
rightPlane.x = -leftPlane.x;
|
||||
rightPlane.y = -leftPlane.y;
|
||||
rightPlane.z = -leftPlane.z;
|
||||
rightPlane.offset = (transform.d + transform.a * _loc20_) * rightPlane.x + (transform.h + transform.e * _loc20_) * rightPlane.y + (transform.l + transform.i * _loc20_) * rightPlane.z;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function calculateRays(transform:Transform3D) : void
|
||||
{
|
||||
var o:Vector3D = null;
|
||||
var d:Vector3D = null;
|
||||
var origin:Vector3D = null;
|
||||
var direction:Vector3D = null;
|
||||
for(var i:int = 0; i < this.alternativa3d::raysLength; i++)
|
||||
{
|
||||
o = this.view.name_Cr[i];
|
||||
d = this.view.name_g4[i];
|
||||
origin = this.alternativa3d::origins[i];
|
||||
direction = this.alternativa3d::directions[i];
|
||||
origin.x = transform.a * o.x + transform.b * o.y + transform.c * o.z + transform.d;
|
||||
origin.y = transform.e * o.x + transform.f * o.y + transform.g * o.z + transform.h;
|
||||
origin.z = transform.i * o.x + transform.j * o.y + transform.k * o.z + transform.l;
|
||||
direction.x = transform.a * d.x + transform.b * d.y + transform.c * d.z;
|
||||
direction.y = transform.e * d.x + transform.f * d.y + transform.g * d.z;
|
||||
direction.z = transform.i * d.x + transform.j * d.y + transform.k * d.z;
|
||||
}
|
||||
}
|
||||
|
||||
public function addToDebug(debug:int, objectOrClass:*) : void
|
||||
{
|
||||
if(!this.debugSet[debug])
|
||||
{
|
||||
this.debugSet[debug] = new Dictionary();
|
||||
}
|
||||
this.debugSet[debug][objectOrClass] = true;
|
||||
}
|
||||
|
||||
public function removeFromDebug(debug:int, objectOrClass:*) : void
|
||||
{
|
||||
var key:* = undefined;
|
||||
if(Boolean(this.debugSet[debug]))
|
||||
{
|
||||
delete this.debugSet[debug][objectOrClass];
|
||||
var _loc4_:int = 0;
|
||||
var _loc5_:* = this.debugSet[debug];
|
||||
for(key in _loc5_)
|
||||
{
|
||||
}
|
||||
if(!key)
|
||||
{
|
||||
delete this.debugSet[debug];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function checkInDebug(object:Object3D) : int
|
||||
{
|
||||
var _loc4_:Class = null;
|
||||
var res:int = 0;
|
||||
for(var debug:int = 1; debug <= 512; )
|
||||
{
|
||||
if(Boolean(this.debugSet[debug]))
|
||||
{
|
||||
if(Boolean(this.debugSet[debug][Object3D]) || Boolean(this.debugSet[debug][object]))
|
||||
{
|
||||
res |= debug;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(_loc4_ = getDefinitionByName(getQualifiedClassName(object)) as Class; _loc4_ != Object3D; )
|
||||
{
|
||||
if(Boolean(this.debugSet[debug][_loc4_]))
|
||||
{
|
||||
res |= debug;
|
||||
break;
|
||||
}
|
||||
_loc4_ = Class(getDefinitionByName(getQualifiedSuperclassName(_loc4_)));
|
||||
}
|
||||
}
|
||||
}
|
||||
debug <<= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public function startTimer() : void
|
||||
{
|
||||
this.timer = getTimer();
|
||||
}
|
||||
|
||||
public function stopTimer() : void
|
||||
{
|
||||
this.timeSum += getTimer() - this.timer;
|
||||
++this.timeCount;
|
||||
}
|
||||
|
||||
public function get diagram() : DisplayObject
|
||||
{
|
||||
return this._diagram;
|
||||
}
|
||||
|
||||
public function get diagramAlign() : String
|
||||
{
|
||||
return this._diagramAlign;
|
||||
}
|
||||
|
||||
public function set diagramAlign(value:String) : void
|
||||
{
|
||||
this._diagramAlign = value;
|
||||
this.resizeDiagram();
|
||||
}
|
||||
|
||||
public function get diagramHorizontalMargin() : Number
|
||||
{
|
||||
return this._diagramHorizontalMargin;
|
||||
}
|
||||
|
||||
public function set diagramHorizontalMargin(value:Number) : void
|
||||
{
|
||||
this._diagramHorizontalMargin = value;
|
||||
this.resizeDiagram();
|
||||
}
|
||||
|
||||
public function get diagramVerticalMargin() : Number
|
||||
{
|
||||
return this._diagramVerticalMargin;
|
||||
}
|
||||
|
||||
public function set diagramVerticalMargin(value:Number) : void
|
||||
{
|
||||
this._diagramVerticalMargin = value;
|
||||
this.resizeDiagram();
|
||||
}
|
||||
|
||||
private function createDiagram() : Sprite
|
||||
{
|
||||
var diagram:Sprite = null;
|
||||
diagram = new Sprite();
|
||||
diagram.mouseEnabled = false;
|
||||
diagram.mouseChildren = false;
|
||||
this.fpsTextField = new TextField();
|
||||
this.fpsTextField.defaultTextFormat = new TextFormat("Tahoma",10,13421772);
|
||||
this.fpsTextField.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.fpsTextField.text = "FPS:";
|
||||
this.fpsTextField.selectable = false;
|
||||
this.fpsTextField.x = -3;
|
||||
this.fpsTextField.y = -5;
|
||||
diagram.addChild(this.fpsTextField);
|
||||
this.timerTextField = new TextField();
|
||||
this.timerTextField.defaultTextFormat = new TextFormat("Tahoma",10,26367);
|
||||
this.timerTextField.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.timerTextField.text = "MS:";
|
||||
this.timerTextField.selectable = false;
|
||||
this.timerTextField.x = -3;
|
||||
this.timerTextField.y = 4;
|
||||
diagram.addChild(this.timerTextField);
|
||||
this.memoryTextField = new TextField();
|
||||
this.memoryTextField.defaultTextFormat = new TextFormat("Tahoma",10,13421568);
|
||||
this.memoryTextField.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.memoryTextField.text = "MEM:";
|
||||
this.memoryTextField.selectable = false;
|
||||
this.memoryTextField.x = -3;
|
||||
this.memoryTextField.y = 13;
|
||||
diagram.addChild(this.memoryTextField);
|
||||
this.drawsTextField = new TextField();
|
||||
this.drawsTextField.defaultTextFormat = new TextFormat("Tahoma",10,52224);
|
||||
this.drawsTextField.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.drawsTextField.text = "DRW:";
|
||||
this.drawsTextField.selectable = false;
|
||||
this.drawsTextField.x = -3;
|
||||
this.drawsTextField.y = 22;
|
||||
diagram.addChild(this.drawsTextField);
|
||||
this.trianglesTextField = new TextField();
|
||||
this.trianglesTextField.defaultTextFormat = new TextFormat("Tahoma",10,16724736);
|
||||
this.trianglesTextField.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.trianglesTextField.text = "TRI:";
|
||||
this.trianglesTextField.selectable = false;
|
||||
this.trianglesTextField.x = -3;
|
||||
this.trianglesTextField.y = 31;
|
||||
diagram.addChild(this.trianglesTextField);
|
||||
diagram.addEventListener(Event.ADDED_TO_STAGE,function():void
|
||||
{
|
||||
fpsTextField = new TextField();
|
||||
fpsTextField.defaultTextFormat = new TextFormat("Tahoma",10,13421772);
|
||||
fpsTextField.autoSize = TextFieldAutoSize.RIGHT;
|
||||
fpsTextField.text = Number(diagram.stage.frameRate).toFixed(2);
|
||||
fpsTextField.selectable = false;
|
||||
fpsTextField.x = -3;
|
||||
fpsTextField.y = -5;
|
||||
fpsTextField.width = 85;
|
||||
diagram.addChild(fpsTextField);
|
||||
timerTextField = new TextField();
|
||||
timerTextField.defaultTextFormat = new TextFormat("Tahoma",10,26367);
|
||||
timerTextField.autoSize = TextFieldAutoSize.RIGHT;
|
||||
timerTextField.text = "";
|
||||
timerTextField.selectable = false;
|
||||
timerTextField.x = -3;
|
||||
timerTextField.y = 4;
|
||||
timerTextField.width = 85;
|
||||
diagram.addChild(timerTextField);
|
||||
memoryTextField = new TextField();
|
||||
memoryTextField.defaultTextFormat = new TextFormat("Tahoma",10,13421568);
|
||||
memoryTextField.autoSize = TextFieldAutoSize.RIGHT;
|
||||
memoryTextField.text = bytesToString(System.totalMemory);
|
||||
memoryTextField.selectable = false;
|
||||
memoryTextField.x = -3;
|
||||
memoryTextField.y = 13;
|
||||
memoryTextField.width = 85;
|
||||
diagram.addChild(memoryTextField);
|
||||
drawsTextField = new TextField();
|
||||
drawsTextField.defaultTextFormat = new TextFormat("Tahoma",10,52224);
|
||||
drawsTextField.autoSize = TextFieldAutoSize.RIGHT;
|
||||
drawsTextField.text = "0";
|
||||
drawsTextField.selectable = false;
|
||||
drawsTextField.x = -3;
|
||||
drawsTextField.y = 22;
|
||||
drawsTextField.width = 72;
|
||||
diagram.addChild(drawsTextField);
|
||||
trianglesTextField = new TextField();
|
||||
trianglesTextField.defaultTextFormat = new TextFormat("Tahoma",10,16724736);
|
||||
trianglesTextField.autoSize = TextFieldAutoSize.RIGHT;
|
||||
trianglesTextField.text = "0";
|
||||
trianglesTextField.selectable = false;
|
||||
trianglesTextField.x = -3;
|
||||
trianglesTextField.y = 31;
|
||||
trianglesTextField.width = 72;
|
||||
diagram.addChild(trianglesTextField);
|
||||
graph = new Bitmap(new BitmapData(80,40,true,553648127));
|
||||
rect = new Rectangle(0,0,1,40);
|
||||
graph.x = 0;
|
||||
graph.y = 45;
|
||||
diagram.addChild(graph);
|
||||
previousPeriodTime = getTimer();
|
||||
previousFrameTime = previousPeriodTime;
|
||||
fpsUpdateCounter = 0;
|
||||
maxMemory = 0;
|
||||
timerUpdateCounter = 0;
|
||||
timeSum = 0;
|
||||
timeCount = 0;
|
||||
diagram.stage.addEventListener(Event.ENTER_FRAME,updateDiagram,false,-1000);
|
||||
diagram.stage.addEventListener(Event.RESIZE,resizeDiagram,false,-1000);
|
||||
resizeDiagram();
|
||||
});
|
||||
diagram.addEventListener(Event.REMOVED_FROM_STAGE,function():void
|
||||
{
|
||||
diagram.removeChild(fpsTextField);
|
||||
diagram.removeChild(memoryTextField);
|
||||
diagram.removeChild(drawsTextField);
|
||||
diagram.removeChild(trianglesTextField);
|
||||
diagram.removeChild(timerTextField);
|
||||
diagram.removeChild(graph);
|
||||
fpsTextField = null;
|
||||
memoryTextField = null;
|
||||
drawsTextField = null;
|
||||
trianglesTextField = null;
|
||||
timerTextField = null;
|
||||
graph.bitmapData.dispose();
|
||||
graph = null;
|
||||
rect = null;
|
||||
diagram.stage.removeEventListener(Event.ENTER_FRAME,updateDiagram);
|
||||
diagram.stage.removeEventListener(Event.RESIZE,resizeDiagram);
|
||||
});
|
||||
return diagram;
|
||||
}
|
||||
|
||||
private function resizeDiagram(e:Event = null) : void
|
||||
{
|
||||
var coord:Point = null;
|
||||
if(this._diagram.stage != null)
|
||||
{
|
||||
coord = this._diagram.parent.globalToLocal(new Point());
|
||||
if(this._diagramAlign == StageAlign.TOP_LEFT || this._diagramAlign == StageAlign.LEFT || this._diagramAlign == StageAlign.BOTTOM_LEFT)
|
||||
{
|
||||
this._diagram.x = Math.round(coord.x + this._diagramHorizontalMargin);
|
||||
}
|
||||
if(this._diagramAlign == StageAlign.TOP || this._diagramAlign == StageAlign.BOTTOM)
|
||||
{
|
||||
this._diagram.x = Math.round(coord.x + this._diagram.stage.stageWidth / 2 - this.graph.width / 2);
|
||||
}
|
||||
if(this._diagramAlign == StageAlign.TOP_RIGHT || this._diagramAlign == StageAlign.RIGHT || this._diagramAlign == StageAlign.BOTTOM_RIGHT)
|
||||
{
|
||||
this._diagram.x = Math.round(coord.x + this._diagram.stage.stageWidth - this._diagramHorizontalMargin - this.graph.width);
|
||||
}
|
||||
if(this._diagramAlign == StageAlign.TOP_LEFT || this._diagramAlign == StageAlign.TOP || this._diagramAlign == StageAlign.TOP_RIGHT)
|
||||
{
|
||||
this._diagram.y = Math.round(coord.y + this._diagramVerticalMargin);
|
||||
}
|
||||
if(this._diagramAlign == StageAlign.LEFT || this._diagramAlign == StageAlign.RIGHT)
|
||||
{
|
||||
this._diagram.y = Math.round(coord.y + this._diagram.stage.stageHeight / 2 - (this.graph.y + this.graph.height) / 2);
|
||||
}
|
||||
if(this._diagramAlign == StageAlign.BOTTOM_LEFT || this._diagramAlign == StageAlign.BOTTOM || this._diagramAlign == StageAlign.BOTTOM_RIGHT)
|
||||
{
|
||||
this._diagram.y = Math.round(coord.y + this._diagram.stage.stageHeight - this._diagramVerticalMargin - this.graph.y - this.graph.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updateDiagram(e:Event) : void
|
||||
{
|
||||
var value:Number = NaN;
|
||||
var mod:int = 0;
|
||||
var time:int = int(getTimer());
|
||||
var stageFrameRate:int = int(this._diagram.stage.frameRate);
|
||||
if(++this.fpsUpdateCounter == this.fpsUpdatePeriod)
|
||||
{
|
||||
value = 1000 * this.fpsUpdatePeriod / (time - this.previousPeriodTime);
|
||||
if(value > stageFrameRate)
|
||||
{
|
||||
value = stageFrameRate;
|
||||
}
|
||||
mod = value * 100 % 100;
|
||||
this.fpsTextField.text = int(value) + "." + (mod >= 10 ? mod : (mod > 0 ? "0" + mod : "00"));
|
||||
this.previousPeriodTime = time;
|
||||
this.fpsUpdateCounter = 0;
|
||||
}
|
||||
value = 1000 / (time - this.previousFrameTime);
|
||||
if(value > stageFrameRate)
|
||||
{
|
||||
value = stageFrameRate;
|
||||
}
|
||||
this.graph.bitmapData.scroll(1,0);
|
||||
this.graph.bitmapData.fillRect(this.rect,553648127);
|
||||
this.graph.bitmapData.setPixel32(0,40 * (1 - value / stageFrameRate),4291611852);
|
||||
this.previousFrameTime = time;
|
||||
if(++this.timerUpdateCounter == this.timerUpdatePeriod)
|
||||
{
|
||||
if(this.timeCount > 0)
|
||||
{
|
||||
value = this.timeSum / this.timeCount;
|
||||
mod = value * 100 % 100;
|
||||
this.timerTextField.text = int(value) + "." + (mod >= 10 ? mod : (mod > 0 ? "0" + mod : "00"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.timerTextField.text = "";
|
||||
}
|
||||
this.timerUpdateCounter = 0;
|
||||
this.timeSum = 0;
|
||||
this.timeCount = 0;
|
||||
}
|
||||
var memory:int = int(System.totalMemory);
|
||||
value = memory / 1048576;
|
||||
mod = value * 100 % 100;
|
||||
this.memoryTextField.text = int(value) + "." + (mod >= 10 ? mod : (mod > 0 ? "0" + mod : "00"));
|
||||
if(memory > this.maxMemory)
|
||||
{
|
||||
this.maxMemory = memory;
|
||||
}
|
||||
this.graph.bitmapData.setPixel32(0,40 * (1 - memory / this.maxMemory),4291611648);
|
||||
this.drawsTextField.text = this.formatInt(this.alternativa3d::numDraws);
|
||||
this.trianglesTextField.text = this.formatInt(this.alternativa3d::numTriangles);
|
||||
}
|
||||
|
||||
private function formatInt(num:int) : String
|
||||
{
|
||||
var n:int = 0;
|
||||
var s:String = null;
|
||||
if(num < 1000)
|
||||
{
|
||||
return "" + num;
|
||||
}
|
||||
if(num < 1000000)
|
||||
{
|
||||
n = num % 1000;
|
||||
if(n < 10)
|
||||
{
|
||||
s = "00" + n;
|
||||
}
|
||||
else if(n < 100)
|
||||
{
|
||||
s = "0" + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "" + n;
|
||||
}
|
||||
return int(num / 1000) + " " + s;
|
||||
}
|
||||
n = num % 1000000 / 1000;
|
||||
if(n < 10)
|
||||
{
|
||||
s = "00" + n;
|
||||
}
|
||||
else if(n < 100)
|
||||
{
|
||||
s = "0" + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "" + n;
|
||||
}
|
||||
n = num % 1000;
|
||||
if(n < 10)
|
||||
{
|
||||
s += " 00" + n;
|
||||
}
|
||||
else if(n < 100)
|
||||
{
|
||||
s += " 0" + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
s += " " + n;
|
||||
}
|
||||
return int(num / 1000000) + " " + s;
|
||||
}
|
||||
|
||||
private function bytesToString(bytes:int) : String
|
||||
{
|
||||
if(bytes < 1024)
|
||||
{
|
||||
return bytes + "b";
|
||||
}
|
||||
if(bytes < 10240)
|
||||
{
|
||||
return (bytes / 1024).toFixed(2) + "kb";
|
||||
}
|
||||
if(bytes < 102400)
|
||||
{
|
||||
return (bytes / 1024).toFixed(1) + "kb";
|
||||
}
|
||||
if(bytes < 1048576)
|
||||
{
|
||||
return (bytes >> 10) + "kb";
|
||||
}
|
||||
if(bytes < 10485760)
|
||||
{
|
||||
return (bytes / 1048576).toFixed(2);
|
||||
}
|
||||
if(bytes < 104857600)
|
||||
{
|
||||
return (bytes / 1048576).toFixed(1);
|
||||
}
|
||||
return String(bytes >> 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
public class CullingPlane
|
||||
{
|
||||
public static var collector:CullingPlane;
|
||||
|
||||
public var x:Number;
|
||||
|
||||
public var y:Number;
|
||||
|
||||
public var z:Number;
|
||||
|
||||
public var offset:Number;
|
||||
|
||||
public var next:CullingPlane;
|
||||
|
||||
public function CullingPlane()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static function create() : CullingPlane
|
||||
{
|
||||
var res:CullingPlane = null;
|
||||
if(collector != null)
|
||||
{
|
||||
res = collector;
|
||||
collector = res.next;
|
||||
res.next = null;
|
||||
return res;
|
||||
}
|
||||
return new CullingPlane();
|
||||
}
|
||||
|
||||
public function create() : CullingPlane
|
||||
{
|
||||
var res:CullingPlane = null;
|
||||
if(collector != null)
|
||||
{
|
||||
res = collector;
|
||||
collector = res.next;
|
||||
res.next = null;
|
||||
return res;
|
||||
}
|
||||
return new CullingPlane();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.objects.WireFrame;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Debug
|
||||
{
|
||||
public static const BOUNDS:int = 8;
|
||||
|
||||
private static var boundWires:Dictionary = new Dictionary();
|
||||
|
||||
public function Debug()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private static function createBoundWire() : WireFrame
|
||||
{
|
||||
var res:WireFrame = new WireFrame();
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,-0.5,-0.5,0.5,-0.5,-0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,-0.5,-0.5,0.5,0.5,-0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,0.5,-0.5,-0.5,0.5,-0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,0.5,-0.5,-0.5,-0.5,-0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,-0.5,0.5,0.5,-0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,-0.5,0.5,0.5,0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,0.5,0.5,-0.5,0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,0.5,0.5,-0.5,-0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,-0.5,-0.5,-0.5,-0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,-0.5,-0.5,0.5,-0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(0.5,0.5,-0.5,0.5,0.5,0.5);
|
||||
res.alternativa3d::geometry.alternativa3d::addLine(-0.5,0.5,-0.5,-0.5,0.5,0.5);
|
||||
return res;
|
||||
}
|
||||
|
||||
alternativa3d static function drawBoundBox(camera:Camera3D, boundBox:BoundBox, transform:Transform3D, color:int = -1) : void
|
||||
{
|
||||
var boundWire:WireFrame = boundWires[camera.alternativa3d::context3D];
|
||||
if(boundWire == null)
|
||||
{
|
||||
boundWire = createBoundWire();
|
||||
boundWires[camera.alternativa3d::context3D] = boundWire;
|
||||
boundWire.alternativa3d::geometry.upload(camera.alternativa3d::context3D);
|
||||
}
|
||||
boundWire.color = color >= 0 ? uint(color) : 10092288;
|
||||
boundWire.thickness = 1;
|
||||
boundWire.alternativa3d::transform.compose((boundBox.minX + boundBox.maxX) * 0.5,(boundBox.minY + boundBox.maxY) * 0.5,(boundBox.minZ + boundBox.maxZ) * 0.5,0,0,0,boundBox.maxX - boundBox.minX,boundBox.maxY - boundBox.minY,boundBox.maxZ - boundBox.minZ);
|
||||
boundWire.alternativa3d::localToCameraTransform.combine(transform,boundWire.alternativa3d::transform);
|
||||
boundWire.alternativa3d::collectDraws(camera,null,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,368 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DTriangleFace;
|
||||
import flash.display3D.IndexBuffer3D;
|
||||
import flash.display3D.Program3D;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.display3D.textures.TextureBase;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DrawUnit
|
||||
{
|
||||
alternativa3d var next:DrawUnit;
|
||||
|
||||
alternativa3d var object:Object3D;
|
||||
|
||||
alternativa3d var program:Program3D;
|
||||
|
||||
alternativa3d var indexBuffer:IndexBuffer3D;
|
||||
|
||||
alternativa3d var firstIndex:int;
|
||||
|
||||
alternativa3d var numTriangles:int;
|
||||
|
||||
alternativa3d var blendSource:String = "one";
|
||||
|
||||
alternativa3d var blendDestination:String = "zero";
|
||||
|
||||
alternativa3d var culling:String = "front";
|
||||
|
||||
alternativa3d var textures:Vector.<TextureBase> = new Vector.<TextureBase>();
|
||||
|
||||
alternativa3d var name_kR:Vector.<int> = new Vector.<int>();
|
||||
|
||||
alternativa3d var name_Oq:int = 0;
|
||||
|
||||
alternativa3d var vertexBuffers:Vector.<VertexBuffer3D> = new Vector.<VertexBuffer3D>();
|
||||
|
||||
alternativa3d var name_else:Vector.<int> = new Vector.<int>();
|
||||
|
||||
alternativa3d var name_nw:Vector.<int> = new Vector.<int>();
|
||||
|
||||
alternativa3d var name_EL:Vector.<String> = new Vector.<String>();
|
||||
|
||||
alternativa3d var name_3G:int = 0;
|
||||
|
||||
alternativa3d var name_Aq:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
alternativa3d var name_9X:int = 0;
|
||||
|
||||
alternativa3d var name_Cl:Vector.<Number> = new Vector.<Number>(28 * 4,true);
|
||||
|
||||
alternativa3d var name_Kv:int = 0;
|
||||
|
||||
public function DrawUnit()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
alternativa3d function clear() : void
|
||||
{
|
||||
this.alternativa3d::object = null;
|
||||
this.alternativa3d::program = null;
|
||||
this.alternativa3d::indexBuffer = null;
|
||||
this.alternativa3d::blendSource = Context3DBlendFactor.ONE;
|
||||
this.alternativa3d::blendDestination = Context3DBlendFactor.ZERO;
|
||||
this.alternativa3d::culling = Context3DTriangleFace.FRONT;
|
||||
this.alternativa3d::textures.length = 0;
|
||||
this.name_Oq = 0;
|
||||
this.alternativa3d::vertexBuffers.length = 0;
|
||||
this.name_3G = 0;
|
||||
this.name_9X = 0;
|
||||
this.name_Kv = 0;
|
||||
}
|
||||
|
||||
alternativa3d function setTextureAt(sampler:int, texture:TextureBase) : void
|
||||
{
|
||||
if(uint(sampler) > 8)
|
||||
{
|
||||
throw new Error("Sampler index " + sampler + " is out of bounds.");
|
||||
}
|
||||
if(texture == null)
|
||||
{
|
||||
throw new Error("Texture is null");
|
||||
}
|
||||
this.name_kR[this.name_Oq] = sampler;
|
||||
this.alternativa3d::textures[this.name_Oq] = texture;
|
||||
++this.name_Oq;
|
||||
}
|
||||
|
||||
alternativa3d function setVertexBufferAt(index:int, buffer:VertexBuffer3D, bufferOffset:int, format:String) : void
|
||||
{
|
||||
if(uint(index) > 8)
|
||||
{
|
||||
throw new Error("VertexBuffer index " + index + " is out of bounds.");
|
||||
}
|
||||
if(buffer == null)
|
||||
{
|
||||
throw new Error("Buffer is null");
|
||||
}
|
||||
this.name_else[this.name_3G] = index;
|
||||
this.alternativa3d::vertexBuffers[this.name_3G] = buffer;
|
||||
this.name_nw[this.name_3G] = bufferOffset;
|
||||
this.name_EL[this.name_3G] = format;
|
||||
++this.name_3G;
|
||||
}
|
||||
|
||||
alternativa3d function setVertexConstantsFromVector(firstRegister:int, data:Vector.<Number>, numRegisters:int) : void
|
||||
{
|
||||
if(uint(firstRegister + numRegisters) > 128)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + numRegisters > this.name_9X)
|
||||
{
|
||||
this.name_9X = firstRegister + numRegisters;
|
||||
this.name_Aq.length = this.name_9X << 2;
|
||||
}
|
||||
for(var i:int = 0, len:int = numRegisters << 2; i < len; )
|
||||
{
|
||||
this.name_Aq[offset] = data[i];
|
||||
offset++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function setVertexConstantsFromNumbers(firstRegister:int, x:Number, y:Number, z:Number, w:Number = 1) : void
|
||||
{
|
||||
if(uint(firstRegister + 1) > 128)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + 1 > this.name_9X)
|
||||
{
|
||||
this.name_9X = firstRegister + 1;
|
||||
this.name_Aq.length = this.name_9X << 2;
|
||||
}
|
||||
this.name_Aq[offset] = x;
|
||||
offset++;
|
||||
this.name_Aq[offset] = y;
|
||||
offset++;
|
||||
this.name_Aq[offset] = z;
|
||||
offset++;
|
||||
this.name_Aq[offset] = w;
|
||||
}
|
||||
|
||||
alternativa3d function setVertexConstantsFromTransform(firstRegister:int, transform:Transform3D) : void
|
||||
{
|
||||
if(uint(firstRegister + 3) > 128)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + 3 > this.name_9X)
|
||||
{
|
||||
this.name_9X = firstRegister + 3;
|
||||
this.name_Aq.length = this.name_9X << 2;
|
||||
}
|
||||
this.name_Aq[offset] = transform.a;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.b;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.c;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.d;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.e;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.f;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.g;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.h;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.i;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.j;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.k;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.l;
|
||||
}
|
||||
|
||||
alternativa3d function setProjectionConstants(camera:Camera3D, firstRegister:int, transform:Transform3D = null) : void
|
||||
{
|
||||
if(uint(firstRegister + 4) > 128)
|
||||
{
|
||||
throw new Error("Register index is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + 4 > this.name_9X)
|
||||
{
|
||||
this.name_9X = firstRegister + 4;
|
||||
this.name_Aq.length = this.name_9X << 2;
|
||||
}
|
||||
if(transform != null)
|
||||
{
|
||||
this.name_Aq[offset] = transform.a * camera.alternativa3d::m0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.b * camera.alternativa3d::m0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.c * camera.alternativa3d::m0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.d * camera.alternativa3d::m0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.e * camera.alternativa3d::m5;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.f * camera.alternativa3d::m5;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.g * camera.alternativa3d::m5;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.h * camera.alternativa3d::m5;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.i * camera.alternativa3d::m10;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.j * camera.alternativa3d::m10;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.k * camera.alternativa3d::m10;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.l * camera.alternativa3d::m10 + camera.alternativa3d::m14;
|
||||
offset++;
|
||||
if(!camera.orthographic)
|
||||
{
|
||||
this.name_Aq[offset] = transform.i;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.j;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.k;
|
||||
offset++;
|
||||
this.name_Aq[offset] = transform.l;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_Aq[offset] = camera.alternativa3d::m0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = camera.alternativa3d::m5;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = camera.alternativa3d::m10;
|
||||
offset++;
|
||||
this.name_Aq[offset] = camera.alternativa3d::m14;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
if(!camera.orthographic)
|
||||
{
|
||||
this.name_Aq[offset] = 1;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_Aq[offset] = 0;
|
||||
offset++;
|
||||
this.name_Aq[offset] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function setFragmentConstantsFromVector(firstRegister:int, data:Vector.<Number>, numRegisters:int) : void
|
||||
{
|
||||
if(uint(firstRegister + numRegisters) > 28)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + numRegisters > this.name_Kv)
|
||||
{
|
||||
this.name_Kv = firstRegister + numRegisters;
|
||||
}
|
||||
for(var i:int = 0, len:int = numRegisters << 2; i < len; )
|
||||
{
|
||||
this.name_Cl[offset] = data[i];
|
||||
offset++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function setFragmentConstantsFromNumbers(firstRegister:int, x:Number, y:Number, z:Number, w:Number = 1) : void
|
||||
{
|
||||
if(uint(firstRegister + 1) > 28)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + 1 > this.name_Kv)
|
||||
{
|
||||
this.name_Kv = firstRegister + 1;
|
||||
}
|
||||
this.name_Cl[offset] = x;
|
||||
offset++;
|
||||
this.name_Cl[offset] = y;
|
||||
offset++;
|
||||
this.name_Cl[offset] = z;
|
||||
offset++;
|
||||
this.name_Cl[offset] = w;
|
||||
}
|
||||
|
||||
alternativa3d function setFragmentConstantsFromTransform(firstRegister:int, transform:Transform3D) : void
|
||||
{
|
||||
if(uint(firstRegister + 3) > 28)
|
||||
{
|
||||
throw new Error("Register index " + firstRegister + " is out of bounds.");
|
||||
}
|
||||
var offset:int = firstRegister << 2;
|
||||
if(firstRegister + 3 > this.name_Kv)
|
||||
{
|
||||
this.name_Kv = firstRegister + 3;
|
||||
}
|
||||
this.name_Cl[offset] = transform.a;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.b;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.c;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.d;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.e;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.f;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.g;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.h;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.i;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.j;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.k;
|
||||
offset++;
|
||||
this.name_Cl[offset] = transform.l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Light3D extends Object3D
|
||||
{
|
||||
private static var lastLightNumber:uint = 0;
|
||||
|
||||
public var color:uint;
|
||||
|
||||
public var intensity:Number = 1;
|
||||
|
||||
alternativa3d var name_cl:Transform3D = new Transform3D();
|
||||
|
||||
alternativa3d var name_oG:String;
|
||||
|
||||
alternativa3d var red:Number;
|
||||
|
||||
alternativa3d var green:Number;
|
||||
|
||||
alternativa3d var blue:Number;
|
||||
|
||||
public function Light3D()
|
||||
{
|
||||
super();
|
||||
this.name_oG = "l" + lastLightNumber.toString(16);
|
||||
name = "L" + (lastLightNumber++).toString();
|
||||
}
|
||||
|
||||
override alternativa3d function calculateVisibility(camera:Camera3D) : void
|
||||
{
|
||||
if(this.intensity != 0 && this.color > 0)
|
||||
{
|
||||
camera.alternativa3d::lights[camera.alternativa3d::lightsLength] = this;
|
||||
++camera.alternativa3d::lightsLength;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function checkBound(targetObject:Object3D) : Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Light3D = new Light3D();
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
var src:Light3D = source as Light3D;
|
||||
this.color = src.color;
|
||||
this.intensity = src.intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Occluder extends Object3D
|
||||
{
|
||||
public function Occluder()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
override alternativa3d function calculateVisibility(camera:Camera3D) : void
|
||||
{
|
||||
camera.alternativa3d::occluders[camera.alternativa3d::occludersLength] = this;
|
||||
++camera.alternativa3d::occludersLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import flash.geom.Point;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
public class RayIntersectionData
|
||||
{
|
||||
public var object:Object3D;
|
||||
|
||||
public var point:Vector3D;
|
||||
|
||||
public var surface:Surface;
|
||||
|
||||
public var time:Number;
|
||||
|
||||
public var uv:Point;
|
||||
|
||||
public function RayIntersectionData()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[RayIntersectionData " + this.object + ", " + this.point + ", " + this.uv + ", " + this.time + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
public class RenderPriority
|
||||
{
|
||||
public static const SKY:int = 0;
|
||||
|
||||
public static const OPAQUE_SORT:int = 1;
|
||||
|
||||
public static const OPAQUE:int = 2;
|
||||
|
||||
public static const DECALS:int = 3;
|
||||
|
||||
public static const TANK_SHADOW:int = 4;
|
||||
|
||||
public static const TANK_OPAQUE:int = 5;
|
||||
|
||||
public static const SHADOWS:int = 6;
|
||||
|
||||
public static const SHADOWED_LIGHTS:int = 7;
|
||||
|
||||
public static const LIGHTS:int = 8;
|
||||
|
||||
public static const FOG:int = 9;
|
||||
|
||||
public static const TRANSPARENT_SORT:int = 10;
|
||||
|
||||
public static const NEXT_LAYER:int = 11;
|
||||
|
||||
public static const EFFECTS:int = 12;
|
||||
|
||||
public function RenderPriority()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.materials.ShaderProgram;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.display3D.Context3DCompareMode;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.IndexBuffer3D;
|
||||
import flash.display3D.Program3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Renderer
|
||||
{
|
||||
protected static var collector:DrawUnit;
|
||||
|
||||
private static var _usedBuffers:uint = 0;
|
||||
|
||||
private static var _usedTextures:uint = 0;
|
||||
|
||||
alternativa3d var camera:Camera3D;
|
||||
|
||||
alternativa3d var name_T5:Vector.<DrawUnit> = new Vector.<DrawUnit>();
|
||||
|
||||
public function Renderer()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
alternativa3d function render(context:Context3D) : void
|
||||
{
|
||||
var list:DrawUnit = null;
|
||||
var next:DrawUnit = null;
|
||||
var drawUnitsLength:int = int(this.name_T5.length);
|
||||
for(var i:int = 0; i < drawUnitsLength; i++)
|
||||
{
|
||||
list = this.name_T5[i];
|
||||
if(list != null)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case RenderPriority.SKY:
|
||||
context.setDepthTest(false,Context3DCompareMode.ALWAYS);
|
||||
break;
|
||||
case RenderPriority.OPAQUE_SORT:
|
||||
context.setDepthTest(true,Context3DCompareMode.LESS);
|
||||
break;
|
||||
case RenderPriority.OPAQUE:
|
||||
context.setDepthTest(true,Context3DCompareMode.LESS);
|
||||
break;
|
||||
case RenderPriority.TANK_SHADOW:
|
||||
context.setDepthTest(false,Context3DCompareMode.LESS_EQUAL);
|
||||
break;
|
||||
case RenderPriority.TANK_OPAQUE:
|
||||
context.setDepthTest(true,Context3DCompareMode.LESS);
|
||||
break;
|
||||
case RenderPriority.DECALS:
|
||||
context.setDepthTest(false,Context3DCompareMode.LESS_EQUAL);
|
||||
break;
|
||||
case RenderPriority.SHADOWS:
|
||||
context.setDepthTest(false,Context3DCompareMode.EQUAL);
|
||||
break;
|
||||
case RenderPriority.SHADOWED_LIGHTS:
|
||||
context.setDepthTest(false,Context3DCompareMode.EQUAL);
|
||||
break;
|
||||
case RenderPriority.LIGHTS:
|
||||
context.setDepthTest(false,Context3DCompareMode.EQUAL);
|
||||
break;
|
||||
case RenderPriority.FOG:
|
||||
context.setDepthTest(false,Context3DCompareMode.EQUAL);
|
||||
break;
|
||||
case RenderPriority.TRANSPARENT_SORT:
|
||||
if(list.alternativa3d::next != null)
|
||||
{
|
||||
list = this.alternativa3d::sortByAverageZ(list);
|
||||
}
|
||||
context.setDepthTest(false,Context3DCompareMode.LESS);
|
||||
break;
|
||||
case RenderPriority.NEXT_LAYER:
|
||||
context.setDepthTest(false,Context3DCompareMode.ALWAYS);
|
||||
break;
|
||||
case RenderPriority.EFFECTS:
|
||||
if(list.alternativa3d::next != null)
|
||||
{
|
||||
list = this.alternativa3d::sortByAverageZ(list);
|
||||
}
|
||||
context.setDepthTest(false,Context3DCompareMode.LESS);
|
||||
}
|
||||
// Rendering, XXX: this was missing from the decompile so I just coppied the code from latest A3D (8.32)
|
||||
while (list != null) {
|
||||
next = list.next;
|
||||
renderDrawUnit(list, context, camera);
|
||||
// Send to collector
|
||||
list.clear();
|
||||
list.next = collector;
|
||||
collector = list;
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.name_T5.length = 0;
|
||||
}
|
||||
|
||||
alternativa3d function createDrawUnit(object:Object3D, program:Program3D, indexBuffer:IndexBuffer3D, firstIndex:int, numTriangles:int, debugShader:ShaderProgram = null) : DrawUnit
|
||||
{
|
||||
var res:DrawUnit = null;
|
||||
if(collector != null)
|
||||
{
|
||||
res = collector;
|
||||
collector = collector.alternativa3d::next;
|
||||
res.alternativa3d::next = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = new DrawUnit();
|
||||
}
|
||||
res.alternativa3d::object = object;
|
||||
res.alternativa3d::program = program;
|
||||
res.alternativa3d::indexBuffer = indexBuffer;
|
||||
res.alternativa3d::firstIndex = firstIndex;
|
||||
res.alternativa3d::numTriangles = numTriangles;
|
||||
return res;
|
||||
}
|
||||
|
||||
alternativa3d function addDrawUnit(drawUnit:DrawUnit, renderPriority:int) : void
|
||||
{
|
||||
if(renderPriority >= this.name_T5.length)
|
||||
{
|
||||
this.name_T5.length = renderPriority + 1;
|
||||
}
|
||||
drawUnit.alternativa3d::next = this.name_T5[renderPriority];
|
||||
this.name_T5[renderPriority] = drawUnit;
|
||||
}
|
||||
|
||||
protected function renderDrawUnit(drawUnit:DrawUnit, context:Context3D, camera:Camera3D) : void
|
||||
{
|
||||
var bufferIndex:int = 0;
|
||||
var bufferBit:int = 0;
|
||||
var currentBuffers:int = 0;
|
||||
var textureSampler:int = 0;
|
||||
var textureBit:int = 0;
|
||||
var currentTextures:int = 0;
|
||||
context.setBlendFactors(drawUnit.alternativa3d::blendSource,drawUnit.alternativa3d::blendDestination);
|
||||
context.setCulling(drawUnit.alternativa3d::culling);
|
||||
for(var i:int = 0; i < drawUnit.name_3G; i++)
|
||||
{
|
||||
bufferIndex = int(drawUnit.name_else[i]);
|
||||
bufferBit = 1 << bufferIndex;
|
||||
currentBuffers |= bufferBit;
|
||||
_usedBuffers &= ~bufferBit;
|
||||
context.setVertexBufferAt(bufferIndex,drawUnit.alternativa3d::vertexBuffers[i],drawUnit.name_nw[i],drawUnit.name_EL[i]);
|
||||
}
|
||||
if(drawUnit.name_9X > 0)
|
||||
{
|
||||
context.setProgramConstantsFromVector(Context3DProgramType.VERTEX,0,drawUnit.name_Aq,drawUnit.name_9X);
|
||||
}
|
||||
if(drawUnit.name_Kv > 0)
|
||||
{
|
||||
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,0,drawUnit.name_Cl,drawUnit.name_Kv);
|
||||
}
|
||||
for(i = 0; i < drawUnit.name_Oq; )
|
||||
{
|
||||
textureSampler = int(drawUnit.name_kR[i]);
|
||||
textureBit = 1 << textureSampler;
|
||||
currentTextures |= textureBit;
|
||||
_usedTextures &= ~textureBit;
|
||||
context.setTextureAt(textureSampler,drawUnit.alternativa3d::textures[i]);
|
||||
i++;
|
||||
}
|
||||
context.setProgram(drawUnit.alternativa3d::program);
|
||||
for(bufferIndex = 0; _usedBuffers > 0; )
|
||||
{
|
||||
bufferBit = _usedBuffers & 1;
|
||||
_usedBuffers >>= 1;
|
||||
if(Boolean(bufferBit))
|
||||
{
|
||||
context.setVertexBufferAt(bufferIndex,null);
|
||||
}
|
||||
bufferIndex++;
|
||||
}
|
||||
for(textureSampler = 0; _usedTextures > 0; )
|
||||
{
|
||||
textureBit = _usedTextures & 1;
|
||||
_usedTextures >>= 1;
|
||||
if(Boolean(textureBit))
|
||||
{
|
||||
context.setTextureAt(textureSampler,null);
|
||||
}
|
||||
textureSampler++;
|
||||
}
|
||||
context.drawTriangles(drawUnit.alternativa3d::indexBuffer,drawUnit.alternativa3d::firstIndex,drawUnit.alternativa3d::numTriangles);
|
||||
_usedBuffers = currentBuffers;
|
||||
_usedTextures = currentTextures;
|
||||
++camera.alternativa3d::numDraws;
|
||||
camera.alternativa3d::numTriangles += drawUnit.alternativa3d::numTriangles;
|
||||
}
|
||||
|
||||
alternativa3d function sortByAverageZ(list:DrawUnit, direction:Boolean = true) : DrawUnit
|
||||
{
|
||||
var left:DrawUnit = list;
|
||||
var right:DrawUnit = list.alternativa3d::next;
|
||||
while(right != null && right.alternativa3d::next != null)
|
||||
{
|
||||
list = list.alternativa3d::next;
|
||||
right = right.alternativa3d::next.alternativa3d::next;
|
||||
}
|
||||
right = list.alternativa3d::next;
|
||||
list.alternativa3d::next = null;
|
||||
if(left.alternativa3d::next != null)
|
||||
{
|
||||
left = this.alternativa3d::sortByAverageZ(left,direction);
|
||||
}
|
||||
if(right.alternativa3d::next != null)
|
||||
{
|
||||
right = this.alternativa3d::sortByAverageZ(right,direction);
|
||||
}
|
||||
var flag:Boolean = direction ? left.alternativa3d::object.alternativa3d::localToCameraTransform.l > right.alternativa3d::object.alternativa3d::localToCameraTransform.l : left.alternativa3d::object.alternativa3d::localToCameraTransform.l < right.alternativa3d::object.alternativa3d::localToCameraTransform.l;
|
||||
if(flag)
|
||||
{
|
||||
list = left;
|
||||
left = left.alternativa3d::next;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = right;
|
||||
right = right.alternativa3d::next;
|
||||
}
|
||||
var last:DrawUnit = list;
|
||||
while(left != null)
|
||||
{
|
||||
if(right == null)
|
||||
{
|
||||
last.alternativa3d::next = left;
|
||||
return list;
|
||||
}
|
||||
if(flag)
|
||||
{
|
||||
if(direction ? left.alternativa3d::object.alternativa3d::localToCameraTransform.l > right.alternativa3d::object.alternativa3d::localToCameraTransform.l : left.alternativa3d::object.alternativa3d::localToCameraTransform.l < right.alternativa3d::object.alternativa3d::localToCameraTransform.l)
|
||||
{
|
||||
last = left;
|
||||
left = left.alternativa3d::next;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.alternativa3d::next = right;
|
||||
last = right;
|
||||
right = right.alternativa3d::next;
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
else if(direction ? left.alternativa3d::object.alternativa3d::localToCameraTransform.l < right.alternativa3d::object.alternativa3d::localToCameraTransform.l : left.alternativa3d::object.alternativa3d::localToCameraTransform.l > right.alternativa3d::object.alternativa3d::localToCameraTransform.l)
|
||||
{
|
||||
last = right;
|
||||
right = right.alternativa3d::next;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.alternativa3d::next = left;
|
||||
last = left;
|
||||
left = left.alternativa3d::next;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
last.alternativa3d::next = right;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import flash.display3D.Context3D;
|
||||
|
||||
public class Resource
|
||||
{
|
||||
public function Resource()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function get isUploaded() : Boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function upload(context3D:Context3D) : void
|
||||
{
|
||||
throw new Error("Cannot upload without data");
|
||||
}
|
||||
|
||||
public function dispose() : void
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Transform3D
|
||||
{
|
||||
public var a:Number = 1;
|
||||
|
||||
public var b:Number = 0;
|
||||
|
||||
public var c:Number = 0;
|
||||
|
||||
public var d:Number = 0;
|
||||
|
||||
public var e:Number = 0;
|
||||
|
||||
public var f:Number = 1;
|
||||
|
||||
public var g:Number = 0;
|
||||
|
||||
public var h:Number = 0;
|
||||
|
||||
public var i:Number = 0;
|
||||
|
||||
public var j:Number = 0;
|
||||
|
||||
public var k:Number = 1;
|
||||
|
||||
public var l:Number = 0;
|
||||
|
||||
public function Transform3D()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function identity() : void
|
||||
{
|
||||
this.a = 1;
|
||||
this.b = 0;
|
||||
this.c = 0;
|
||||
this.d = 0;
|
||||
this.e = 0;
|
||||
this.f = 1;
|
||||
this.g = 0;
|
||||
this.h = 0;
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
this.k = 1;
|
||||
this.l = 0;
|
||||
}
|
||||
|
||||
public function compose(x:Number, y:Number, z:Number, rotationX:Number, rotationY:Number, rotationZ:Number, scaleX:Number, scaleY:Number, scaleZ:Number) : void
|
||||
{
|
||||
var cosX:Number = Number(Math.cos(rotationX));
|
||||
var sinX:Number = Number(Math.sin(rotationX));
|
||||
var cosY:Number = Number(Math.cos(rotationY));
|
||||
var sinY:Number = Number(Math.sin(rotationY));
|
||||
var cosZ:Number = Number(Math.cos(rotationZ));
|
||||
var sinZ:Number = Number(Math.sin(rotationZ));
|
||||
var cosZsinY:Number = cosZ * sinY;
|
||||
var sinZsinY:Number = sinZ * sinY;
|
||||
var cosYscaleX:Number = cosY * scaleX;
|
||||
var sinXscaleY:Number = sinX * scaleY;
|
||||
var cosXscaleY:Number = cosX * scaleY;
|
||||
var cosXscaleZ:Number = cosX * scaleZ;
|
||||
var sinXscaleZ:Number = sinX * scaleZ;
|
||||
this.a = cosZ * cosYscaleX;
|
||||
this.b = cosZsinY * sinXscaleY - sinZ * cosXscaleY;
|
||||
this.c = cosZsinY * cosXscaleZ + sinZ * sinXscaleZ;
|
||||
this.d = x;
|
||||
this.e = sinZ * cosYscaleX;
|
||||
this.f = sinZsinY * sinXscaleY + cosZ * cosXscaleY;
|
||||
this.g = sinZsinY * cosXscaleZ - cosZ * sinXscaleZ;
|
||||
this.h = y;
|
||||
this.i = -sinY * scaleX;
|
||||
this.j = cosY * sinXscaleY;
|
||||
this.k = cosY * cosXscaleZ;
|
||||
this.l = z;
|
||||
}
|
||||
|
||||
public function composeInverse(x:Number, y:Number, z:Number, rotationX:Number, rotationY:Number, rotationZ:Number, scaleX:Number, scaleY:Number, scaleZ:Number) : void
|
||||
{
|
||||
var cosX:Number = Number(Math.cos(rotationX));
|
||||
var sinX:Number = Number(Math.sin(-rotationX));
|
||||
var cosY:Number = Number(Math.cos(rotationY));
|
||||
var sinY:Number = Number(Math.sin(-rotationY));
|
||||
var cosZ:Number = Number(Math.cos(rotationZ));
|
||||
var sinZ:Number = Number(Math.sin(-rotationZ));
|
||||
var sinXsinY:Number = sinX * sinY;
|
||||
var cosYscaleX:Number = cosY / scaleX;
|
||||
var cosXscaleY:Number = cosX / scaleY;
|
||||
var sinXscaleZ:Number = sinX / scaleZ;
|
||||
var cosXscaleZ:Number = cosX / scaleZ;
|
||||
this.a = cosZ * cosYscaleX;
|
||||
this.b = -sinZ * cosYscaleX;
|
||||
this.c = sinY / scaleX;
|
||||
this.d = -this.a * x - this.b * y - this.c * z;
|
||||
this.e = sinZ * cosXscaleY + sinXsinY * cosZ / scaleY;
|
||||
this.f = cosZ * cosXscaleY - sinXsinY * sinZ / scaleY;
|
||||
this.g = -sinX * cosY / scaleY;
|
||||
this.h = -this.e * x - this.f * y - this.g * z;
|
||||
this.i = sinZ * sinXscaleZ - cosZ * sinY * cosXscaleZ;
|
||||
this.j = cosZ * sinXscaleZ + sinY * sinZ * cosXscaleZ;
|
||||
this.k = cosY * cosXscaleZ;
|
||||
this.l = -this.i * x - this.j * y - this.k * z;
|
||||
}
|
||||
|
||||
public function invert() : void
|
||||
{
|
||||
var ta:Number = this.a;
|
||||
var tb:Number = this.b;
|
||||
var tc:Number = this.c;
|
||||
var td:Number = this.d;
|
||||
var te:Number = this.e;
|
||||
var tf:Number = this.f;
|
||||
var tg:Number = this.g;
|
||||
var th:Number = this.h;
|
||||
var ti:Number = this.i;
|
||||
var tj:Number = this.j;
|
||||
var tk:Number = this.k;
|
||||
var tl:Number = this.l;
|
||||
var det:Number = 1 / (-tc * tf * ti + tb * tg * ti + tc * te * tj - ta * tg * tj - tb * te * tk + ta * tf * tk);
|
||||
this.a = (-tg * tj + tf * tk) * det;
|
||||
this.b = (tc * tj - tb * tk) * det;
|
||||
this.c = (-tc * tf + tb * tg) * det;
|
||||
this.d = (td * tg * tj - tc * th * tj - td * tf * tk + tb * th * tk + tc * tf * tl - tb * tg * tl) * det;
|
||||
this.e = (tg * ti - te * tk) * det;
|
||||
this.f = (-tc * ti + ta * tk) * det;
|
||||
this.g = (tc * te - ta * tg) * det;
|
||||
this.h = (tc * th * ti - td * tg * ti + td * te * tk - ta * th * tk - tc * te * tl + ta * tg * tl) * det;
|
||||
this.i = (-tf * ti + te * tj) * det;
|
||||
this.j = (tb * ti - ta * tj) * det;
|
||||
this.k = (-tb * te + ta * tf) * det;
|
||||
this.l = (td * tf * ti - tb * th * ti - td * te * tj + ta * th * tj + tb * te * tl - ta * tf * tl) * det;
|
||||
}
|
||||
|
||||
public function initFromVector(vector:Vector.<Number>) : void
|
||||
{
|
||||
this.a = vector[0];
|
||||
this.b = vector[1];
|
||||
this.c = vector[2];
|
||||
this.d = vector[3];
|
||||
this.e = vector[4];
|
||||
this.f = vector[5];
|
||||
this.g = vector[6];
|
||||
this.h = vector[7];
|
||||
this.i = vector[8];
|
||||
this.j = vector[9];
|
||||
this.k = vector[10];
|
||||
this.l = vector[11];
|
||||
}
|
||||
|
||||
public function append(transform:Transform3D) : void
|
||||
{
|
||||
var ta:Number = this.a;
|
||||
var tb:Number = this.b;
|
||||
var tc:Number = this.c;
|
||||
var td:Number = this.d;
|
||||
var te:Number = this.e;
|
||||
var tf:Number = this.f;
|
||||
var tg:Number = this.g;
|
||||
var th:Number = this.h;
|
||||
var ti:Number = this.i;
|
||||
var tj:Number = this.j;
|
||||
var tk:Number = this.k;
|
||||
var tl:Number = this.l;
|
||||
this.a = transform.a * ta + transform.b * te + transform.c * ti;
|
||||
this.b = transform.a * tb + transform.b * tf + transform.c * tj;
|
||||
this.c = transform.a * tc + transform.b * tg + transform.c * tk;
|
||||
this.d = transform.a * td + transform.b * th + transform.c * tl + transform.d;
|
||||
this.e = transform.e * ta + transform.f * te + transform.g * ti;
|
||||
this.f = transform.e * tb + transform.f * tf + transform.g * tj;
|
||||
this.g = transform.e * tc + transform.f * tg + transform.g * tk;
|
||||
this.h = transform.e * td + transform.f * th + transform.g * tl + transform.h;
|
||||
this.i = transform.i * ta + transform.j * te + transform.k * ti;
|
||||
this.j = transform.i * tb + transform.j * tf + transform.k * tj;
|
||||
this.k = transform.i * tc + transform.j * tg + transform.k * tk;
|
||||
this.l = transform.i * td + transform.j * th + transform.k * tl + transform.l;
|
||||
}
|
||||
|
||||
public function prepend(transform:Transform3D) : void
|
||||
{
|
||||
var ta:Number = this.a;
|
||||
var tb:Number = this.b;
|
||||
var tc:Number = this.c;
|
||||
var td:Number = this.d;
|
||||
var te:Number = this.e;
|
||||
var tf:Number = this.f;
|
||||
var tg:Number = this.g;
|
||||
var th:Number = this.h;
|
||||
var ti:Number = this.i;
|
||||
var tj:Number = this.j;
|
||||
var tk:Number = this.k;
|
||||
var tl:Number = this.l;
|
||||
this.a = ta * transform.a + tb * transform.e + tc * transform.i;
|
||||
this.b = ta * transform.b + tb * transform.f + tc * transform.j;
|
||||
this.c = ta * transform.c + tb * transform.g + tc * transform.k;
|
||||
this.d = ta * transform.d + tb * transform.h + tc * transform.l + td;
|
||||
this.e = te * transform.a + tf * transform.e + tg * transform.i;
|
||||
this.f = te * transform.b + tf * transform.f + tg * transform.j;
|
||||
this.g = te * transform.c + tf * transform.g + tg * transform.k;
|
||||
this.h = te * transform.d + tf * transform.h + tg * transform.l + th;
|
||||
this.i = ti * transform.a + tj * transform.e + tk * transform.i;
|
||||
this.j = ti * transform.b + tj * transform.f + tk * transform.j;
|
||||
this.k = ti * transform.c + tj * transform.g + tk * transform.k;
|
||||
this.l = ti * transform.d + tj * transform.h + tk * transform.l + tl;
|
||||
}
|
||||
|
||||
public function combine(transformA:Transform3D, transformB:Transform3D) : void
|
||||
{
|
||||
this.a = transformA.a * transformB.a + transformA.b * transformB.e + transformA.c * transformB.i;
|
||||
this.b = transformA.a * transformB.b + transformA.b * transformB.f + transformA.c * transformB.j;
|
||||
this.c = transformA.a * transformB.c + transformA.b * transformB.g + transformA.c * transformB.k;
|
||||
this.d = transformA.a * transformB.d + transformA.b * transformB.h + transformA.c * transformB.l + transformA.d;
|
||||
this.e = transformA.e * transformB.a + transformA.f * transformB.e + transformA.g * transformB.i;
|
||||
this.f = transformA.e * transformB.b + transformA.f * transformB.f + transformA.g * transformB.j;
|
||||
this.g = transformA.e * transformB.c + transformA.f * transformB.g + transformA.g * transformB.k;
|
||||
this.h = transformA.e * transformB.d + transformA.f * transformB.h + transformA.g * transformB.l + transformA.h;
|
||||
this.i = transformA.i * transformB.a + transformA.j * transformB.e + transformA.k * transformB.i;
|
||||
this.j = transformA.i * transformB.b + transformA.j * transformB.f + transformA.k * transformB.j;
|
||||
this.k = transformA.i * transformB.c + transformA.j * transformB.g + transformA.k * transformB.k;
|
||||
this.l = transformA.i * transformB.d + transformA.j * transformB.h + transformA.k * transformB.l + transformA.l;
|
||||
}
|
||||
|
||||
public function calculateInversion(source:Transform3D) : void
|
||||
{
|
||||
var ta:Number = source.a;
|
||||
var tb:Number = source.b;
|
||||
var tc:Number = source.c;
|
||||
var td:Number = source.d;
|
||||
var te:Number = source.e;
|
||||
var tf:Number = source.f;
|
||||
var tg:Number = source.g;
|
||||
var th:Number = source.h;
|
||||
var ti:Number = source.i;
|
||||
var tj:Number = source.j;
|
||||
var tk:Number = source.k;
|
||||
var tl:Number = source.l;
|
||||
var det:Number = 1 / (-tc * tf * ti + tb * tg * ti + tc * te * tj - ta * tg * tj - tb * te * tk + ta * tf * tk);
|
||||
this.a = (-tg * tj + tf * tk) * det;
|
||||
this.b = (tc * tj - tb * tk) * det;
|
||||
this.c = (-tc * tf + tb * tg) * det;
|
||||
this.d = (td * tg * tj - tc * th * tj - td * tf * tk + tb * th * tk + tc * tf * tl - tb * tg * tl) * det;
|
||||
this.e = (tg * ti - te * tk) * det;
|
||||
this.f = (-tc * ti + ta * tk) * det;
|
||||
this.g = (tc * te - ta * tg) * det;
|
||||
this.h = (tc * th * ti - td * tg * ti + td * te * tk - ta * th * tk - tc * te * tl + ta * tg * tl) * det;
|
||||
this.i = (-tf * ti + te * tj) * det;
|
||||
this.j = (tb * ti - ta * tj) * det;
|
||||
this.k = (-tb * te + ta * tf) * det;
|
||||
this.l = (td * tf * ti - tb * th * ti - td * te * tj + ta * th * tj + tb * te * tl - ta * tf * tl) * det;
|
||||
}
|
||||
|
||||
public function copy(source:Transform3D) : void
|
||||
{
|
||||
this.a = source.a;
|
||||
this.b = source.b;
|
||||
this.c = source.c;
|
||||
this.d = source.d;
|
||||
this.e = source.e;
|
||||
this.f = source.f;
|
||||
this.g = source.g;
|
||||
this.h = source.h;
|
||||
this.i = source.i;
|
||||
this.j = source.j;
|
||||
this.k = source.k;
|
||||
this.l = source.l;
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[Transform3D" + " a:" + this.a.toFixed(3) + " b:" + this.b.toFixed(3) + " c:" + this.a.toFixed(3) + " d:" + this.d.toFixed(3) + " e:" + this.e.toFixed(3) + " f:" + this.f.toFixed(3) + " g:" + this.a.toFixed(3) + " h:" + this.h.toFixed(3) + " i:" + this.i.toFixed(3) + " j:" + this.j.toFixed(3) + " k:" + this.a.toFixed(3) + " l:" + this.l.toFixed(3) + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.display3D.Context3DVertexBufferFormat;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class VertexAttributes
|
||||
{
|
||||
public static const POSITION:uint = 1;
|
||||
|
||||
public static const NORMAL:uint = 2;
|
||||
|
||||
public static const TANGENT4:uint = 3;
|
||||
|
||||
public static const JOINTS:Vector.<uint> = Vector.<uint>([4,5,6,7]);
|
||||
|
||||
public static const TEXCOORDS:Vector.<uint> = Vector.<uint>([8,9,10,11,12,13,14,15]);
|
||||
|
||||
alternativa3d static const FORMATS:Array = [Context3DVertexBufferFormat.FLOAT_1,Context3DVertexBufferFormat.FLOAT_3,Context3DVertexBufferFormat.FLOAT_3,Context3DVertexBufferFormat.FLOAT_4,Context3DVertexBufferFormat.FLOAT_4,Context3DVertexBufferFormat.FLOAT_4,Context3DVertexBufferFormat.FLOAT_4,Context3DVertexBufferFormat.FLOAT_4,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2,Context3DVertexBufferFormat.FLOAT_2];
|
||||
|
||||
public function VertexAttributes()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static function getAttributeStride(attribute:int) : int
|
||||
{
|
||||
switch(alternativa3d::FORMATS[attribute])
|
||||
{
|
||||
case Context3DVertexBufferFormat.FLOAT_1:
|
||||
return 1;
|
||||
case Context3DVertexBufferFormat.FLOAT_2:
|
||||
return 2;
|
||||
case Context3DVertexBufferFormat.FLOAT_3:
|
||||
return 3;
|
||||
case Context3DVertexBufferFormat.FLOAT_4:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package alternativa.engine3d.core
|
||||
{
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class VertexStream
|
||||
{
|
||||
public var buffer:VertexBuffer3D;
|
||||
|
||||
public var attributes:Array;
|
||||
|
||||
public var data:ByteArray;
|
||||
|
||||
public function VertexStream()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,78 +0,0 @@
|
||||
package alternativa.engine3d.core.events
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import flash.events.Event;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Event3D extends Event
|
||||
{
|
||||
public static const ADDED:String = "added3D";
|
||||
|
||||
public static const REMOVED:String = "removed3D";
|
||||
|
||||
alternativa3d var name_5E:Object3D;
|
||||
|
||||
alternativa3d var name_Kh:Object3D;
|
||||
|
||||
alternativa3d var name_iJ:Boolean;
|
||||
|
||||
alternativa3d var name_VE:uint = 3;
|
||||
|
||||
alternativa3d var stop:Boolean = false;
|
||||
|
||||
alternativa3d var name_XD:Boolean = false;
|
||||
|
||||
public function Event3D(type:String, bubbles:Boolean = true)
|
||||
{
|
||||
super(type,bubbles);
|
||||
this.name_iJ = bubbles;
|
||||
}
|
||||
|
||||
override public function get bubbles() : Boolean
|
||||
{
|
||||
return this.name_iJ;
|
||||
}
|
||||
|
||||
override public function get eventPhase() : uint
|
||||
{
|
||||
return this.name_VE;
|
||||
}
|
||||
|
||||
override public function get target() : Object
|
||||
{
|
||||
return this.name_5E;
|
||||
}
|
||||
|
||||
override public function get currentTarget() : Object
|
||||
{
|
||||
return this.name_Kh;
|
||||
}
|
||||
|
||||
override public function stopPropagation() : void
|
||||
{
|
||||
this.alternativa3d::stop = true;
|
||||
}
|
||||
|
||||
override public function stopImmediatePropagation() : void
|
||||
{
|
||||
this.name_XD = true;
|
||||
}
|
||||
|
||||
override public function clone() : Event
|
||||
{
|
||||
var result:Event3D = new Event3D(type,this.name_iJ);
|
||||
result.name_5E = this.name_5E;
|
||||
result.name_Kh = this.name_Kh;
|
||||
result.name_VE = this.name_VE;
|
||||
return result;
|
||||
}
|
||||
|
||||
override public function toString() : String
|
||||
{
|
||||
return formatToString("Event3D","type","bubbles","eventPhase");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package alternativa.engine3d.core.events
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import flash.events.Event;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class MouseEvent3D extends Event3D
|
||||
{
|
||||
public static const CLICK:String = "click3D";
|
||||
|
||||
public static const DOUBLE_CLICK:String = "doubleClick3D";
|
||||
|
||||
public static const MOUSE_DOWN:String = "mouseDown3D";
|
||||
|
||||
public static const MOUSE_UP:String = "mouseUp3D";
|
||||
|
||||
public static const MOUSE_OVER:String = "mouseOver3D";
|
||||
|
||||
public static const MOUSE_OUT:String = "mouseOut3D";
|
||||
|
||||
public static const ROLL_OVER:String = "rollOver3D";
|
||||
|
||||
public static const ROLL_OUT:String = "rollOut3D";
|
||||
|
||||
public static const MOUSE_MOVE:String = "mouseMove3D";
|
||||
|
||||
public static const MOUSE_WHEEL:String = "mouseWheel3D";
|
||||
|
||||
public var ctrlKey:Boolean;
|
||||
|
||||
public var altKey:Boolean;
|
||||
|
||||
public var shiftKey:Boolean;
|
||||
|
||||
public var buttonDown:Boolean;
|
||||
|
||||
public var delta:int;
|
||||
|
||||
public var relatedObject:Object3D;
|
||||
|
||||
public var localX:Number;
|
||||
|
||||
public var localY:Number;
|
||||
|
||||
public var localZ:Number;
|
||||
|
||||
alternativa3d var name_BX:Surface;
|
||||
|
||||
public function MouseEvent3D(type:String, bubbles:Boolean = true, localX:Number = NaN, localY:Number = NaN, localZ:Number = NaN, relatedObject:Object3D = null, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, buttonDown:Boolean = false, delta:int = 0)
|
||||
{
|
||||
super(type,bubbles);
|
||||
this.localX = localX;
|
||||
this.localY = localY;
|
||||
this.localZ = localZ;
|
||||
this.relatedObject = relatedObject;
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.altKey = altKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.buttonDown = buttonDown;
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
public function get surface() : Surface
|
||||
{
|
||||
return this.name_BX;
|
||||
}
|
||||
|
||||
override public function clone() : Event
|
||||
{
|
||||
return new MouseEvent3D(type,name_iJ,this.localX,this.localY,this.localZ,this.relatedObject,this.ctrlKey,this.altKey,this.shiftKey,this.buttonDown,this.delta);
|
||||
}
|
||||
|
||||
override public function toString() : String
|
||||
{
|
||||
return formatToString("MouseEvent3D","type","bubbles","eventPhase","localX","localY","localZ","relatedObject","altKey","ctrlKey","shiftKey","buttonDown","delta");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,826 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import flash.utils.*;
|
||||
|
||||
public class AGALMiniAssembler
|
||||
{
|
||||
private static var initialized:Boolean = false;
|
||||
|
||||
private static const OPMAP:Dictionary = new Dictionary();
|
||||
|
||||
private static const REGMAP:Dictionary = new Dictionary();
|
||||
|
||||
private static const SAMPLEMAP:Dictionary = new Dictionary();
|
||||
|
||||
private static const MAX_NESTING:int = 4;
|
||||
|
||||
private static const MAX_OPCODES:int = 256;
|
||||
|
||||
private static const FRAGMENT:String = "fragment";
|
||||
|
||||
private static const VERTEX:String = "vertex";
|
||||
|
||||
private static const SAMPLER_DIM_SHIFT:uint = 12;
|
||||
|
||||
private static const SAMPLER_SPECIAL_SHIFT:uint = 16;
|
||||
|
||||
private static const SAMPLER_REPEAT_SHIFT:uint = 20;
|
||||
|
||||
private static const SAMPLER_MIPMAP_SHIFT:uint = 24;
|
||||
|
||||
private static const SAMPLER_FILTER_SHIFT:uint = 28;
|
||||
|
||||
private static const REG_WRITE:uint = 1;
|
||||
|
||||
private static const REG_READ:uint = 2;
|
||||
|
||||
private static const REG_FRAG:uint = 32;
|
||||
|
||||
private static const REG_VERT:uint = 64;
|
||||
|
||||
private static const OP_SCALAR:uint = 1;
|
||||
|
||||
private static const OP_INC_NEST:uint = 2;
|
||||
|
||||
private static const OP_DEC_NEST:uint = 4;
|
||||
|
||||
private static const OP_SPECIAL_TEX:uint = 8;
|
||||
|
||||
private static const OP_SPECIAL_MATRIX:uint = 16;
|
||||
|
||||
private static const OP_FRAG_ONLY:uint = 32;
|
||||
|
||||
private static const OP_VERT_ONLY:uint = 64;
|
||||
|
||||
private static const OP_NO_DEST:uint = 128;
|
||||
|
||||
private static const MOV:String = "mov";
|
||||
|
||||
private static const ADD:String = "add";
|
||||
|
||||
private static const SUB:String = "sub";
|
||||
|
||||
private static const MUL:String = "mul";
|
||||
|
||||
private static const DIV:String = "div";
|
||||
|
||||
private static const RCP:String = "rcp";
|
||||
|
||||
private static const MIN:String = "min";
|
||||
|
||||
private static const MAX:String = "max";
|
||||
|
||||
private static const FRC:String = "frc";
|
||||
|
||||
private static const SQT:String = "sqt";
|
||||
|
||||
private static const RSQ:String = "rsq";
|
||||
|
||||
private static const POW:String = "pow";
|
||||
|
||||
private static const LOG:String = "log";
|
||||
|
||||
private static const EXP:String = "exp";
|
||||
|
||||
private static const NRM:String = "nrm";
|
||||
|
||||
private static const SIN:String = "sin";
|
||||
|
||||
private static const COS:String = "cos";
|
||||
|
||||
private static const CRS:String = "crs";
|
||||
|
||||
private static const DP3:String = "dp3";
|
||||
|
||||
private static const DP4:String = "dp4";
|
||||
|
||||
private static const ABS:String = "abs";
|
||||
|
||||
private static const NEG:String = "neg";
|
||||
|
||||
private static const SAT:String = "sat";
|
||||
|
||||
private static const M33:String = "m33";
|
||||
|
||||
private static const M44:String = "m44";
|
||||
|
||||
private static const M34:String = "m34";
|
||||
|
||||
private static const IFZ:String = "ifz";
|
||||
|
||||
private static const INZ:String = "inz";
|
||||
|
||||
private static const IFE:String = "ife";
|
||||
|
||||
private static const INE:String = "ine";
|
||||
|
||||
private static const IFG:String = "ifg";
|
||||
|
||||
private static const IFL:String = "ifl";
|
||||
|
||||
private static const IEG:String = "ieg";
|
||||
|
||||
private static const IEL:String = "iel";
|
||||
|
||||
private static const ELS:String = "els";
|
||||
|
||||
private static const EIF:String = "eif";
|
||||
|
||||
private static const REP:String = "rep";
|
||||
|
||||
private static const ERP:String = "erp";
|
||||
|
||||
private static const BRK:String = "brk";
|
||||
|
||||
private static const KIL:String = "kil";
|
||||
|
||||
private static const TEX:String = "tex";
|
||||
|
||||
private static const SGE:String = "sge";
|
||||
|
||||
private static const SLT:String = "slt";
|
||||
|
||||
private static const SGN:String = "sgn";
|
||||
|
||||
private static const VA:String = "va";
|
||||
|
||||
private static const VC:String = "vc";
|
||||
|
||||
private static const VT:String = "vt";
|
||||
|
||||
private static const OP:String = "op";
|
||||
|
||||
private static const V:String = "v";
|
||||
|
||||
private static const FC:String = "fc";
|
||||
|
||||
private static const FT:String = "ft";
|
||||
|
||||
private static const FS:String = "fs";
|
||||
|
||||
private static const OC:String = "oc";
|
||||
|
||||
private static const D2:String = "2d";
|
||||
|
||||
private static const D3:String = "3d";
|
||||
|
||||
private static const CUBE:String = "cube";
|
||||
|
||||
private static const MIPNEAREST:String = "mipnearest";
|
||||
|
||||
private static const MIPLINEAR:String = "miplinear";
|
||||
|
||||
private static const MIPNONE:String = "mipnone";
|
||||
|
||||
private static const NOMIP:String = "nomip";
|
||||
|
||||
private static const NEAREST:String = "nearest";
|
||||
|
||||
private static const LINEAR:String = "linear";
|
||||
|
||||
private static const CENTROID:String = "centroid";
|
||||
|
||||
private static const SINGLE:String = "single";
|
||||
|
||||
private static const DEPTH:String = "depth";
|
||||
|
||||
private static const REPEAT:String = "repeat";
|
||||
|
||||
private static const WRAP:String = "wrap";
|
||||
|
||||
private static const CLAMP:String = "clamp";
|
||||
|
||||
private var name_0e:ByteArray = null;
|
||||
|
||||
private var name_iF:String = "";
|
||||
|
||||
private var name_9J:Boolean = false;
|
||||
|
||||
public function AGALMiniAssembler(debugging:Boolean = false)
|
||||
{
|
||||
super();
|
||||
this.name_9J = debugging;
|
||||
if(!initialized)
|
||||
{
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
private static function init() : void
|
||||
{
|
||||
initialized = true;
|
||||
OPMAP[MOV] = new OpCode(MOV,2,0,0);
|
||||
OPMAP[ADD] = new OpCode(ADD,3,1,0);
|
||||
OPMAP[SUB] = new OpCode(SUB,3,2,0);
|
||||
OPMAP[MUL] = new OpCode(MUL,3,3,0);
|
||||
OPMAP[DIV] = new OpCode(DIV,3,4,0);
|
||||
OPMAP[RCP] = new OpCode(RCP,2,5,0);
|
||||
OPMAP[MIN] = new OpCode(MIN,3,6,0);
|
||||
OPMAP[MAX] = new OpCode(MAX,3,7,0);
|
||||
OPMAP[FRC] = new OpCode(FRC,2,8,0);
|
||||
OPMAP[SQT] = new OpCode(SQT,2,9,0);
|
||||
OPMAP[RSQ] = new OpCode(RSQ,2,10,0);
|
||||
OPMAP[POW] = new OpCode(POW,3,11,0);
|
||||
OPMAP[LOG] = new OpCode(LOG,2,12,0);
|
||||
OPMAP[EXP] = new OpCode(EXP,2,13,0);
|
||||
OPMAP[NRM] = new OpCode(NRM,2,14,0);
|
||||
OPMAP[SIN] = new OpCode(SIN,2,15,0);
|
||||
OPMAP[COS] = new OpCode(COS,2,16,0);
|
||||
OPMAP[CRS] = new OpCode(CRS,3,17,0);
|
||||
OPMAP[DP3] = new OpCode(DP3,3,18,0);
|
||||
OPMAP[DP4] = new OpCode(DP4,3,19,0);
|
||||
OPMAP[ABS] = new OpCode(ABS,2,20,0);
|
||||
OPMAP[NEG] = new OpCode(NEG,2,21,0);
|
||||
OPMAP[SAT] = new OpCode(SAT,2,22,0);
|
||||
OPMAP[M33] = new OpCode(M33,3,23,OP_SPECIAL_MATRIX);
|
||||
OPMAP[M44] = new OpCode(M44,3,24,OP_SPECIAL_MATRIX);
|
||||
OPMAP[M34] = new OpCode(M34,3,25,OP_SPECIAL_MATRIX);
|
||||
OPMAP[IFZ] = new OpCode(IFZ,1,26,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[INZ] = new OpCode(INZ,1,27,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[IFE] = new OpCode(IFE,2,28,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[INE] = new OpCode(INE,2,29,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[IFG] = new OpCode(IFG,2,30,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[IFL] = new OpCode(IFL,2,31,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[IEG] = new OpCode(IEG,2,32,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[IEL] = new OpCode(IEL,2,33,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[ELS] = new OpCode(ELS,0,34,OP_NO_DEST | OP_INC_NEST | OP_DEC_NEST);
|
||||
OPMAP[EIF] = new OpCode(EIF,0,35,OP_NO_DEST | OP_DEC_NEST);
|
||||
OPMAP[REP] = new OpCode(REP,1,36,OP_NO_DEST | OP_INC_NEST | OP_SCALAR);
|
||||
OPMAP[ERP] = new OpCode(ERP,0,37,OP_NO_DEST | OP_DEC_NEST);
|
||||
OPMAP[BRK] = new OpCode(BRK,0,38,OP_NO_DEST);
|
||||
OPMAP[KIL] = new OpCode(KIL,1,39,OP_NO_DEST | OP_FRAG_ONLY);
|
||||
OPMAP[TEX] = new OpCode(TEX,3,40,OP_FRAG_ONLY | OP_SPECIAL_TEX);
|
||||
OPMAP[SGE] = new OpCode(SGE,3,41,0);
|
||||
OPMAP[SLT] = new OpCode(SLT,3,42,0);
|
||||
OPMAP[SGN] = new OpCode(SGN,2,43,0);
|
||||
REGMAP[VA] = new Register(VA,"vertex attribute",0,7,REG_VERT | REG_READ);
|
||||
REGMAP[VC] = new Register(VC,"vertex constant",1,127,REG_VERT | REG_READ);
|
||||
REGMAP[VT] = new Register(VT,"vertex temporary",2,7,REG_VERT | REG_WRITE | REG_READ);
|
||||
REGMAP[OP] = new Register(OP,"vertex output",3,0,REG_VERT | REG_WRITE);
|
||||
REGMAP[V] = new Register(V,"varying",4,7,REG_VERT | REG_FRAG | REG_READ | REG_WRITE);
|
||||
REGMAP[FC] = new Register(FC,"fragment constant",1,27,REG_FRAG | REG_READ);
|
||||
REGMAP[FT] = new Register(FT,"fragment temporary",2,7,REG_FRAG | REG_WRITE | REG_READ);
|
||||
REGMAP[FS] = new Register(FS,"texture sampler",5,7,REG_FRAG | REG_READ);
|
||||
REGMAP[OC] = new Register(OC,"fragment output",3,0,REG_FRAG | REG_WRITE);
|
||||
SAMPLEMAP[D2] = new Sampler(D2,SAMPLER_DIM_SHIFT,0);
|
||||
SAMPLEMAP[D3] = new Sampler(D3,SAMPLER_DIM_SHIFT,2);
|
||||
SAMPLEMAP[CUBE] = new Sampler(CUBE,SAMPLER_DIM_SHIFT,1);
|
||||
SAMPLEMAP[MIPNEAREST] = new Sampler(MIPNEAREST,SAMPLER_MIPMAP_SHIFT,1);
|
||||
SAMPLEMAP[MIPLINEAR] = new Sampler(MIPLINEAR,SAMPLER_MIPMAP_SHIFT,2);
|
||||
SAMPLEMAP[MIPNONE] = new Sampler(MIPNONE,SAMPLER_MIPMAP_SHIFT,0);
|
||||
SAMPLEMAP[NOMIP] = new Sampler(NOMIP,SAMPLER_MIPMAP_SHIFT,0);
|
||||
SAMPLEMAP[NEAREST] = new Sampler(NEAREST,SAMPLER_FILTER_SHIFT,0);
|
||||
SAMPLEMAP[LINEAR] = new Sampler(LINEAR,SAMPLER_FILTER_SHIFT,1);
|
||||
SAMPLEMAP[CENTROID] = new Sampler(CENTROID,SAMPLER_SPECIAL_SHIFT,1 << 0);
|
||||
SAMPLEMAP[SINGLE] = new Sampler(SINGLE,SAMPLER_SPECIAL_SHIFT,1 << 1);
|
||||
SAMPLEMAP[DEPTH] = new Sampler(DEPTH,SAMPLER_SPECIAL_SHIFT,1 << 2);
|
||||
SAMPLEMAP[REPEAT] = new Sampler(REPEAT,SAMPLER_REPEAT_SHIFT,1);
|
||||
SAMPLEMAP[WRAP] = new Sampler(WRAP,SAMPLER_REPEAT_SHIFT,1);
|
||||
SAMPLEMAP[CLAMP] = new Sampler(CLAMP,SAMPLER_REPEAT_SHIFT,0);
|
||||
}
|
||||
|
||||
public function get error() : String
|
||||
{
|
||||
return this.name_iF;
|
||||
}
|
||||
|
||||
public function get agalcode() : ByteArray
|
||||
{
|
||||
return this.name_0e;
|
||||
}
|
||||
|
||||
public function assemble(mode:String, source:String, verbose:Boolean = false) : ByteArray
|
||||
{
|
||||
var i:int = 0;
|
||||
var line:String = null;
|
||||
var startcomment:int = 0;
|
||||
var optsi:int = 0;
|
||||
var opts:Array = null;
|
||||
var opCode:Array = null;
|
||||
var opFound:OpCode = null;
|
||||
var regs:Array = null;
|
||||
var badreg:Boolean = false;
|
||||
var pad:uint = 0;
|
||||
var regLength:uint = 0;
|
||||
var j:int = 0;
|
||||
var isRelative:Boolean = false;
|
||||
var relreg:Array = null;
|
||||
var res:Array = null;
|
||||
var regFound:Register = null;
|
||||
var idxmatch:Array = null;
|
||||
var regidx:uint = 0;
|
||||
var regmask:uint = 0;
|
||||
var maskmatch:Array = null;
|
||||
var isDest:Boolean = false;
|
||||
var isSampler:Boolean = false;
|
||||
var reltype:uint = 0;
|
||||
var relsel:uint = 0;
|
||||
var reloffset:int = 0;
|
||||
var cv:uint = 0;
|
||||
var maskLength:uint = 0;
|
||||
var k:int = 0;
|
||||
var relname:Array = null;
|
||||
var regFoundRel:Register = null;
|
||||
var selmatch:Array = null;
|
||||
var relofs:Array = null;
|
||||
var samplerbits:uint = 0;
|
||||
var optsLength:uint = 0;
|
||||
var bias:Number = NaN;
|
||||
var optfound:Sampler = null;
|
||||
var dbgLine:String = null;
|
||||
var agalLength:uint = 0;
|
||||
var index:uint = 0;
|
||||
var byteStr:String = null;
|
||||
var start:uint = uint(getTimer());
|
||||
this.name_0e = new ByteArray();
|
||||
this.name_iF = "";
|
||||
var isFrag:Boolean = false;
|
||||
if(mode == FRAGMENT)
|
||||
{
|
||||
isFrag = true;
|
||||
}
|
||||
else if(mode != VERTEX)
|
||||
{
|
||||
this.name_iF = "ERROR: mode needs to be \"" + FRAGMENT + "\" or \"" + VERTEX + "\" but is \"" + mode + "\".";
|
||||
}
|
||||
this.agalcode.endian = Endian.LITTLE_ENDIAN;
|
||||
this.agalcode.writeByte(160);
|
||||
this.agalcode.writeUnsignedInt(1);
|
||||
this.agalcode.writeByte(161);
|
||||
this.agalcode.writeByte(isFrag ? 1 : 0);
|
||||
var lines:Array = source.replace(/[\f\n\r\v]+/g,"\n").split("\n");
|
||||
var nest:int = 0;
|
||||
var nops:int = 0;
|
||||
var lng:int = int(lines.length);
|
||||
i = 0;
|
||||
while(i < lng && this.name_iF == "")
|
||||
{
|
||||
line = new String(lines[i]);
|
||||
startcomment = int(line.search("//"));
|
||||
if(startcomment != -1)
|
||||
{
|
||||
line = line.slice(0,startcomment);
|
||||
}
|
||||
optsi = int(line.search(/<.*>/g));
|
||||
if(optsi != -1)
|
||||
{
|
||||
opts = line.slice(optsi).match(/([\w\.\-\+]+)/gi);
|
||||
line = line.slice(0,optsi);
|
||||
}
|
||||
opCode = line.match(/^\w{3}/ig);
|
||||
opFound = OPMAP[opCode[0]];
|
||||
if(this.name_9J)
|
||||
{
|
||||
trace(opFound);
|
||||
}
|
||||
if(opFound == null)
|
||||
{
|
||||
if(line.length >= 3)
|
||||
{
|
||||
trace("warning: bad line " + i + ": " + lines[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line = line.slice(line.search(opFound.name) + opFound.name.length);
|
||||
if(Boolean(opFound.flags & OP_DEC_NEST))
|
||||
{
|
||||
nest--;
|
||||
if(nest < 0)
|
||||
{
|
||||
this.name_iF = "error: conditional closes without open.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(Boolean(opFound.flags & OP_INC_NEST))
|
||||
{
|
||||
nest++;
|
||||
if(nest > MAX_NESTING)
|
||||
{
|
||||
this.name_iF = "error: nesting to deep, maximum allowed is " + MAX_NESTING + ".";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(Boolean(opFound.flags & OP_FRAG_ONLY) && !isFrag)
|
||||
{
|
||||
this.name_iF = "error: opcode is only allowed in fragment programs.";
|
||||
break;
|
||||
}
|
||||
if(verbose)
|
||||
{
|
||||
trace("emit opcode=" + opFound);
|
||||
}
|
||||
this.agalcode.writeUnsignedInt(opFound.emitCode);
|
||||
nops++;
|
||||
if(nops > MAX_OPCODES)
|
||||
{
|
||||
this.name_iF = "error: too many opcodes. maximum is " + MAX_OPCODES + ".";
|
||||
break;
|
||||
}
|
||||
regs = line.match(/vc\[([vof][actps]?)(\d*)?(\.[xyzw](\+\d{1,3})?)?\](\.[xyzw]{1,4})?|([vof][actps]?)(\d*)?(\.[xyzw]{1,4})?/gi);
|
||||
if(regs.length != opFound.numRegister)
|
||||
{
|
||||
this.name_iF = "error: wrong number of operands. found " + regs.length + " but expected " + opFound.numRegister + ".";
|
||||
break;
|
||||
}
|
||||
badreg = false;
|
||||
pad = uint(64 + 64 + 32);
|
||||
regLength = uint(regs.length);
|
||||
for(j = 0; j < regLength; j++)
|
||||
{
|
||||
isRelative = false;
|
||||
relreg = regs[j].match(/\[.*\]/ig);
|
||||
if(relreg.length > 0)
|
||||
{
|
||||
regs[j] = regs[j].replace(relreg[0],"0");
|
||||
if(verbose)
|
||||
{
|
||||
trace("IS REL");
|
||||
}
|
||||
isRelative = true;
|
||||
}
|
||||
res = regs[j].match(/^\b[A-Za-z]{1,2}/ig);
|
||||
regFound = REGMAP[res[0]];
|
||||
if(this.name_9J)
|
||||
{
|
||||
trace(regFound);
|
||||
}
|
||||
if(regFound == null)
|
||||
{
|
||||
this.name_iF = "error: could not parse operand " + j + " (" + regs[j] + ").";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
if(isFrag)
|
||||
{
|
||||
if(!(regFound.flags & REG_FRAG))
|
||||
{
|
||||
this.name_iF = "error: register operand " + j + " (" + regs[j] + ") only allowed in vertex programs.";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
if(isRelative)
|
||||
{
|
||||
this.name_iF = "error: register operand " + j + " (" + regs[j] + ") relative adressing not allowed in fragment programs.";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(!(regFound.flags & REG_VERT))
|
||||
{
|
||||
this.name_iF = "error: register operand " + j + " (" + regs[j] + ") only allowed in fragment programs.";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
regs[j] = regs[j].slice(regs[j].search(regFound.name) + regFound.name.length);
|
||||
idxmatch = isRelative ? relreg[0].match(/\d+/) : regs[j].match(/\d+/);
|
||||
regidx = 0;
|
||||
if(Boolean(idxmatch))
|
||||
{
|
||||
regidx = uint(uint(idxmatch[0]));
|
||||
}
|
||||
if(regFound.range < regidx)
|
||||
{
|
||||
this.name_iF = "error: register operand " + j + " (" + regs[j] + ") index exceeds limit of " + (regFound.range + 1) + ".";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
regmask = 0;
|
||||
maskmatch = regs[j].match(/(\.[xyzw]{1,4})/);
|
||||
isDest = j == 0 && !(opFound.flags & OP_NO_DEST);
|
||||
isSampler = j == 2 && Boolean(opFound.flags & OP_SPECIAL_TEX);
|
||||
reltype = 0;
|
||||
relsel = 0;
|
||||
reloffset = 0;
|
||||
if(isDest && isRelative)
|
||||
{
|
||||
this.name_iF = "error: relative can not be destination";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
if(Boolean(maskmatch))
|
||||
{
|
||||
regmask = 0;
|
||||
maskLength = uint(maskmatch[0].length);
|
||||
for(k = 1; k < maskLength; k++)
|
||||
{
|
||||
cv = maskmatch[0].charCodeAt(k) - "x".charCodeAt(0);
|
||||
if(cv > 2)
|
||||
{
|
||||
cv = 3;
|
||||
}
|
||||
if(isDest)
|
||||
{
|
||||
regmask |= 1 << cv;
|
||||
}
|
||||
else
|
||||
{
|
||||
regmask |= cv << (k - 1 << 1);
|
||||
}
|
||||
}
|
||||
if(!isDest)
|
||||
{
|
||||
while(k <= 4)
|
||||
{
|
||||
regmask |= cv << (k - 1 << 1);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
regmask = isDest ? 15 : 228;
|
||||
}
|
||||
if(isRelative)
|
||||
{
|
||||
relname = relreg[0].match(/[A-Za-z]{1,2}/ig);
|
||||
regFoundRel = REGMAP[relname[0]];
|
||||
if(regFoundRel == null)
|
||||
{
|
||||
this.name_iF = "error: bad index register";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
reltype = regFoundRel.emitCode;
|
||||
selmatch = relreg[0].match(/(\.[xyzw]{1,1})/);
|
||||
if(selmatch.length == 0)
|
||||
{
|
||||
this.name_iF = "error: bad index register select";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
relsel = selmatch[0].charCodeAt(1) - "x".charCodeAt(0);
|
||||
if(relsel > 2)
|
||||
{
|
||||
relsel = 3;
|
||||
}
|
||||
relofs = relreg[0].match(/\+\d{1,3}/ig);
|
||||
if(relofs.length > 0)
|
||||
{
|
||||
reloffset = int(relofs[0]);
|
||||
}
|
||||
if(reloffset < 0 || reloffset > 255)
|
||||
{
|
||||
this.name_iF = "error: index offset " + reloffset + " out of bounds. [0..255]";
|
||||
badreg = true;
|
||||
break;
|
||||
}
|
||||
if(verbose)
|
||||
{
|
||||
trace("RELATIVE: type=" + reltype + "==" + relname[0] + " sel=" + relsel + "==" + selmatch[0] + " idx=" + regidx + " offset=" + reloffset);
|
||||
}
|
||||
}
|
||||
if(verbose)
|
||||
{
|
||||
trace(" emit argcode=" + regFound + "[" + regidx + "][" + regmask + "]");
|
||||
}
|
||||
if(isDest)
|
||||
{
|
||||
this.agalcode.writeShort(regidx);
|
||||
this.agalcode.writeByte(regmask);
|
||||
this.agalcode.writeByte(regFound.emitCode);
|
||||
pad -= 32;
|
||||
}
|
||||
else if(isSampler)
|
||||
{
|
||||
if(verbose)
|
||||
{
|
||||
trace(" emit sampler");
|
||||
}
|
||||
samplerbits = 5;
|
||||
optsLength = uint(opts.length);
|
||||
bias = 0;
|
||||
for(k = 0; k < optsLength; k++)
|
||||
{
|
||||
if(verbose)
|
||||
{
|
||||
trace(" opt: " + opts[k]);
|
||||
}
|
||||
optfound = SAMPLEMAP[opts[k]];
|
||||
if(optfound == null)
|
||||
{
|
||||
bias = Number(Number(opts[k]));
|
||||
if(verbose)
|
||||
{
|
||||
trace(" bias: " + bias);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(optfound.flag != SAMPLER_SPECIAL_SHIFT)
|
||||
{
|
||||
samplerbits &= ~(15 << optfound.flag);
|
||||
}
|
||||
samplerbits |= uint(optfound.mask) << uint(optfound.flag);
|
||||
}
|
||||
}
|
||||
this.agalcode.writeShort(regidx);
|
||||
this.agalcode.writeByte(int(bias * 8));
|
||||
this.agalcode.writeByte(0);
|
||||
this.agalcode.writeUnsignedInt(samplerbits);
|
||||
if(verbose)
|
||||
{
|
||||
trace(" bits: " + (samplerbits - 5));
|
||||
}
|
||||
pad -= 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(j == 0)
|
||||
{
|
||||
this.agalcode.writeUnsignedInt(0);
|
||||
pad -= 32;
|
||||
}
|
||||
this.agalcode.writeShort(regidx);
|
||||
this.agalcode.writeByte(reloffset);
|
||||
this.agalcode.writeByte(regmask);
|
||||
this.agalcode.writeByte(regFound.emitCode);
|
||||
this.agalcode.writeByte(reltype);
|
||||
this.agalcode.writeShort(isRelative ? relsel | 1 << 15 : 0);
|
||||
pad -= 64;
|
||||
}
|
||||
}
|
||||
for(j = 0; j < pad; )
|
||||
{
|
||||
this.agalcode.writeByte(0);
|
||||
j += 8;
|
||||
}
|
||||
if(badreg)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(this.name_iF != "")
|
||||
{
|
||||
this.name_iF += "\n at line " + i + " " + lines[i];
|
||||
this.agalcode.length = 0;
|
||||
trace(this.name_iF);
|
||||
}
|
||||
if(this.name_9J)
|
||||
{
|
||||
dbgLine = "generated bytecode:";
|
||||
agalLength = uint(this.agalcode.length);
|
||||
for(index = 0; index < agalLength; index++)
|
||||
{
|
||||
if(!(index % 16))
|
||||
{
|
||||
dbgLine += "\n";
|
||||
}
|
||||
if(!(index % 4))
|
||||
{
|
||||
dbgLine += " ";
|
||||
}
|
||||
byteStr = this.agalcode[index].toString(16);
|
||||
if(byteStr.length < 2)
|
||||
{
|
||||
byteStr = "0" + byteStr;
|
||||
}
|
||||
dbgLine += byteStr;
|
||||
}
|
||||
trace(dbgLine);
|
||||
}
|
||||
if(verbose)
|
||||
{
|
||||
trace("AGALMiniAssembler.assemble time: " + (getTimer() - start) / 1000 + "s");
|
||||
}
|
||||
return this.agalcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OpCode
|
||||
{
|
||||
private var _emitCode:uint;
|
||||
|
||||
private var _flags:uint;
|
||||
|
||||
private var _name:String;
|
||||
|
||||
private var _numRegister:uint;
|
||||
|
||||
public function OpCode(name:String, numRegister:uint, emitCode:uint, flags:uint)
|
||||
{
|
||||
super();
|
||||
this._name = name;
|
||||
this._numRegister = numRegister;
|
||||
this._emitCode = emitCode;
|
||||
this._flags = flags;
|
||||
}
|
||||
|
||||
public function get emitCode() : uint
|
||||
{
|
||||
return this._emitCode;
|
||||
}
|
||||
|
||||
public function get flags() : uint
|
||||
{
|
||||
return this._flags;
|
||||
}
|
||||
|
||||
public function get name() : String
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public function get numRegister() : uint
|
||||
{
|
||||
return this._numRegister;
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[OpCode name=\"" + this._name + "\", numRegister=" + this._numRegister + ", emitCode=" + this._emitCode + ", flags=" + this._flags + "]";
|
||||
}
|
||||
}
|
||||
|
||||
class Register
|
||||
{
|
||||
private var _emitCode:uint;
|
||||
|
||||
private var _name:String;
|
||||
|
||||
private var _longName:String;
|
||||
|
||||
private var _flags:uint;
|
||||
|
||||
private var _range:uint;
|
||||
|
||||
public function Register(name:String, longName:String, emitCode:uint, range:uint, flags:uint)
|
||||
{
|
||||
super();
|
||||
this._name = name;
|
||||
this._longName = longName;
|
||||
this._emitCode = emitCode;
|
||||
this._range = range;
|
||||
this._flags = flags;
|
||||
}
|
||||
|
||||
public function get emitCode() : uint
|
||||
{
|
||||
return this._emitCode;
|
||||
}
|
||||
|
||||
public function get longName() : String
|
||||
{
|
||||
return this._longName;
|
||||
}
|
||||
|
||||
public function get name() : String
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public function get flags() : uint
|
||||
{
|
||||
return this._flags;
|
||||
}
|
||||
|
||||
public function get range() : uint
|
||||
{
|
||||
return this._range;
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[Register name=\"" + this._name + "\", longName=\"" + this._longName + "\", emitCode=" + this._emitCode + ", range=" + this._range + ", flags=" + this._flags + "]";
|
||||
}
|
||||
}
|
||||
|
||||
class Sampler
|
||||
{
|
||||
private var _flag:uint;
|
||||
|
||||
private var _mask:uint;
|
||||
|
||||
private var _name:String;
|
||||
|
||||
public function Sampler(name:String, flag:uint, mask:uint)
|
||||
{
|
||||
super();
|
||||
this._name = name;
|
||||
this._flag = flag;
|
||||
this._mask = mask;
|
||||
}
|
||||
|
||||
public function get flag() : uint
|
||||
{
|
||||
return this._flag;
|
||||
}
|
||||
|
||||
public function get mask() : uint
|
||||
{
|
||||
return this._mask;
|
||||
}
|
||||
|
||||
public function get name() : String
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public function toString() : String
|
||||
{
|
||||
return "[Sampler name=\"" + this._name + "\", flag=\"" + this._flag + "\", mask=" + this.mask + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import flash.display3D.textures.TextureBase;
|
||||
|
||||
public class Particle
|
||||
{
|
||||
public static var collector:Particle;
|
||||
|
||||
public var diffuse:TextureBase;
|
||||
|
||||
public var opacity:TextureBase;
|
||||
|
||||
public var blendSource:String;
|
||||
|
||||
public var blendDestination:String;
|
||||
|
||||
public var x:Number;
|
||||
|
||||
public var y:Number;
|
||||
|
||||
public var z:Number;
|
||||
|
||||
public var rotation:Number;
|
||||
|
||||
public var width:Number;
|
||||
|
||||
public var height:Number;
|
||||
|
||||
public var originX:Number;
|
||||
|
||||
public var originY:Number;
|
||||
|
||||
public var name_q:Number;
|
||||
|
||||
public var name_Ts:Number;
|
||||
|
||||
public var name_ej:Number;
|
||||
|
||||
public var name_W5:Number;
|
||||
|
||||
public var red:Number;
|
||||
|
||||
public var green:Number;
|
||||
|
||||
public var blue:Number;
|
||||
|
||||
public var alpha:Number;
|
||||
|
||||
public var next:Particle;
|
||||
|
||||
public function Particle()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static function create() : Particle
|
||||
{
|
||||
var res:Particle = null;
|
||||
if(collector != null)
|
||||
{
|
||||
res = collector;
|
||||
collector = collector.next;
|
||||
res.next = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = new Particle();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParticleEffect
|
||||
{
|
||||
private static var randomNumbers:Vector.<Number>;
|
||||
|
||||
private static const randomNumbersCount:int = 1000;
|
||||
|
||||
private static const vector:Vector3D = new Vector3D();
|
||||
|
||||
public var name:String;
|
||||
|
||||
public var scale:Number = 1;
|
||||
|
||||
public var boundBox:BoundBox;
|
||||
|
||||
alternativa3d var next:ParticleEffect;
|
||||
|
||||
alternativa3d var name_implements:ParticleEffect;
|
||||
|
||||
alternativa3d var system:ParticleSystem;
|
||||
|
||||
alternativa3d var startTime:Number;
|
||||
|
||||
alternativa3d var lifeTime:Number = 1.7976931348623157e+308;
|
||||
|
||||
alternativa3d var particleList:Particle;
|
||||
|
||||
alternativa3d var aabb:BoundBox;
|
||||
|
||||
alternativa3d var name_M7:Vector3D;
|
||||
|
||||
protected var name_cF:Vector3D;
|
||||
|
||||
protected var name_gV:Vector.<Number>;
|
||||
|
||||
protected var name_lB:Vector.<Vector3D>;
|
||||
|
||||
protected var name_ib:Vector.<Vector3D>;
|
||||
|
||||
protected var name_Nz:Vector.<Function>;
|
||||
|
||||
protected var name_kf:int = 0;
|
||||
|
||||
private var name_TK:int;
|
||||
|
||||
private var name_hs:int;
|
||||
|
||||
private var name_G1:Vector3D;
|
||||
|
||||
private var name_Q2:Vector3D;
|
||||
|
||||
public function ParticleEffect()
|
||||
{
|
||||
var i:int = 0;
|
||||
this.alternativa3d::aabb = new BoundBox();
|
||||
this.name_gV = new Vector.<Number>();
|
||||
this.name_lB = new Vector.<Vector3D>();
|
||||
this.name_ib = new Vector.<Vector3D>();
|
||||
this.name_Nz = new Vector.<Function>();
|
||||
this.name_G1 = new Vector3D(0,0,0);
|
||||
this.name_Q2 = new Vector3D(0,0,1);
|
||||
super();
|
||||
if(randomNumbers == null)
|
||||
{
|
||||
randomNumbers = new Vector.<Number>();
|
||||
for(i = 0; i < randomNumbersCount; randomNumbers[i] = Math.random(),i++)
|
||||
{
|
||||
}
|
||||
}
|
||||
this.name_TK = Math.random() * randomNumbersCount;
|
||||
}
|
||||
|
||||
public function get position() : Vector3D
|
||||
{
|
||||
return this.name_G1.clone();
|
||||
}
|
||||
|
||||
public function set position(value:Vector3D) : void
|
||||
{
|
||||
this.name_G1.x = value.x;
|
||||
this.name_G1.y = value.y;
|
||||
this.name_G1.z = value.z;
|
||||
this.name_G1.w = value.w;
|
||||
if(this.alternativa3d::system != null)
|
||||
{
|
||||
this.alternativa3d::setPositionKeys(this.alternativa3d::system.alternativa3d::getTime() - this.alternativa3d::startTime);
|
||||
}
|
||||
}
|
||||
|
||||
public function get direction() : Vector3D
|
||||
{
|
||||
return this.name_Q2.clone();
|
||||
}
|
||||
|
||||
public function set direction(value:Vector3D) : void
|
||||
{
|
||||
this.name_Q2.x = value.x;
|
||||
this.name_Q2.y = value.y;
|
||||
this.name_Q2.z = value.z;
|
||||
this.name_Q2.w = value.w;
|
||||
if(this.alternativa3d::system != null)
|
||||
{
|
||||
this.alternativa3d::setDirectionKeys(this.alternativa3d::system.alternativa3d::getTime() - this.alternativa3d::startTime);
|
||||
}
|
||||
}
|
||||
|
||||
public function stop() : void
|
||||
{
|
||||
var time:Number = this.alternativa3d::system.alternativa3d::getTime() - this.alternativa3d::startTime;
|
||||
for(var i:int = 0; i < this.name_kf; )
|
||||
{
|
||||
if(time < this.name_gV[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this.name_kf = i;
|
||||
}
|
||||
|
||||
protected function get particleSystem() : ParticleSystem
|
||||
{
|
||||
return this.alternativa3d::system;
|
||||
}
|
||||
|
||||
protected function get cameraTransform() : Transform3D
|
||||
{
|
||||
return this.alternativa3d::system.alternativa3d::cameraToLocalTransform;
|
||||
}
|
||||
|
||||
protected function random() : Number
|
||||
{
|
||||
var res:Number = randomNumbers[this.name_hs];
|
||||
++this.name_hs;
|
||||
if(this.name_hs == randomNumbersCount)
|
||||
{
|
||||
this.name_hs = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected function addKey(time:Number, script:Function) : void
|
||||
{
|
||||
this.name_gV[this.name_kf] = time;
|
||||
this.name_lB[this.name_kf] = new Vector3D();
|
||||
this.name_ib[this.name_kf] = new Vector3D();
|
||||
this.name_Nz[this.name_kf] = script;
|
||||
++this.name_kf;
|
||||
}
|
||||
|
||||
protected function setLife(time:Number) : void
|
||||
{
|
||||
this.alternativa3d::lifeTime = time;
|
||||
}
|
||||
|
||||
alternativa3d function calculateAABB() : void
|
||||
{
|
||||
this.alternativa3d::aabb.minX = this.boundBox.minX * this.scale + this.name_G1.x;
|
||||
this.alternativa3d::aabb.minY = this.boundBox.minY * this.scale + this.name_G1.y;
|
||||
this.alternativa3d::aabb.minZ = this.boundBox.minZ * this.scale + this.name_G1.z;
|
||||
this.alternativa3d::aabb.maxX = this.boundBox.maxX * this.scale + this.name_G1.x;
|
||||
this.alternativa3d::aabb.maxY = this.boundBox.maxY * this.scale + this.name_G1.y;
|
||||
this.alternativa3d::aabb.maxZ = this.boundBox.maxZ * this.scale + this.name_G1.z;
|
||||
}
|
||||
|
||||
alternativa3d function setPositionKeys(time:Number) : void
|
||||
{
|
||||
var pos:Vector3D = null;
|
||||
for(var i:int = 0; i < this.name_kf; )
|
||||
{
|
||||
if(time <= this.name_gV[i])
|
||||
{
|
||||
pos = this.name_lB[i];
|
||||
pos.x = this.name_G1.x;
|
||||
pos.y = this.name_G1.y;
|
||||
pos.z = this.name_G1.z;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function setDirectionKeys(time:Number) : void
|
||||
{
|
||||
var dir:Vector3D = null;
|
||||
vector.x = this.name_Q2.x;
|
||||
vector.y = this.name_Q2.y;
|
||||
vector.z = this.name_Q2.z;
|
||||
vector.normalize();
|
||||
for(var i:int = 0; i < this.name_kf; )
|
||||
{
|
||||
if(time <= this.name_gV[i])
|
||||
{
|
||||
dir = this.name_ib[i];
|
||||
dir.x = vector.x;
|
||||
dir.y = vector.y;
|
||||
dir.z = vector.z;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
alternativa3d function calculate(time:Number) : Boolean
|
||||
{
|
||||
var keyTime:Number = NaN;
|
||||
var script:Function = null;
|
||||
this.name_hs = this.name_TK;
|
||||
for(var i:int = 0; i < this.name_kf; )
|
||||
{
|
||||
keyTime = this.name_gV[i];
|
||||
if(time < keyTime)
|
||||
{
|
||||
break;
|
||||
}
|
||||
this.name_M7 = this.name_lB[i];
|
||||
this.name_cF = this.name_ib[i];
|
||||
script = this.name_Nz[i];
|
||||
script.call(this,keyTime,time - keyTime);
|
||||
i++;
|
||||
}
|
||||
return i < this.name_kf || this.alternativa3d::particleList != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import flash.display3D.textures.TextureBase;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParticlePrototype
|
||||
{
|
||||
public var atlas:TextureAtlas;
|
||||
|
||||
private var blendSource:String;
|
||||
|
||||
private var blendDestination:String;
|
||||
|
||||
private var animated:Boolean;
|
||||
|
||||
private var width:Number;
|
||||
|
||||
private var height:Number;
|
||||
|
||||
private var name_gV:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_0r:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_4e:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_Oj:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_07:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_3l:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_7S:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_Ch:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
private var name_kf:int = 0;
|
||||
|
||||
public function ParticlePrototype(width:Number, height:Number, atlas:TextureAtlas, animated:Boolean = false, blendSource:String = "sourceAlpha", blendDestination:String = "oneMinusSourceAlpha")
|
||||
{
|
||||
super();
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.atlas = atlas;
|
||||
this.animated = animated;
|
||||
this.blendSource = blendSource;
|
||||
this.blendDestination = blendDestination;
|
||||
}
|
||||
|
||||
public function addKey(time:Number, rotation:Number = 0, scaleX:Number = 1, scaleY:Number = 1, red:Number = 1, green:Number = 1, blue:Number = 1, alpha:Number = 1) : void
|
||||
{
|
||||
var lastIndex:int = this.name_kf - 1;
|
||||
if(this.name_kf > 0 && time <= this.name_gV[lastIndex])
|
||||
{
|
||||
throw new Error("Keys must be successively.");
|
||||
}
|
||||
this.name_gV[this.name_kf] = time;
|
||||
this.name_0r[this.name_kf] = rotation;
|
||||
this.name_4e[this.name_kf] = scaleX;
|
||||
this.name_Oj[this.name_kf] = scaleY;
|
||||
this.name_07[this.name_kf] = red;
|
||||
this.name_3l[this.name_kf] = green;
|
||||
this.name_7S[this.name_kf] = blue;
|
||||
this.name_Ch[this.name_kf] = alpha;
|
||||
++this.name_kf;
|
||||
}
|
||||
|
||||
public function createParticle(effect:ParticleEffect, time:Number, position:Vector3D, rotation:Number = 0, scaleX:Number = 1, scaleY:Number = 1, alpha:Number = 1, firstFrame:int = 0) : void
|
||||
{
|
||||
var systemScale:Number = NaN;
|
||||
var effectScale:Number = NaN;
|
||||
var transform:Transform3D = null;
|
||||
var wind:Vector3D = null;
|
||||
var gravity:Vector3D = null;
|
||||
var a:int = 0;
|
||||
var t:Number = NaN;
|
||||
var pos:int = 0;
|
||||
var col:int = 0;
|
||||
var row:int = 0;
|
||||
var particle:Particle = null;
|
||||
var cx:Number = NaN;
|
||||
var cy:Number = NaN;
|
||||
var cz:Number = NaN;
|
||||
var rot:Number = NaN;
|
||||
var b:int = this.name_kf - 1;
|
||||
if(this.atlas.diffuse.alternativa3d::_texture != null && this.name_kf > 1 && time >= this.name_gV[0] && time < this.name_gV[b])
|
||||
{
|
||||
for(b = 1; b < this.name_kf; )
|
||||
{
|
||||
if(time < this.name_gV[b])
|
||||
{
|
||||
systemScale = Number(effect.alternativa3d::system.alternativa3d::scale);
|
||||
effectScale = effect.scale;
|
||||
transform = effect.alternativa3d::system.alternativa3d::localToCameraTransform;
|
||||
wind = effect.alternativa3d::system.wind;
|
||||
gravity = effect.alternativa3d::system.gravity;
|
||||
a = b - 1;
|
||||
t = (time - this.name_gV[a]) / (this.name_gV[b] - this.name_gV[a]);
|
||||
pos = firstFrame + (this.animated ? time * this.atlas.fps : 0);
|
||||
if(this.atlas.loop)
|
||||
{
|
||||
pos %= this.atlas.rangeLength;
|
||||
if(pos < 0)
|
||||
{
|
||||
pos += this.atlas.rangeLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pos < 0)
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
if(pos >= this.atlas.rangeLength)
|
||||
{
|
||||
pos = this.atlas.rangeLength - 1;
|
||||
}
|
||||
}
|
||||
pos += this.atlas.rangeBegin;
|
||||
col = pos % this.atlas.columnsCount;
|
||||
row = pos / this.atlas.columnsCount;
|
||||
particle = Particle.create();
|
||||
particle.diffuse = this.atlas.diffuse.alternativa3d::_texture;
|
||||
particle.opacity = this.atlas.opacity != null ? this.atlas.opacity.alternativa3d::_texture : null;
|
||||
particle.blendSource = this.blendSource;
|
||||
particle.blendDestination = this.blendDestination;
|
||||
cx = effect.name_M7.x + position.x * effectScale;
|
||||
cy = effect.name_M7.y + position.y * effectScale;
|
||||
cz = effect.name_M7.z + position.z * effectScale;
|
||||
particle.x = cx * transform.a + cy * transform.b + cz * transform.c + transform.d;
|
||||
particle.y = cx * transform.e + cy * transform.f + cz * transform.g + transform.h;
|
||||
particle.z = cx * transform.i + cy * transform.j + cz * transform.k + transform.l;
|
||||
rot = this.name_0r[a] + (this.name_0r[b] - this.name_0r[a]) * t;
|
||||
particle.rotation = scaleX * scaleY > 0 ? rotation + rot : rotation - rot;
|
||||
particle.width = systemScale * effectScale * scaleX * this.width * (this.name_4e[a] + (this.name_4e[b] - this.name_4e[a]) * t);
|
||||
particle.height = systemScale * effectScale * scaleY * this.height * (this.name_Oj[a] + (this.name_Oj[b] - this.name_Oj[a]) * t);
|
||||
particle.originX = this.atlas.originX;
|
||||
particle.originY = this.atlas.originY;
|
||||
particle.name_q = 1 / this.atlas.columnsCount;
|
||||
particle.name_Ts = 1 / this.atlas.rowsCount;
|
||||
particle.name_ej = col / this.atlas.columnsCount;
|
||||
particle.name_W5 = row / this.atlas.rowsCount;
|
||||
particle.red = this.name_07[a] + (this.name_07[b] - this.name_07[a]) * t;
|
||||
particle.green = this.name_3l[a] + (this.name_3l[b] - this.name_3l[a]) * t;
|
||||
particle.blue = this.name_7S[a] + (this.name_7S[b] - this.name_7S[a]) * t;
|
||||
particle.alpha = alpha * (this.name_Ch[a] + (this.name_Ch[b] - this.name_Ch[a]) * t);
|
||||
particle.next = effect.alternativa3d::particleList;
|
||||
effect.alternativa3d::particleList = particle;
|
||||
break;
|
||||
}
|
||||
b++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get lifeTime() : Number
|
||||
{
|
||||
var lastIndex:int = this.name_kf - 1;
|
||||
return this.name_gV[lastIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,464 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.Context3DTriangleFace;
|
||||
import flash.display3D.Context3DVertexBufferFormat;
|
||||
import flash.display3D.IndexBuffer3D;
|
||||
import flash.display3D.Program3D;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.display3D.textures.TextureBase;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.getTimer;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParticleSystem extends Object3D
|
||||
{
|
||||
private static var vertexBuffer:VertexBuffer3D;
|
||||
|
||||
private static var indexBuffer:IndexBuffer3D;
|
||||
|
||||
private static var diffuseProgram:Program3D;
|
||||
|
||||
private static var opacityProgram:Program3D;
|
||||
|
||||
private static var diffuseBlendProgram:Program3D;
|
||||
|
||||
private static var opacityBlendProgram:Program3D;
|
||||
|
||||
private static const limit:int = 31;
|
||||
|
||||
public var name_jW:Boolean = true;
|
||||
|
||||
public var gravity:Vector3D = new Vector3D(0,0,-1);
|
||||
|
||||
public var wind:Vector3D = new Vector3D();
|
||||
|
||||
public var name_IN:int = 0;
|
||||
|
||||
public var fogMaxDensity:Number = 0;
|
||||
|
||||
public var fogNear:Number = 0;
|
||||
|
||||
public var fogFar:Number = 0;
|
||||
|
||||
alternativa3d var scale:Number = 1;
|
||||
|
||||
alternativa3d var effectList:ParticleEffect;
|
||||
|
||||
private var drawUnit:DrawUnit = null;
|
||||
|
||||
private var diffuse:TextureBase = null;
|
||||
|
||||
private var opacity:TextureBase = null;
|
||||
|
||||
private var blendSource:String = null;
|
||||
|
||||
private var blendDestination:String = null;
|
||||
|
||||
private var counter:int;
|
||||
|
||||
private var name_La:Number;
|
||||
|
||||
private var name_p3:Number;
|
||||
|
||||
private var name_ZN:Vector.<Object3D> = new Vector.<Object3D>();
|
||||
|
||||
private var name_hr:int = 0;
|
||||
|
||||
private var pause:Boolean = false;
|
||||
|
||||
private var name_pK:Number;
|
||||
|
||||
private var name_L5:Number = 0;
|
||||
|
||||
public function ParticleSystem()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function stop() : void
|
||||
{
|
||||
if(!this.pause)
|
||||
{
|
||||
this.name_pK = getTimer() * 0.001;
|
||||
this.pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function play() : void
|
||||
{
|
||||
if(this.pause)
|
||||
{
|
||||
this.name_L5 += getTimer() * 0.001 - this.name_pK;
|
||||
this.pause = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function prevFrame() : void
|
||||
{
|
||||
this.name_pK -= 0.001;
|
||||
}
|
||||
|
||||
public function nextFrame() : void
|
||||
{
|
||||
this.name_pK += 0.001;
|
||||
}
|
||||
|
||||
public function each(effect:ParticleEffect) : ParticleEffect
|
||||
{
|
||||
if(effect.alternativa3d::system != null)
|
||||
{
|
||||
throw new Error("Cannot add the same effect twice.");
|
||||
}
|
||||
effect.alternativa3d::startTime = this.alternativa3d::getTime();
|
||||
effect.alternativa3d::system = this;
|
||||
effect.alternativa3d::setPositionKeys(0);
|
||||
effect.alternativa3d::setDirectionKeys(0);
|
||||
effect.name_implements = this.alternativa3d::effectList;
|
||||
this.alternativa3d::effectList = effect;
|
||||
return effect;
|
||||
}
|
||||
|
||||
public function getEffectByName(name:String) : ParticleEffect
|
||||
{
|
||||
for(var effect:ParticleEffect = this.alternativa3d::effectList; effect != null; )
|
||||
{
|
||||
if(effect.name == name)
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
effect = effect.name_implements;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
alternativa3d function getTime() : Number
|
||||
{
|
||||
return this.pause ? this.name_pK - this.name_L5 : getTimer() * 0.001 - this.name_L5;
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var visibleEffectList:ParticleEffect = null;
|
||||
var effectTime:Number = NaN;
|
||||
var culling:int = 0;
|
||||
var debug:int = 0;
|
||||
if(vertexBuffer == null)
|
||||
{
|
||||
this.createAndUpload(camera.alternativa3d::context3D);
|
||||
}
|
||||
this.alternativa3d::scale = Math.sqrt(alternativa3d::localToCameraTransform.a * alternativa3d::localToCameraTransform.a + alternativa3d::localToCameraTransform.e * alternativa3d::localToCameraTransform.e + alternativa3d::localToCameraTransform.i * alternativa3d::localToCameraTransform.i);
|
||||
this.alternativa3d::scale += Math.sqrt(alternativa3d::localToCameraTransform.b * alternativa3d::localToCameraTransform.b + alternativa3d::localToCameraTransform.f * alternativa3d::localToCameraTransform.f + alternativa3d::localToCameraTransform.j * alternativa3d::localToCameraTransform.j);
|
||||
this.alternativa3d::scale += Math.sqrt(alternativa3d::localToCameraTransform.c * alternativa3d::localToCameraTransform.c + alternativa3d::localToCameraTransform.g * alternativa3d::localToCameraTransform.g + alternativa3d::localToCameraTransform.k * alternativa3d::localToCameraTransform.k);
|
||||
this.alternativa3d::scale /= 3;
|
||||
camera.alternativa3d::calculateFrustum(alternativa3d::cameraToLocalTransform);
|
||||
var conflictAnyway:Boolean = false;
|
||||
var time:Number = this.alternativa3d::getTime();
|
||||
for(var effect:ParticleEffect = this.alternativa3d::effectList, prev:ParticleEffect = null; effect != null; )
|
||||
{
|
||||
effectTime = time - effect.alternativa3d::startTime;
|
||||
if(effectTime <= effect.alternativa3d::lifeTime)
|
||||
{
|
||||
culling = 63;
|
||||
if(effect.boundBox != null)
|
||||
{
|
||||
effect.alternativa3d::calculateAABB();
|
||||
culling = int(effect.alternativa3d::aabb.alternativa3d::checkFrustumCulling(camera.alternativa3d::frustum,63));
|
||||
}
|
||||
if(culling >= 0)
|
||||
{
|
||||
if(effect.alternativa3d::calculate(effectTime))
|
||||
{
|
||||
if(effect.alternativa3d::particleList != null)
|
||||
{
|
||||
effect.alternativa3d::next = visibleEffectList;
|
||||
visibleEffectList = effect;
|
||||
conflictAnyway ||= effect.boundBox == null;
|
||||
}
|
||||
prev = effect;
|
||||
effect = effect.name_implements;
|
||||
}
|
||||
else if(prev != null)
|
||||
{
|
||||
prev.name_implements = effect.name_implements;
|
||||
effect = prev.name_implements;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::effectList = effect.name_implements;
|
||||
effect = this.alternativa3d::effectList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = effect;
|
||||
effect = effect.name_implements;
|
||||
}
|
||||
}
|
||||
else if(prev != null)
|
||||
{
|
||||
prev.name_implements = effect.name_implements;
|
||||
effect = prev.name_implements;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alternativa3d::effectList = effect.name_implements;
|
||||
effect = this.alternativa3d::effectList;
|
||||
}
|
||||
}
|
||||
if(visibleEffectList != null)
|
||||
{
|
||||
if(visibleEffectList.alternativa3d::next != null)
|
||||
{
|
||||
this.drawConflictEffects(camera,visibleEffectList);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.drawParticleList(camera,visibleEffectList.alternativa3d::particleList);
|
||||
visibleEffectList.alternativa3d::particleList = null;
|
||||
if(camera.debug && visibleEffectList.boundBox != null && Boolean(camera.alternativa3d::checkInDebug(this) & Debug.BOUNDS))
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,visibleEffectList.alternativa3d::aabb,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
this.flush(camera);
|
||||
this.drawUnit = null;
|
||||
this.diffuse = null;
|
||||
this.opacity = null;
|
||||
this.blendSource = null;
|
||||
this.blendDestination = null;
|
||||
this.name_hr = 0;
|
||||
}
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createAndUpload(context:Context3D) : void
|
||||
{
|
||||
var vertices:Vector.<Number> = new Vector.<Number>();
|
||||
var indices:Vector.<uint> = new Vector.<uint>();
|
||||
for(var i:int = 0; i < limit; i++)
|
||||
{
|
||||
vertices.push(0,0,0,0,0,i * 4,0,1,0,0,1,i * 4,1,1,0,1,1,i * 4,1,0,0,1,0,i * 4);
|
||||
indices.push(i * 4,i * 4 + 1,i * 4 + 3,i * 4 + 2,i * 4 + 3,i * 4 + 1);
|
||||
}
|
||||
vertexBuffer = context.createVertexBuffer(limit * 4,6);
|
||||
vertexBuffer.uploadFromVector(vertices,0,limit * 4);
|
||||
indexBuffer = context.createIndexBuffer(limit * 6);
|
||||
indexBuffer.uploadFromVector(indices,0,limit * 6);
|
||||
var vertexProgram:Array = ["mov vt2, vc[va1.z]","sub vt0.z, va0.x, vt2.x","sub vt0.w, va0.y, vt2.y","mul vt0.z, vt0.z, vt2.z","mul vt0.w, vt0.w, vt2.w","mov vt2, vc[va1.z+1]","mov vt1.z, vt2.w","sin vt1.x, vt1.z","cos vt1.y, vt1.z","mul vt1.z, vt0.z, vt1.y","mul vt1.w, vt0.w, vt1.x","sub vt0.x, vt1.z, vt1.w","mul vt1.z, vt0.z, vt1.x","mul vt1.w, vt0.w, vt1.y","add vt0.y, vt1.z, vt1.w","add vt0.x, vt0.x, vt2.x","add vt0.y, vt0.y, vt2.y","add vt0.z, va0.z, vt2.z","mov vt0.w, va0.w","dp4 op.x, vt0, vc124","dp4 op.y, vt0, vc125","dp4 op.z, vt0, vc126","dp4 op.w, vt0, vc127","mov vt2, vc[va1.z+2]","mul vt1.x, va1.x, vt2.x","mul vt1.y, va1.y, vt2.y","add vt1.x, vt1.x, vt2.z","add vt1.y, vt1.y, vt2.w","mov v0, vt1","mov v1, vc[va1.z+3]","mov v2, vt0"];
|
||||
var fragmentDiffuseProgram:Array = ["tex ft0, v0, fs0 <2d,clamp,linear,miplinear>","mul ft0, ft0, v1","sub ft1.w, v2.z, fc1.x","div ft1.w, ft1.w, fc1.y","max ft1.w, ft1.w, fc1.z","min ft1.w, ft1.w, fc0.w","sub ft1.xyz, fc0.xyz, ft0.xyz","mul ft1.xyz, ft1.xyz, ft1.w","add ft0.xyz, ft0.xyz, ft1.xyz","mov oc, ft0"];
|
||||
var fragmentOpacityProgram:Array = ["tex ft0, v0, fs0 <2d,clamp,linear,miplinear>","tex ft1, v0, fs1 <2d,clamp,linear,miplinear>","mov ft0.w, ft1.x","mul ft0, ft0, v1","sub ft1.w, v2.z, fc1.x","div ft1.w, ft1.w, fc1.y","max ft1.w, ft1.w, fc1.z","min ft1.w, ft1.w, fc0.w","sub ft1.xyz, fc0.xyz, ft0.xyz","mul ft1.xyz, ft1.xyz, ft1.w","add ft0.xyz, ft0.xyz, ft1.xyz","mov oc, ft0"];
|
||||
var fragmentDiffuseBlendProgram:Array = ["tex ft0, v0, fs0 <2d,clamp,linear,miplinear>","mul ft0, ft0, v1","sub ft1.w, v2.z, fc1.x","div ft1.w, ft1.w, fc1.y","max ft1.w, ft1.w, fc1.z","min ft1.w, ft1.w, fc0.w","sub ft1.w, fc1.w, ft1.w","mul ft0.w, ft0.w, ft1.w","mov oc, ft0"];
|
||||
var fragmentOpacityBlendProgram:Array = ["tex ft0, v0, fs0 <2d,clamp,linear,miplinear>","tex ft1, v0, fs1 <2d,clamp,linear,miplinear>","mov ft0.w, ft1.x","mul ft0, ft0, v1","sub ft1.w, v2.z, fc1.x","div ft1.w, ft1.w, fc1.y","max ft1.w, ft1.w, fc1.z","min ft1.w, ft1.w, fc0.w","sub ft1.w, fc1.w, ft1.w","mul ft0.w, ft0.w, ft1.w","mov oc, ft0"];
|
||||
diffuseProgram = context.createProgram();
|
||||
opacityProgram = context.createProgram();
|
||||
diffuseBlendProgram = context.createProgram();
|
||||
opacityBlendProgram = context.createProgram();
|
||||
var compiledVertexProgram:ByteArray = this.compileProgram(Context3DProgramType.VERTEX,vertexProgram);
|
||||
diffuseProgram.upload(compiledVertexProgram,this.compileProgram(Context3DProgramType.FRAGMENT,fragmentDiffuseProgram));
|
||||
opacityProgram.upload(compiledVertexProgram,this.compileProgram(Context3DProgramType.FRAGMENT,fragmentOpacityProgram));
|
||||
diffuseBlendProgram.upload(compiledVertexProgram,this.compileProgram(Context3DProgramType.FRAGMENT,fragmentDiffuseBlendProgram));
|
||||
opacityBlendProgram.upload(compiledVertexProgram,this.compileProgram(Context3DProgramType.FRAGMENT,fragmentOpacityBlendProgram));
|
||||
}
|
||||
|
||||
private function compileProgram(mode:String, program:Array) : ByteArray
|
||||
{
|
||||
var line:String = null;
|
||||
var string:String = "";
|
||||
var length:int = int(program.length);
|
||||
for(var i:int = 0; i < length; i++)
|
||||
{
|
||||
line = program[i];
|
||||
string += line + (i < length - 1 ? " \n" : "");
|
||||
}
|
||||
return new AGALMiniAssembler().assemble(mode,string,false);
|
||||
}
|
||||
|
||||
private function flush(camera:Camera3D) : void
|
||||
{
|
||||
if(this.name_hr == this.name_ZN.length)
|
||||
{
|
||||
this.name_ZN[this.name_hr] = new Object3D();
|
||||
}
|
||||
var object:Object3D = this.name_ZN[this.name_hr];
|
||||
++this.name_hr;
|
||||
object.alternativa3d::localToCameraTransform.l = (this.name_La + this.name_p3) / 2;
|
||||
this.drawUnit.alternativa3d::object = object;
|
||||
this.drawUnit.alternativa3d::numTriangles = this.counter << 1;
|
||||
if(this.blendDestination == Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA)
|
||||
{
|
||||
this.drawUnit.alternativa3d::program = this.opacity != null ? opacityProgram : diffuseProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.drawUnit.alternativa3d::program = this.opacity != null ? opacityBlendProgram : diffuseBlendProgram;
|
||||
}
|
||||
this.drawUnit.alternativa3d::setVertexBufferAt(0,vertexBuffer,0,Context3DVertexBufferFormat.FLOAT_3);
|
||||
this.drawUnit.alternativa3d::setVertexBufferAt(1,vertexBuffer,3,Context3DVertexBufferFormat.FLOAT_3);
|
||||
this.drawUnit.alternativa3d::setProjectionConstants(camera,124);
|
||||
this.drawUnit.alternativa3d::setFragmentConstantsFromNumbers(0,(this.name_IN >> 16 & 0xFF) / 255,(this.name_IN >> 8 & 0xFF) / 255,(this.name_IN & 0xFF) / 255,this.fogMaxDensity);
|
||||
this.drawUnit.alternativa3d::setFragmentConstantsFromNumbers(1,this.fogNear,this.fogFar - this.fogNear,0,1);
|
||||
this.drawUnit.alternativa3d::setTextureAt(0,this.diffuse);
|
||||
if(this.opacity != null)
|
||||
{
|
||||
this.drawUnit.alternativa3d::setTextureAt(1,this.opacity);
|
||||
}
|
||||
this.drawUnit.alternativa3d::blendSource = this.blendSource;
|
||||
this.drawUnit.alternativa3d::blendDestination = this.blendDestination;
|
||||
this.drawUnit.alternativa3d::culling = Context3DTriangleFace.NONE;
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(this.drawUnit,RenderPriority.TRANSPARENT_SORT);
|
||||
}
|
||||
|
||||
private function drawParticleList(camera:Camera3D, list:Particle) : void
|
||||
{
|
||||
var last:Particle = null;
|
||||
var offset:int = 0;
|
||||
if(list.next != null)
|
||||
{
|
||||
list = this.sortParticleList(list);
|
||||
}
|
||||
for(var particle:Particle = list; particle != null; )
|
||||
{
|
||||
if(this.counter >= limit || particle.diffuse != this.diffuse || particle.opacity != this.opacity || particle.blendSource != this.blendSource || particle.blendDestination != this.blendDestination)
|
||||
{
|
||||
if(this.drawUnit != null)
|
||||
{
|
||||
this.flush(camera);
|
||||
}
|
||||
this.drawUnit = camera.alternativa3d::renderer.alternativa3d::createDrawUnit(null,null,indexBuffer,0,0);
|
||||
this.diffuse = particle.diffuse;
|
||||
this.opacity = particle.opacity;
|
||||
this.blendSource = particle.blendSource;
|
||||
this.blendDestination = particle.blendDestination;
|
||||
this.counter = 0;
|
||||
this.name_La = particle.z;
|
||||
}
|
||||
offset = this.counter << 2;
|
||||
this.drawUnit.alternativa3d::setVertexConstantsFromNumbers(offset++,particle.originX,particle.originY,particle.width,particle.height);
|
||||
this.drawUnit.alternativa3d::setVertexConstantsFromNumbers(offset++,particle.x,particle.y,particle.z,particle.rotation);
|
||||
this.drawUnit.alternativa3d::setVertexConstantsFromNumbers(offset++,particle.name_q,particle.name_Ts,particle.name_ej,particle.name_W5);
|
||||
this.drawUnit.alternativa3d::setVertexConstantsFromNumbers(offset++,particle.red,particle.green,particle.blue,particle.alpha);
|
||||
++this.counter;
|
||||
this.name_p3 = particle.z;
|
||||
last = particle;
|
||||
particle = particle.next;
|
||||
}
|
||||
last.next = Particle.collector;
|
||||
Particle.collector = list;
|
||||
}
|
||||
|
||||
private function sortParticleList(list:Particle) : Particle
|
||||
{
|
||||
var left:Particle = list;
|
||||
var right:Particle = list.next;
|
||||
while(right != null && right.next != null)
|
||||
{
|
||||
list = list.next;
|
||||
right = right.next.next;
|
||||
}
|
||||
right = list.next;
|
||||
list.next = null;
|
||||
if(left.next != null)
|
||||
{
|
||||
left = this.sortParticleList(left);
|
||||
}
|
||||
if(right.next != null)
|
||||
{
|
||||
right = this.sortParticleList(right);
|
||||
}
|
||||
var flag:Boolean = left.z > right.z;
|
||||
if(flag)
|
||||
{
|
||||
list = left;
|
||||
left = left.next;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = right;
|
||||
right = right.next;
|
||||
}
|
||||
var last:Particle = list;
|
||||
while(left != null)
|
||||
{
|
||||
if(right == null)
|
||||
{
|
||||
last.next = left;
|
||||
return list;
|
||||
}
|
||||
if(flag)
|
||||
{
|
||||
if(left.z > right.z)
|
||||
{
|
||||
last = left;
|
||||
left = left.next;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.next = right;
|
||||
last = right;
|
||||
right = right.next;
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
else if(right.z > left.z)
|
||||
{
|
||||
last = right;
|
||||
right = right.next;
|
||||
}
|
||||
else
|
||||
{
|
||||
last.next = left;
|
||||
last = left;
|
||||
left = left.next;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
last.next = right;
|
||||
return list;
|
||||
}
|
||||
|
||||
private function drawConflictEffects(camera:Camera3D, effectList:ParticleEffect) : void
|
||||
{
|
||||
var particleList:Particle = null;
|
||||
var next:ParticleEffect = null;
|
||||
var last:Particle = null;
|
||||
for(var effect:ParticleEffect = effectList; effect != null; )
|
||||
{
|
||||
next = effect.alternativa3d::next;
|
||||
effect.alternativa3d::next = null;
|
||||
for(last = effect.alternativa3d::particleList; last.next != null; )
|
||||
{
|
||||
last = last.next;
|
||||
}
|
||||
last.next = particleList;
|
||||
particleList = effect.alternativa3d::particleList;
|
||||
effect.alternativa3d::particleList = null;
|
||||
if(camera.debug && effect.boundBox != null && Boolean(camera.alternativa3d::checkInDebug(this) & Debug.BOUNDS))
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,effect.alternativa3d::aabb,alternativa3d::localToCameraTransform,16711680);
|
||||
}
|
||||
effect = next;
|
||||
}
|
||||
this.drawParticleList(camera,particleList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package alternativa.engine3d.effects
|
||||
{
|
||||
import alternativa.engine3d.resources.TextureResource;
|
||||
|
||||
public class TextureAtlas
|
||||
{
|
||||
public var diffuse:TextureResource;
|
||||
|
||||
public var opacity:TextureResource;
|
||||
|
||||
public var columnsCount:int;
|
||||
|
||||
public var rowsCount:int;
|
||||
|
||||
public var rangeBegin:int;
|
||||
|
||||
public var rangeLength:int;
|
||||
|
||||
public var fps:int;
|
||||
|
||||
public var loop:Boolean;
|
||||
|
||||
public var originX:Number;
|
||||
|
||||
public var originY:Number;
|
||||
|
||||
public function TextureAtlas(diffuse:TextureResource, opacity:TextureResource = null, columnsCount:int = 1, rowsCount:int = 1, rangeBegin:int = 0, rangeLength:int = 1, fps:int = 30, loop:Boolean = false, originX:Number = 0.5, originY:Number = 0.5)
|
||||
{
|
||||
super();
|
||||
this.diffuse = diffuse;
|
||||
this.opacity = opacity;
|
||||
this.columnsCount = columnsCount;
|
||||
this.rowsCount = rowsCount;
|
||||
this.rangeBegin = rangeBegin;
|
||||
this.rangeLength = rangeLength;
|
||||
this.fps = fps;
|
||||
this.loop = loop;
|
||||
this.originX = originX;
|
||||
this.originY = originY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package alternativa.engine3d.lights
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class AmbientLight extends Light3D
|
||||
{
|
||||
public function AmbientLight(color:uint)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
override alternativa3d function calculateVisibility(camera:Camera3D) : void
|
||||
{
|
||||
camera.alternativa3d::ambient[0] += (color >> 16 & 0xFF) * intensity / 255;
|
||||
camera.alternativa3d::ambient[1] += (color >> 8 & 0xFF) * intensity / 255;
|
||||
camera.alternativa3d::ambient[2] += (color & 0xFF) * intensity / 255;
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var debug:int = 0;
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:AmbientLight = new AmbientLight(color);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package alternativa.engine3d.lights
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.shadows.ShadowRenderer;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DirectionalLight extends Light3D
|
||||
{
|
||||
public var shadow:ShadowRenderer;
|
||||
|
||||
public function DirectionalLight(color:uint)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public function lookAt(x:Number, y:Number, z:Number) : void
|
||||
{
|
||||
var dx:Number = x - this.x;
|
||||
var dy:Number = y - this.y;
|
||||
var dz:Number = z - this.z;
|
||||
rotationX = Math.atan2(dz,Math.sqrt(dx * dx + dy * dy)) - Math.PI / 2;
|
||||
rotationY = 0;
|
||||
rotationZ = -Math.atan2(dx,dy);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var debug:int = 0;
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:DirectionalLight = new DirectionalLight(color);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
package alternativa.engine3d.lights
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class OmniLight extends Light3D
|
||||
{
|
||||
public var attenuationBegin:Number;
|
||||
|
||||
public var attenuationEnd:Number;
|
||||
|
||||
public function OmniLight(color:uint, attenuationBegin:Number, attenuationEnd:Number)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
this.attenuationBegin = attenuationBegin;
|
||||
this.attenuationEnd = attenuationEnd;
|
||||
calculateBoundBox();
|
||||
}
|
||||
|
||||
override alternativa3d function updateBoundBox(boundBox:BoundBox, hierarchy:Boolean, transform:Transform3D = null) : void
|
||||
{
|
||||
super.alternativa3d::updateBoundBox(boundBox,hierarchy,transform);
|
||||
if(transform == null)
|
||||
{
|
||||
if(-this.attenuationEnd < boundBox.minX)
|
||||
{
|
||||
boundBox.minX = -this.attenuationEnd;
|
||||
}
|
||||
if(this.attenuationEnd > boundBox.maxX)
|
||||
{
|
||||
boundBox.maxX = this.attenuationEnd;
|
||||
}
|
||||
if(-this.attenuationEnd < boundBox.minY)
|
||||
{
|
||||
boundBox.minY = -this.attenuationEnd;
|
||||
}
|
||||
if(this.attenuationEnd > boundBox.maxY)
|
||||
{
|
||||
boundBox.maxY = this.attenuationEnd;
|
||||
}
|
||||
if(-this.attenuationEnd < boundBox.minZ)
|
||||
{
|
||||
boundBox.minZ = -this.attenuationEnd;
|
||||
}
|
||||
if(this.attenuationEnd > boundBox.maxZ)
|
||||
{
|
||||
boundBox.maxZ = this.attenuationEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var debug:int = 0;
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function checkBound(targetObject:Object3D) : Boolean
|
||||
{
|
||||
var rScale:Number = Number(Math.sqrt(name_cl.a * name_cl.a + name_cl.e * name_cl.e + name_cl.i * name_cl.i));
|
||||
rScale += Math.sqrt(name_cl.b * name_cl.b + name_cl.f * name_cl.f + name_cl.j * name_cl.j);
|
||||
rScale += Math.sqrt(name_cl.c * name_cl.c + name_cl.g * name_cl.g + name_cl.k * name_cl.k);
|
||||
rScale /= 3;
|
||||
rScale *= this.attenuationEnd;
|
||||
rScale *= rScale;
|
||||
var len:Number = 0;
|
||||
var bb:BoundBox = targetObject.boundBox;
|
||||
var minX:Number = bb.minX;
|
||||
var minY:Number = bb.minY;
|
||||
var minZ:Number = bb.minZ;
|
||||
var maxX:Number = bb.maxX;
|
||||
var px:Number = Number(name_cl.d);
|
||||
var py:Number = Number(name_cl.h);
|
||||
var pz:Number = Number(name_cl.l);
|
||||
var maxY:Number = bb.maxY;
|
||||
var maxZ:Number = bb.maxZ;
|
||||
if(px < minX)
|
||||
{
|
||||
if(py < minY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (minY - py) * (minY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (minY - py) * (minY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (minY - py) * (minY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py < maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py > maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (maxY - py) * (maxY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (maxY - py) * (maxY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (minX - px) * (minX - px) + (maxY - py) * (maxY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(px < maxX)
|
||||
{
|
||||
if(py < minY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (minY - py) * (minY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (minY - py) * (minY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (minY - py) * (minY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py < maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py > maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (maxY - py) * (maxY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (maxY - py) * (maxY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (maxY - py) * (maxY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(px > maxX)
|
||||
{
|
||||
if(py < minY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (minY - py) * (minY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (minY - py) * (minY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (minY - py) * (minY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py < maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
else if(py > maxY)
|
||||
{
|
||||
if(pz < minZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (maxY - py) * (maxY - py) + (minZ - pz) * (minZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz < maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (maxY - py) * (maxY - py);
|
||||
return len < rScale;
|
||||
}
|
||||
if(pz > maxZ)
|
||||
{
|
||||
len = (maxX - px) * (maxX - px) + (maxY - py) * (maxY - py) + (maxZ - pz) * (maxZ - pz);
|
||||
return len < rScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:OmniLight = new OmniLight(color,this.attenuationBegin,this.attenuationEnd);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
package alternativa.engine3d.lights
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class SpotLight extends Light3D
|
||||
{
|
||||
public var attenuationBegin:Number;
|
||||
|
||||
public var attenuationEnd:Number;
|
||||
|
||||
public var hotspot:Number;
|
||||
|
||||
public var falloff:Number;
|
||||
|
||||
public function SpotLight(color:uint, attenuationBegin:Number, attenuationEnd:Number, hotspot:Number, falloff:Number)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
this.attenuationBegin = attenuationBegin;
|
||||
this.attenuationEnd = attenuationEnd;
|
||||
this.hotspot = hotspot;
|
||||
this.falloff = falloff;
|
||||
calculateBoundBox();
|
||||
}
|
||||
|
||||
override alternativa3d function updateBoundBox(boundBox:BoundBox, hierarchy:Boolean, transform:Transform3D = null) : void
|
||||
{
|
||||
var bottom:Number = NaN;
|
||||
var r:Number = this.falloff < Math.PI ? Math.sin(this.falloff * 0.5) * this.attenuationEnd : this.attenuationEnd;
|
||||
bottom = this.falloff < Math.PI ? 0 : Math.cos(this.falloff * 0.5) * this.attenuationEnd;
|
||||
boundBox.minX = -r;
|
||||
boundBox.minY = -r;
|
||||
boundBox.minZ = bottom;
|
||||
boundBox.maxX = r;
|
||||
boundBox.maxY = r;
|
||||
boundBox.maxZ = this.attenuationEnd;
|
||||
}
|
||||
|
||||
public function lookAt(x:Number, y:Number, z:Number) : void
|
||||
{
|
||||
var dx:Number = x - this.x;
|
||||
var dy:Number = y - this.y;
|
||||
var dz:Number = z - this.z;
|
||||
rotationX = Math.atan2(dz,Math.sqrt(dx * dx + dy * dy)) - Math.PI / 2;
|
||||
rotationY = 0;
|
||||
rotationZ = -Math.atan2(dx,dy);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var debug:int = 0;
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function checkBound(targetObject:Object3D) : Boolean
|
||||
{
|
||||
var sum:Number = NaN;
|
||||
var pro:Number = NaN;
|
||||
var minX:Number = boundBox.minX;
|
||||
var minY:Number = boundBox.minY;
|
||||
var minZ:Number = boundBox.minZ;
|
||||
var maxX:Number = boundBox.maxX;
|
||||
var maxY:Number = boundBox.maxY;
|
||||
var maxZ:Number = boundBox.maxZ;
|
||||
var w:Number = (maxX - minX) * 0.5;
|
||||
var l:Number = (maxY - minY) * 0.5;
|
||||
var h:Number = (maxZ - minZ) * 0.5;
|
||||
var ax:Number = name_cl.a * w;
|
||||
var ay:Number = name_cl.e * w;
|
||||
var az:Number = name_cl.i * w;
|
||||
var bx:Number = name_cl.b * l;
|
||||
var by:Number = name_cl.f * l;
|
||||
var bz:Number = name_cl.j * l;
|
||||
var cx:Number = name_cl.c * h;
|
||||
var cy:Number = name_cl.g * h;
|
||||
var cz:Number = name_cl.k * h;
|
||||
var objectBB:BoundBox = targetObject.boundBox;
|
||||
var hw:Number = (objectBB.maxX - objectBB.minX) * 0.5;
|
||||
var hl:Number = (objectBB.maxY - objectBB.minY) * 0.5;
|
||||
var hh:Number = (objectBB.maxZ - objectBB.minZ) * 0.5;
|
||||
var dx:Number = name_cl.a * (minX + w) + name_cl.b * (minY + l) + name_cl.c * (minZ + h) + name_cl.d - objectBB.minX - hw;
|
||||
var dy:Number = name_cl.e * (minX + w) + name_cl.f * (minY + l) + name_cl.g * (minZ + h) + name_cl.h - objectBB.minY - hl;
|
||||
var dz:Number = name_cl.i * (minX + w) + name_cl.j * (minY + l) + name_cl.k * (minZ + h) + name_cl.l - objectBB.minZ - hh;
|
||||
sum = 0;
|
||||
if(ax >= 0)
|
||||
{
|
||||
sum += ax;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= ax;
|
||||
}
|
||||
if(bx >= 0)
|
||||
{
|
||||
sum += bx;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= bx;
|
||||
}
|
||||
if(cx >= 0)
|
||||
{
|
||||
sum += cx;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= cx;
|
||||
}
|
||||
sum += hw;
|
||||
if(dx >= 0)
|
||||
{
|
||||
sum -= dx;
|
||||
}
|
||||
sum += dx;
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sum = 0;
|
||||
if(ay >= 0)
|
||||
{
|
||||
sum += ay;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= ay;
|
||||
}
|
||||
if(by >= 0)
|
||||
{
|
||||
sum += by;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= by;
|
||||
}
|
||||
if(cy >= 0)
|
||||
{
|
||||
sum += cy;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= cy;
|
||||
}
|
||||
sum += hl;
|
||||
if(dy >= 0)
|
||||
{
|
||||
sum -= dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += dy;
|
||||
}
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sum = 0;
|
||||
if(az >= 0)
|
||||
{
|
||||
sum += az;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= az;
|
||||
}
|
||||
if(bz >= 0)
|
||||
{
|
||||
sum += bz;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= bz;
|
||||
}
|
||||
if(cz >= 0)
|
||||
{
|
||||
sum += cz;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= cz;
|
||||
}
|
||||
sum += hl;
|
||||
if(dz >= 0)
|
||||
{
|
||||
sum -= dz;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += dz;
|
||||
}
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sum = 0;
|
||||
pro = name_cl.a * ax + name_cl.e * ay + name_cl.i * az;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.a * bx + name_cl.e * by + name_cl.i * bz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.a * cx + name_cl.e * cy + name_cl.i * cz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
if(name_cl.a >= 0)
|
||||
{
|
||||
sum += name_cl.a * hw;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.a * hw;
|
||||
}
|
||||
if(name_cl.e >= 0)
|
||||
{
|
||||
sum += name_cl.e * hl;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.e * hl;
|
||||
}
|
||||
if(name_cl.i >= 0)
|
||||
{
|
||||
sum += name_cl.i * hh;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.i * hh;
|
||||
}
|
||||
pro = name_cl.a * dx + name_cl.e * dy + name_cl.i * dz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sum = 0;
|
||||
pro = name_cl.b * ax + name_cl.f * ay + name_cl.j * az;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.b * bx + name_cl.f * by + name_cl.j * bz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.b * cx + name_cl.f * cy + name_cl.j * cz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
if(name_cl.b >= 0)
|
||||
{
|
||||
sum += name_cl.b * hw;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.b * hw;
|
||||
}
|
||||
if(name_cl.f >= 0)
|
||||
{
|
||||
sum += name_cl.f * hl;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.f * hl;
|
||||
}
|
||||
if(name_cl.j >= 0)
|
||||
{
|
||||
sum += name_cl.j * hh;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.j * hh;
|
||||
}
|
||||
pro = name_cl.b * dx + name_cl.f * dy + name_cl.j * dz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
sum += pro;
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sum = 0;
|
||||
pro = name_cl.c * ax + name_cl.g * ay + name_cl.k * az;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.c * bx + name_cl.g * by + name_cl.k * bz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
pro = name_cl.c * cx + name_cl.g * cy + name_cl.k * cz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
if(name_cl.c >= 0)
|
||||
{
|
||||
sum += name_cl.c * hw;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.c * hw;
|
||||
}
|
||||
if(name_cl.g >= 0)
|
||||
{
|
||||
sum += name_cl.g * hl;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.g * hl;
|
||||
}
|
||||
if(name_cl.k >= 0)
|
||||
{
|
||||
sum += name_cl.k * hh;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum -= name_cl.k * hh;
|
||||
}
|
||||
pro = name_cl.c * dx + name_cl.g * dy + name_cl.k * dz;
|
||||
if(pro >= 0)
|
||||
{
|
||||
sum -= pro;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += pro;
|
||||
}
|
||||
if(sum <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:SpotLight = new SpotLight(color,this.attenuationBegin,this.attenuationEnd,this.hotspot,this.falloff);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,883 +0,0 @@
|
||||
package alternativa.engine3d.loaders
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.core.VertexStream;
|
||||
import alternativa.engine3d.lights.AmbientLight;
|
||||
import alternativa.engine3d.lights.DirectionalLight;
|
||||
import alternativa.engine3d.lights.OmniLight;
|
||||
import alternativa.engine3d.lights.SpotLight;
|
||||
import alternativa.engine3d.materials.A3DUtils;
|
||||
import alternativa.engine3d.objects.Joint;
|
||||
import alternativa.engine3d.objects.Mesh;
|
||||
import alternativa.engine3d.objects.Skin;
|
||||
import alternativa.engine3d.resources.ExternalTextureResource;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.osgi.OSGi;
|
||||
import alternativa.osgi.service.clientlog.IClientLog;
|
||||
import alternativa.protocol.ICodec;
|
||||
import alternativa.protocol.IProtocol;
|
||||
import alternativa.protocol.OptionalMap;
|
||||
import alternativa.protocol.ProtocolBuffer;
|
||||
import alternativa.protocol.impl.OptionalMapCodecHelper;
|
||||
import alternativa.protocol.impl.PacketHelper;
|
||||
import alternativa.protocol.impl.Protocol;
|
||||
import alternativa.protocol.info.TypeCodecInfo;
|
||||
import alternativa.protocol.osgi.ProtocolActivator;
|
||||
import alternativa.types.Long;
|
||||
import commons.A3DMatrix;
|
||||
import commons.Id;
|
||||
import flash.geom.Matrix3D;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Endian;
|
||||
import platform.client.formats.a3d.osgi.Activator;
|
||||
import platform.clients.fp10.libraries.alternativaprotocol.Activator;
|
||||
import versions.version1.a3d.A3D;
|
||||
import versions.version1.a3d.geometry.A3DGeometry;
|
||||
import versions.version1.a3d.geometry.A3DIndexBuffer;
|
||||
import versions.version1.a3d.geometry.A3DVertexBuffer;
|
||||
import versions.version1.a3d.id.ParentId;
|
||||
import versions.version1.a3d.materials.A3DImage;
|
||||
import versions.version1.a3d.materials.A3DMap;
|
||||
import versions.version1.a3d.materials.A3DMaterial;
|
||||
import versions.version1.a3d.objects.A3DBox;
|
||||
import versions.version1.a3d.objects.A3DObject;
|
||||
import versions.version1.a3d.objects.A3DSurface;
|
||||
import versions.version2.a3d.A3D2;
|
||||
import versions.version2.a3d.geometry.A3D2IndexBuffer;
|
||||
import versions.version2.a3d.geometry.A3D2VertexAttributes;
|
||||
import versions.version2.a3d.geometry.A3D2VertexBuffer;
|
||||
import versions.version2.a3d.materials.A3D2Image;
|
||||
import versions.version2.a3d.materials.A3D2Map;
|
||||
import versions.version2.a3d.materials.A3D2Material;
|
||||
import versions.version2.a3d.objects.A3D2AmbientLight;
|
||||
import versions.version2.a3d.objects.A3D2Box;
|
||||
import versions.version2.a3d.objects.A3D2DirectionalLight;
|
||||
import versions.version2.a3d.objects.A3D2Joint;
|
||||
import versions.version2.a3d.objects.A3D2Mesh;
|
||||
import versions.version2.a3d.objects.A3D2Object;
|
||||
import versions.version2.a3d.objects.A3D2OmniLight;
|
||||
import versions.version2.a3d.objects.A3D2Skin;
|
||||
import versions.version2.a3d.objects.A3D2SpotLight;
|
||||
import versions.version2.a3d.objects.A3D2Surface;
|
||||
import versions.version2.a3d.objects.A3D2Transform;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParserA3D
|
||||
{
|
||||
public var hierarchy:Vector.<Object3D>;
|
||||
|
||||
public var objects:Vector.<Object3D>;
|
||||
|
||||
private var maps:Dictionary;
|
||||
|
||||
private var materials:Dictionary;
|
||||
|
||||
private var protocol:Protocol;
|
||||
|
||||
private var name_gk:Object;
|
||||
|
||||
private var name_Y8:Boolean = false;
|
||||
|
||||
public function ParserA3D()
|
||||
{
|
||||
super();
|
||||
this.init();
|
||||
}
|
||||
|
||||
private static function convert1_2(source:A3D) : A3D2
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var sourceBox:A3DBox = null;
|
||||
var destBox:A3D2Box = null;
|
||||
var sourceGeometry:A3DGeometry = null;
|
||||
var sourceImage:A3DImage = null;
|
||||
var destImage:A3D2Image = null;
|
||||
var sourceMap:A3DMap = null;
|
||||
var destMap:A3D2Map = null;
|
||||
var sourceMaterial:A3DMaterial = null;
|
||||
var destMaterial:A3D2Material = null;
|
||||
var sourceObject:A3DObject = null;
|
||||
var destMesh:A3D2Mesh = null;
|
||||
var destIndexBufferId:int = 0;
|
||||
var destVertexBuffersIds:Vector.<int> = null;
|
||||
var sourceIndexBuffer:A3DIndexBuffer = null;
|
||||
var sourceVertexBuffers:Vector.<A3DVertexBuffer> = null;
|
||||
var destIndexBuffer:A3D2IndexBuffer = null;
|
||||
var j:int = 0;
|
||||
var inCount:int = 0;
|
||||
var sourceVertexBuffer:A3DVertexBuffer = null;
|
||||
var sourceAttributes:Vector.<int> = null;
|
||||
var destAttributes:Vector.<A3D2VertexAttributes> = null;
|
||||
var k:int = 0;
|
||||
var kCount:int = 0;
|
||||
var destVertexBuffer:A3D2VertexBuffer = null;
|
||||
var attr:int = 0;
|
||||
var _loc47_:A3D2Object = null;
|
||||
var sourceBoxes:Vector.<A3DBox> = source.boxes;
|
||||
var destBoxes:Vector.<A3D2Box> = null;
|
||||
if(sourceBoxes != null)
|
||||
{
|
||||
destBoxes = new Vector.<A3D2Box>();
|
||||
for(i = 0,count = int(sourceBoxes.length); i < count; i++)
|
||||
{
|
||||
sourceBox = sourceBoxes[i];
|
||||
destBox = new A3D2Box(sourceBox.box,sourceBox.id.id);
|
||||
destBoxes[i] = destBox;
|
||||
}
|
||||
}
|
||||
var sourceGeometries:Dictionary = new Dictionary();
|
||||
if(source.geometries != null)
|
||||
{
|
||||
for each(sourceGeometry in source.geometries)
|
||||
{
|
||||
sourceGeometries[sourceGeometry.id.id] = sourceGeometry;
|
||||
}
|
||||
}
|
||||
var sourceImages:Vector.<A3DImage> = source.images;
|
||||
var destImages:Vector.<A3D2Image> = null;
|
||||
if(sourceImages != null)
|
||||
{
|
||||
destImages = new Vector.<A3D2Image>();
|
||||
for(i = 0,count = int(sourceImages.length); i < count; i++)
|
||||
{
|
||||
sourceImage = sourceImages[i];
|
||||
destImage = new A3D2Image(sourceImage.id.id,sourceImage.url);
|
||||
destImages[i] = destImage;
|
||||
}
|
||||
}
|
||||
var sourceMaps:Vector.<A3DMap> = source.maps;
|
||||
var destMaps:Vector.<A3D2Map> = null;
|
||||
if(sourceMaps != null)
|
||||
{
|
||||
destMaps = new Vector.<A3D2Map>();
|
||||
for(i = 0,count = int(sourceMaps.length); i < count; i++)
|
||||
{
|
||||
sourceMap = sourceMaps[i];
|
||||
destMap = new A3D2Map(sourceMap.channel,sourceMap.id.id,sourceMap.imageId.id);
|
||||
destMaps[i] = destMap;
|
||||
}
|
||||
}
|
||||
var sourceMaterials:Vector.<A3DMaterial> = source.materials;
|
||||
var destMaterials:Vector.<A3D2Material> = null;
|
||||
if(sourceMaterials != null)
|
||||
{
|
||||
destMaterials = new Vector.<A3D2Material>();
|
||||
for(i = 0,count = int(sourceMaterials.length); i < count; i++)
|
||||
{
|
||||
sourceMaterial = sourceMaterials[i];
|
||||
destMaterial = new A3D2Material(idToInt(sourceMaterial.diffuseMapId),idToInt(sourceMaterial.glossinessMapId),idToInt(sourceMaterial.id),idToInt(sourceMaterial.lightMapId),idToInt(sourceMaterial.normalMapId),idToInt(sourceMaterial.opacityMapId),-1,idToInt(sourceMaterial.specularMapId));
|
||||
destMaterials[i] = destMaterial;
|
||||
}
|
||||
}
|
||||
var sourceObjects:Vector.<A3DObject> = source.objects;
|
||||
var destObjects:Vector.<A3D2Object> = null;
|
||||
var destMeshes:Vector.<A3D2Mesh> = null;
|
||||
var destVertexBuffers:Vector.<A3D2VertexBuffer> = null;
|
||||
var destIndexBuffers:Vector.<A3D2IndexBuffer> = null;
|
||||
var lastIndexBufferIndex:uint = 0;
|
||||
var lastVertexBufferIndex:uint = 0;
|
||||
var objectsMap:Dictionary = new Dictionary();
|
||||
if(sourceObjects != null)
|
||||
{
|
||||
destMeshes = new Vector.<A3D2Mesh>();
|
||||
destObjects = new Vector.<A3D2Object>();
|
||||
destVertexBuffers = new Vector.<A3D2VertexBuffer>();
|
||||
destIndexBuffers = new Vector.<A3D2IndexBuffer>();
|
||||
for(i = 0,count = int(sourceObjects.length); i < count; i++)
|
||||
{
|
||||
sourceObject = sourceObjects[i];
|
||||
if(sourceObject.surfaces != null && sourceObject.surfaces.length > 0)
|
||||
{
|
||||
destMesh = null;
|
||||
sourceGeometry = sourceGeometries[sourceObject.geometryId.id];
|
||||
destIndexBufferId = -1;
|
||||
destVertexBuffersIds = new Vector.<int>();
|
||||
if(sourceGeometry != null)
|
||||
{
|
||||
sourceIndexBuffer = sourceGeometry.indexBuffer;
|
||||
sourceVertexBuffers = sourceGeometry.vertexBuffers;
|
||||
destIndexBuffer = new A3D2IndexBuffer(sourceIndexBuffer.byteBuffer,lastIndexBufferIndex++,sourceIndexBuffer.indexCount);
|
||||
destIndexBufferId = destIndexBuffer.id;
|
||||
destIndexBuffers.push(destIndexBuffer);
|
||||
for(j = 0,inCount = int(sourceVertexBuffers.length); j < inCount; j++)
|
||||
{
|
||||
sourceVertexBuffer = sourceVertexBuffers[j];
|
||||
sourceAttributes = sourceVertexBuffer.attributes;
|
||||
destAttributes = new Vector.<A3D2VertexAttributes>();
|
||||
for(k = 0,kCount = int(sourceAttributes.length); k < kCount; )
|
||||
{
|
||||
attr = sourceAttributes[k];
|
||||
switch(attr)
|
||||
{
|
||||
case 0:
|
||||
destAttributes[k] = A3D2VertexAttributes.POSITION;
|
||||
break;
|
||||
case 1:
|
||||
destAttributes[k] = A3D2VertexAttributes.NORMAL;
|
||||
break;
|
||||
case 2:
|
||||
destAttributes[k] = A3D2VertexAttributes.TANGENT4;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
destAttributes[k] = A3D2VertexAttributes.TEXCOORD;
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
destVertexBuffer = new A3D2VertexBuffer(destAttributes,sourceVertexBuffer.byteBuffer,lastVertexBufferIndex++,sourceVertexBuffer.vertexCount);
|
||||
destVertexBuffers.push(destVertexBuffer);
|
||||
destVertexBuffersIds.push(destVertexBuffer.id);
|
||||
}
|
||||
}
|
||||
destMesh = new A3D2Mesh(idToInt(sourceObject.boundBoxId),idToLong(sourceObject.id),destIndexBufferId,sourceObject.name,convertParent1_2(sourceObject.parentId),convertSurfaces1_2(sourceObject.surfaces),new A3D2Transform(sourceObject.transformation.matrix),destVertexBuffersIds,sourceObject.visible);
|
||||
destMeshes.push(destMesh);
|
||||
objectsMap[sourceObject.id.id] = destMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc47_ = new A3D2Object(idToInt(sourceObject.boundBoxId),idToLong(sourceObject.id),sourceObject.name,convertParent1_2(sourceObject.parentId),new A3D2Transform(sourceObject.transformation.matrix),sourceObject.visible);
|
||||
destObjects.push(_loc47_);
|
||||
objectsMap[sourceObject.id.id] = _loc47_;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new A3D2(null,null,null,destBoxes,null,null,null,destImages,destIndexBuffers,null,destMaps,destMaterials,destMeshes != null && destMeshes.length > 0 ? destMeshes : null,destObjects != null && destObjects.length > 0 ? destObjects : null,null,null,null,null,destVertexBuffers);
|
||||
}
|
||||
|
||||
private static function idToInt(id:Id) : int
|
||||
{
|
||||
return id != null ? int(id.id) : -1;
|
||||
}
|
||||
|
||||
private static function idToLong(id:Id) : Long
|
||||
{
|
||||
return id != null ? Long.fromInt(id.id) : Long.fromInt(-1);
|
||||
}
|
||||
|
||||
private static function convertParent1_2(parentId:ParentId) : Long
|
||||
{
|
||||
if(parentId == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return parentId != null ? Long.fromInt(parentId.id) : null;
|
||||
}
|
||||
|
||||
private static function convertSurfaces1_2(source:Vector.<A3DSurface>) : Vector.<A3D2Surface>
|
||||
{
|
||||
var sourceSurface:A3DSurface = null;
|
||||
var destSurface:A3D2Surface = null;
|
||||
var dest:Vector.<A3D2Surface> = new Vector.<A3D2Surface>();
|
||||
for(var i:int = 0, count:int = int(source.length); i < count; i++)
|
||||
{
|
||||
sourceSurface = source[i];
|
||||
destSurface = new A3D2Surface(sourceSurface.indexBegin,idToInt(sourceSurface.materialId),sourceSurface.numTriangles);
|
||||
dest[i] = destSurface;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
public function parse(input:ByteArray) : void
|
||||
{
|
||||
var version:int = 0;
|
||||
try
|
||||
{
|
||||
input.position = 0;
|
||||
version = int(input.readByte());
|
||||
if(version == 0)
|
||||
{
|
||||
this.parseVersion1(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parseVersionOver1(input);
|
||||
}
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
throw new Error("parsing failed",0);
|
||||
}
|
||||
}
|
||||
|
||||
public function getObjectByName(name:String) : Object3D
|
||||
{
|
||||
var object:Object3D = null;
|
||||
for each(object in this.objects)
|
||||
{
|
||||
if(object.name == name)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function init() : void
|
||||
{
|
||||
if(this.name_Y8)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(OSGi.getInstance() != null)
|
||||
{
|
||||
this.protocol = Protocol(OSGi.getInstance().getService(IProtocol));
|
||||
return;
|
||||
}
|
||||
OSGi.clientLog = new DummyClientLog();
|
||||
var osgi:OSGi = new OSGi();
|
||||
osgi.registerService(IClientLog,new DummyClientLog());
|
||||
new ProtocolActivator().start(osgi);
|
||||
new platform.client.formats.a3d.osgi.Activator().start(osgi);
|
||||
new platform.clients.fp10.libraries.alternativaprotocol.Activator().start(osgi);
|
||||
this.protocol = Protocol(osgi.getService(IProtocol));
|
||||
this.name_Y8 = true;
|
||||
}
|
||||
|
||||
private function parseVersion1(input:ByteArray) : void
|
||||
{
|
||||
input.position = 4;
|
||||
var nullMap:OptionalMap = OptionalMapCodecHelper.decodeNullMap(input);
|
||||
nullMap.setReadPosition(0);
|
||||
var data:ByteArray = new ByteArray();
|
||||
data.writeBytes(input,input.position);
|
||||
data.position = 0;
|
||||
var buffer:ProtocolBuffer = new ProtocolBuffer(data,data,nullMap);
|
||||
var codec:ICodec = this.protocol.getCodec(new TypeCodecInfo(A3D,false));
|
||||
var _a3d:A3D = A3D(codec.decode(buffer));
|
||||
var a3d2:A3D2 = convert1_2(_a3d);
|
||||
this.doParse2_0(a3d2);
|
||||
}
|
||||
|
||||
private function doParse2_0(a3d:A3D2) : void
|
||||
{
|
||||
var a3DObject:A3D2Object = null;
|
||||
var a3DMesh:A3D2Mesh = null;
|
||||
var a3DIndexBuffer:A3D2IndexBuffer = null;
|
||||
var a3DVertexBuffer:A3D2VertexBuffer = null;
|
||||
var a3DMaterial:A3D2Material = null;
|
||||
var a3DBox:A3D2Box = null;
|
||||
var a3DMap:A3D2Map = null;
|
||||
var a3DImage:A3D2Image = null;
|
||||
var a3DAmbientLight:A3D2AmbientLight = null;
|
||||
var a3DOmniLight:A3D2OmniLight = null;
|
||||
var a3DSpotLight:A3D2SpotLight = null;
|
||||
var a3DDirLight:A3D2DirectionalLight = null;
|
||||
var a3DSkin:A3D2Skin = null;
|
||||
var a3DJoint:A3D2Joint = null;
|
||||
var parent:Long = null;
|
||||
var p:Object3D = null;
|
||||
var object:Object3D = null;
|
||||
var resJoint:Joint = null;
|
||||
var resSkin:Mesh = null;
|
||||
var resAmbientLight:AmbientLight = null;
|
||||
var resObject:Object3D = null;
|
||||
var resOmniLight:OmniLight = null;
|
||||
var resSpotLight:SpotLight = null;
|
||||
var resDirLight:DirectionalLight = null;
|
||||
var resMesh:Mesh = null;
|
||||
var objectsMap:Dictionary = new Dictionary();
|
||||
var a3DIndexBuffers:Dictionary = new Dictionary();
|
||||
var a3DVertexBuffers:Dictionary = new Dictionary();
|
||||
var a3DMaterials:Dictionary = new Dictionary();
|
||||
var a3DBoxes:Dictionary = new Dictionary();
|
||||
var a3DMaps:Dictionary = new Dictionary();
|
||||
var a3DImages:Dictionary = new Dictionary();
|
||||
var parents:Dictionary = new Dictionary();
|
||||
for each(a3DIndexBuffer in a3d.indexBuffers)
|
||||
{
|
||||
a3DIndexBuffers[a3DIndexBuffer.id] = a3DIndexBuffer;
|
||||
}
|
||||
for each(a3DVertexBuffer in a3d.vertexBuffers)
|
||||
{
|
||||
a3DVertexBuffers[a3DVertexBuffer.id] = a3DVertexBuffer;
|
||||
}
|
||||
for each(a3DBox in a3d.boxes)
|
||||
{
|
||||
a3DBoxes[a3DBox.id] = a3DBox;
|
||||
}
|
||||
for each(a3DMaterial in a3d.materials)
|
||||
{
|
||||
a3DMaterials[a3DMaterial.id] = a3DMaterial;
|
||||
}
|
||||
for each(a3DMap in a3d.maps)
|
||||
{
|
||||
a3DMaps[a3DMap.id] = a3DMap;
|
||||
}
|
||||
for each(a3DImage in a3d.images)
|
||||
{
|
||||
a3DImages[a3DImage.id] = a3DImage;
|
||||
}
|
||||
this.hierarchy = new Vector.<Object3D>();
|
||||
this.objects = new Vector.<Object3D>();
|
||||
this.maps = new Dictionary();
|
||||
this.materials = new Dictionary();
|
||||
this.name_gk = new Dictionary();
|
||||
for each(a3DJoint in a3d.joints)
|
||||
{
|
||||
resJoint = new Joint();
|
||||
resJoint.visible = a3DJoint.visible;
|
||||
resJoint.name = a3DJoint.name;
|
||||
parents[resJoint] = a3DJoint.parentId;
|
||||
objectsMap[a3DJoint.id] = resJoint;
|
||||
if(a3DJoint.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resJoint);
|
||||
}
|
||||
this.objects.push(resJoint);
|
||||
this.decomposeTransformation(a3DJoint.transform,resJoint);
|
||||
a3DBox = a3DBoxes[a3DJoint.boundBoxId];
|
||||
if(a3DBox != null)
|
||||
{
|
||||
this.parseBoundBox(a3DBox.box,resJoint);
|
||||
}
|
||||
}
|
||||
for each(a3DSkin in a3d.skins)
|
||||
{
|
||||
resSkin = this.parseSkin(a3DSkin,a3DIndexBuffers,a3DVertexBuffers,a3DMaterials,a3DMaps,a3DImages);
|
||||
resSkin.visible = a3DSkin.visible;
|
||||
resSkin.name = a3DSkin.name;
|
||||
parents[resSkin] = a3DSkin.parentId;
|
||||
objectsMap[a3DSkin.id] = resSkin;
|
||||
if(a3DSkin.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resSkin);
|
||||
}
|
||||
this.objects.push(resSkin);
|
||||
this.decomposeTransformation(a3DSkin.transform,resSkin);
|
||||
a3DBox = a3DBoxes[a3DSkin.boundBoxId];
|
||||
if(a3DBox != null)
|
||||
{
|
||||
this.parseBoundBox(a3DBox.box,resSkin);
|
||||
}
|
||||
}
|
||||
for each(a3DAmbientLight in a3d.ambientLights)
|
||||
{
|
||||
resAmbientLight = new AmbientLight(a3DAmbientLight.color);
|
||||
resAmbientLight.intensity = a3DAmbientLight.intensity;
|
||||
resAmbientLight.visible = a3DAmbientLight.visible;
|
||||
resAmbientLight.name = a3DAmbientLight.name;
|
||||
parents[resAmbientLight] = a3DAmbientLight.parentId;
|
||||
objectsMap[a3DAmbientLight.id] = resAmbientLight;
|
||||
if(a3DAmbientLight.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resAmbientLight);
|
||||
}
|
||||
this.objects.push(resAmbientLight);
|
||||
this.decomposeTransformation(a3DAmbientLight.transform,resAmbientLight);
|
||||
a3DBox = a3DBoxes[a3DAmbientLight.boundBoxId];
|
||||
if(a3DBox != null)
|
||||
{
|
||||
this.parseBoundBox(a3DBox.box,resAmbientLight);
|
||||
}
|
||||
}
|
||||
for each(a3DObject in a3d.objects)
|
||||
{
|
||||
resObject = new Object3D();
|
||||
resObject.visible = a3DObject.visible;
|
||||
resObject.name = a3DObject.name;
|
||||
parents[resObject] = a3DObject.parentId;
|
||||
objectsMap[a3DObject.id] = resObject;
|
||||
if(a3DObject.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resObject);
|
||||
}
|
||||
this.objects.push(resObject);
|
||||
this.decomposeTransformation(a3DObject.transform,resObject);
|
||||
a3DBox = a3DBoxes[a3DObject.boundBoxId];
|
||||
if(a3DBox != null)
|
||||
{
|
||||
this.parseBoundBox(a3DBox.box,resObject);
|
||||
}
|
||||
}
|
||||
for each(a3DOmniLight in a3d.omniLights)
|
||||
{
|
||||
resOmniLight = new OmniLight(a3DOmniLight.color,a3DOmniLight.attenuationBegin,a3DOmniLight.attenuationEnd);
|
||||
resOmniLight.visible = a3DOmniLight.visible;
|
||||
resOmniLight.name = a3DOmniLight.name;
|
||||
parents[resOmniLight] = a3DOmniLight.parentId;
|
||||
objectsMap[a3DOmniLight.id] = resOmniLight;
|
||||
if(a3DOmniLight.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resOmniLight);
|
||||
}
|
||||
this.objects.push(resOmniLight);
|
||||
this.decomposeTransformation(a3DOmniLight.transform,resOmniLight);
|
||||
}
|
||||
for each(a3DSpotLight in a3d.spotLights)
|
||||
{
|
||||
resSpotLight = new SpotLight(a3DSpotLight.color,a3DSpotLight.attenuationBegin,a3DSpotLight.attenuationEnd,a3DSpotLight.hotspot,a3DSpotLight.falloff);
|
||||
resSpotLight.visible = a3DSpotLight.visible;
|
||||
resSpotLight.name = a3DSpotLight.name;
|
||||
parents[resSpotLight] = a3DSpotLight.parentId;
|
||||
objectsMap[a3DSpotLight.id] = resSpotLight;
|
||||
if(a3DSpotLight.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resSpotLight);
|
||||
}
|
||||
this.objects.push(resSpotLight);
|
||||
this.decomposeTransformation(a3DSpotLight.transform,resSpotLight);
|
||||
}
|
||||
for each(a3DDirLight in a3d.directionalLights)
|
||||
{
|
||||
resDirLight = new DirectionalLight(a3DDirLight.color);
|
||||
resDirLight.visible = a3DDirLight.visible;
|
||||
resDirLight.name = a3DDirLight.name;
|
||||
parents[resDirLight] = a3DDirLight.parentId;
|
||||
objectsMap[a3DDirLight.id] = resDirLight;
|
||||
if(a3DDirLight.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resDirLight);
|
||||
}
|
||||
this.objects.push(resDirLight);
|
||||
this.decomposeTransformation(a3DDirLight.transform,resDirLight);
|
||||
}
|
||||
for each(a3DMesh in a3d.meshes)
|
||||
{
|
||||
resMesh = this.parseMesh(a3DMesh,a3DIndexBuffers,a3DVertexBuffers,a3DMaterials,a3DMaps,a3DImages);
|
||||
resMesh.visible = a3DMesh.visible;
|
||||
resMesh.name = a3DMesh.name;
|
||||
parents[resMesh] = a3DMesh.parentId;
|
||||
objectsMap[a3DMesh.id] = resMesh;
|
||||
if(a3DMesh.parentId == null)
|
||||
{
|
||||
this.hierarchy.push(resMesh);
|
||||
}
|
||||
this.objects.push(resMesh);
|
||||
this.decomposeTransformation(a3DMesh.transform,resMesh);
|
||||
a3DBox = a3DBoxes[a3DMesh.boundBoxId];
|
||||
if(a3DBox != null)
|
||||
{
|
||||
this.parseBoundBox(a3DBox.box,resMesh);
|
||||
}
|
||||
}
|
||||
for each(object in objectsMap)
|
||||
{
|
||||
parent = parents[object];
|
||||
if(parent != null)
|
||||
{
|
||||
p = objectsMap[parent];
|
||||
p.addChild(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parseSurfaceJoints(source:Vector.<Vector.<Long>>, objectsMap:Dictionary) : Vector.<Vector.<Joint>>
|
||||
{
|
||||
var vector:Vector.<Long> = null;
|
||||
var resultVector:Vector.<Joint> = null;
|
||||
var j:int = 0;
|
||||
var jcount:int = 0;
|
||||
var result:Vector.<Vector.<Joint>> = new Vector.<Vector.<Joint>>();
|
||||
for(var i:int = 0, count:int = int(source.length); i < count; i++)
|
||||
{
|
||||
vector = source[i];
|
||||
resultVector = new Vector.<Joint>();
|
||||
for(j = 0,jcount = int(vector.length); j < jcount; j++)
|
||||
{
|
||||
resultVector[j] = objectsMap[vector[j]];
|
||||
}
|
||||
result[i] = resultVector;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private function parseVersionOver1(input:ByteArray) : void
|
||||
{
|
||||
input.position = 0;
|
||||
var data:ByteArray = new ByteArray();
|
||||
var buffer:ProtocolBuffer = new ProtocolBuffer(data,data,new OptionalMap());
|
||||
PacketHelper.unwrapPacket(input,buffer);
|
||||
input.position = 0;
|
||||
var versionMajor:int = int(buffer.reader.readUnsignedShort());
|
||||
var versionMinor:int = int(buffer.reader.readUnsignedShort());
|
||||
switch(versionMajor)
|
||||
{
|
||||
case 2:
|
||||
this.parseVersion2_0(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private function parseVersion2_0(buffer:ProtocolBuffer) : void
|
||||
{
|
||||
var codec:ICodec = this.protocol.getCodec(new TypeCodecInfo(A3D2,false));
|
||||
var a3d:A3D2 = A3D2(codec.decode(buffer));
|
||||
this.doParse2_0(a3d);
|
||||
}
|
||||
|
||||
private function parseBoundBox(box:Vector.<Number>, destination:Object3D) : void
|
||||
{
|
||||
destination.boundBox = new BoundBox();
|
||||
destination.boundBox.minX = box[0];
|
||||
destination.boundBox.minY = box[1];
|
||||
destination.boundBox.minZ = box[2];
|
||||
destination.boundBox.maxX = box[3];
|
||||
destination.boundBox.maxY = box[4];
|
||||
destination.boundBox.maxZ = box[5];
|
||||
}
|
||||
|
||||
private function decomposeTransformation(transform:A3D2Transform, obj:Object3D) : void
|
||||
{
|
||||
if(transform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var matrix:A3DMatrix = transform.matrix;
|
||||
var mat:Matrix3D = new Matrix3D(Vector.<Number>([matrix.a,matrix.e,matrix.i,0,matrix.b,matrix.f,matrix.j,0,matrix.c,matrix.g,matrix.k,0,matrix.d,matrix.h,matrix.l,1]));
|
||||
var vecs:Vector.<Vector3D> = mat.decompose();
|
||||
obj.x = vecs[0].x;
|
||||
obj.y = vecs[0].y;
|
||||
obj.z = vecs[0].z;
|
||||
obj.rotationX = vecs[1].x;
|
||||
obj.rotationY = vecs[1].y;
|
||||
obj.rotationZ = vecs[1].z;
|
||||
obj.scaleX = vecs[2].x;
|
||||
obj.scaleY = vecs[2].y;
|
||||
obj.scaleZ = vecs[2].z;
|
||||
}
|
||||
|
||||
private function decomposeBindTransformation(transform:A3D2Transform, obj:Joint) : void
|
||||
{
|
||||
if(transform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var matrix:A3DMatrix = transform.matrix;
|
||||
var mat:Vector.<Number> = Vector.<Number>([matrix.a,matrix.b,matrix.c,matrix.d,matrix.e,matrix.f,matrix.g,matrix.h,matrix.i,matrix.j,matrix.k,matrix.l]);
|
||||
obj.alternativa3d::setBindPoseMatrix(mat);
|
||||
}
|
||||
|
||||
private function parseMesh(a3DMesh:A3D2Mesh, indexBuffers:Dictionary, vertexBuffers:Dictionary, materials:Dictionary, maps:Dictionary, images:Dictionary) : Mesh
|
||||
{
|
||||
var s:A3D2Surface = null;
|
||||
var m:ParserMaterial = null;
|
||||
var res:Mesh = new Mesh();
|
||||
res.geometry = this.parseGeometry(a3DMesh.indexBufferId,a3DMesh.vertexBuffers,indexBuffers,vertexBuffers);
|
||||
var surfaces:Vector.<A3D2Surface> = a3DMesh.surfaces;
|
||||
for(var i:int = 0; i < surfaces.length; i++)
|
||||
{
|
||||
s = surfaces[i];
|
||||
m = this.parseMaterial(materials[s.materialId],maps,images);
|
||||
res.addSurface(m,s.indexBegin,s.numTriangles);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private function parseSkin(a3DSkin:A3D2Skin, indexBuffers:Dictionary, vertexBuffers:Dictionary, materials:Dictionary, maps:Dictionary, images:Dictionary) : Skin
|
||||
{
|
||||
var s:A3D2Surface = null;
|
||||
var m:ParserMaterial = null;
|
||||
var res:Skin = new Skin(1,a3DSkin.joints.length);
|
||||
res.geometry = this.parseGeometry(a3DSkin.indexBufferId,a3DSkin.vertexBuffers,indexBuffers,vertexBuffers);
|
||||
var surfaces:Vector.<A3D2Surface> = a3DSkin.surfaces;
|
||||
for(var i:int = 0; i < surfaces.length; i++)
|
||||
{
|
||||
s = surfaces[i];
|
||||
m = this.parseMaterial(materials[s.materialId],maps,images);
|
||||
res.addSurface(m,s.indexBegin,s.numTriangles);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private function traceGeometry(geometry:Geometry) : void
|
||||
{
|
||||
var offset:int = 0;
|
||||
var i:int = 0;
|
||||
var attr:int = 0;
|
||||
var vertexStream:VertexStream = geometry.alternativa3d::_vertexStreams[0];
|
||||
var prev:int = -1;
|
||||
var stride:int = vertexStream.attributes.length * 4;
|
||||
var length:int = vertexStream.data.length / stride;
|
||||
var data:ByteArray = vertexStream.data;
|
||||
for(var j:int = 0; j < length; j++)
|
||||
{
|
||||
offset = -4;
|
||||
for(i = 0; i < stride; i++)
|
||||
{
|
||||
attr = int(vertexStream.attributes[i]);
|
||||
offset += 4;
|
||||
if(attr != prev)
|
||||
{
|
||||
switch(attr)
|
||||
{
|
||||
case VertexAttributes.JOINTS[0]:
|
||||
data.position = j * stride + offset;
|
||||
trace("JOINT0:",data.readFloat(),data.readFloat(),data.readFloat(),data.readFloat());
|
||||
break;
|
||||
case VertexAttributes.JOINTS[1]:
|
||||
data.position = j * stride + offset;
|
||||
trace("JOINT1:",data.readFloat(),data.readFloat(),data.readFloat(),data.readFloat());
|
||||
}
|
||||
prev = attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parseGeometry(indexBufferID:int, vertexBuffersIDs:Vector.<int>, indexBuffers:Dictionary, vertexBuffers:Dictionary) : Geometry
|
||||
{
|
||||
var id:int = 0;
|
||||
var geometry:Geometry = null;
|
||||
var vertexCount:uint = 0;
|
||||
var buffer:A3D2VertexBuffer = null;
|
||||
var byteArray:ByteArray = null;
|
||||
var offset:int = 0;
|
||||
var attributes:Array = null;
|
||||
var jointsOffset:int = 0;
|
||||
var k:int = 0;
|
||||
var attr:int = 0;
|
||||
var numFloats:int = 0;
|
||||
var t:int = 0;
|
||||
var key:String = "i" + indexBufferID.toString();
|
||||
for each(id in vertexBuffersIDs)
|
||||
{
|
||||
key += "v" + id.toString();
|
||||
}
|
||||
geometry = this.name_gk[key];
|
||||
if(geometry != null)
|
||||
{
|
||||
return geometry;
|
||||
}
|
||||
geometry = new Geometry();
|
||||
var a3dIB:A3D2IndexBuffer = indexBuffers[indexBufferID];
|
||||
var indices:Vector.<uint> = A3DUtils.byteArrayToVectorUint(a3dIB.byteBuffer);
|
||||
var uvoffset:int = 0;
|
||||
geometry.alternativa3d::_indices = indices;
|
||||
var buffers:Vector.<int> = vertexBuffersIDs;
|
||||
for(var j:int = 0; j < buffers.length; j++)
|
||||
{
|
||||
buffer = vertexBuffers[buffers[j]];
|
||||
vertexCount = buffer.vertexCount;
|
||||
byteArray = buffer.byteBuffer;
|
||||
byteArray.endian = Endian.LITTLE_ENDIAN;
|
||||
offset = 0;
|
||||
attributes = new Array();
|
||||
jointsOffset = 0;
|
||||
for(k = 0; k < buffer.attributes.length; k++)
|
||||
{
|
||||
switch(buffer.attributes[k])
|
||||
{
|
||||
case A3D2VertexAttributes.POSITION:
|
||||
attr = int(VertexAttributes.POSITION);
|
||||
break;
|
||||
case A3D2VertexAttributes.NORMAL:
|
||||
attr = int(VertexAttributes.NORMAL);
|
||||
break;
|
||||
case A3D2VertexAttributes.TANGENT4:
|
||||
attr = int(VertexAttributes.TANGENT4);
|
||||
break;
|
||||
case A3D2VertexAttributes.TEXCOORD:
|
||||
attr = int(VertexAttributes.TEXCOORDS[uvoffset]);
|
||||
uvoffset++;
|
||||
break;
|
||||
case A3D2VertexAttributes.JOINT:
|
||||
attr = int(VertexAttributes.JOINTS[jointsOffset]);
|
||||
jointsOffset++;
|
||||
}
|
||||
numFloats = VertexAttributes.getAttributeStride(attr);
|
||||
numFloats = numFloats < 1 ? 1 : numFloats;
|
||||
for(t = 0; t < numFloats; t++)
|
||||
{
|
||||
attributes[offset] = attr;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
geometry.addVertexStream(attributes);
|
||||
geometry.alternativa3d::_vertexStreams[0].data = byteArray;
|
||||
}
|
||||
geometry.alternativa3d::_numVertices = buffers.length > 0 ? int(vertexCount) : 0;
|
||||
this.name_gk[key] = geometry;
|
||||
return geometry;
|
||||
}
|
||||
|
||||
private function parseMap(source:A3D2Map, images:Dictionary) : ExternalTextureResource
|
||||
{
|
||||
if(source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var res:ExternalTextureResource = this.maps[source.imageId];
|
||||
if(res != null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return this.maps[source.imageId] = new ExternalTextureResource(images[source.imageId].url);
|
||||
}
|
||||
|
||||
private function parseMaterial(source:A3D2Material, a3DMaps:Dictionary, images:Dictionary) : ParserMaterial
|
||||
{
|
||||
if(source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var res:ParserMaterial = this.materials[source.id];
|
||||
if(res != null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res = this.materials[source.id] = new ParserMaterial();
|
||||
res.textures["diffuse"] = this.parseMap(a3DMaps[source.diffuseMapId],images);
|
||||
res.textures["emission"] = this.parseMap(a3DMaps[source.lightMapId],images);
|
||||
res.textures["bump"] = this.parseMap(a3DMaps[source.normalMapId],images);
|
||||
res.textures["specular"] = this.parseMap(a3DMaps[source.specularMapId],images);
|
||||
res.textures["glossiness"] = this.parseMap(a3DMaps[source.glossinessMapId],images);
|
||||
res.textures["transparent"] = this.parseMap(a3DMaps[source.opacityMapId],images);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import alternativa.osgi.service.clientlog.IClientLog;
|
||||
import alternativa.osgi.service.clientlog.IClientLogChannelListener;
|
||||
|
||||
class DummyClientLog implements IClientLog
|
||||
{
|
||||
public function DummyClientLog()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function logError(channelName:String, text:String, ... vars) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function log(channelName:String, text:String, ... rest) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function getChannelStrings(channelName:String) : Vector.<String>
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function addLogListener(listener:IClientLogChannelListener) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function removeLogListener(listener:IClientLogChannelListener) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function addLogChannelListener(channelName:String, listener:IClientLogChannelListener) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function removeLogChannelListener(channelName:String, listener:IClientLogChannelListener) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function getChannelNames() : Vector.<String>
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,440 +0,0 @@
|
||||
package alternativa.engine3d.loaders
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.AnimationClip;
|
||||
import alternativa.engine3d.animation.keys.Track;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.loaders.collada.DaeDocument;
|
||||
import alternativa.engine3d.loaders.collada.DaeMaterial;
|
||||
import alternativa.engine3d.loaders.collada.DaeNode;
|
||||
import alternativa.engine3d.loaders.collada.DaeObject;
|
||||
import alternativa.engine3d.resources.ExternalTextureResource;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParserCollada
|
||||
{
|
||||
public var hierarchy:Vector.<Object3D>;
|
||||
|
||||
public var objects:Vector.<Object3D>;
|
||||
|
||||
public var lights:Vector.<Light3D>;
|
||||
|
||||
public var materials:Vector.<ParserMaterial>;
|
||||
|
||||
public var name_eL:Vector.<AnimationClip>;
|
||||
|
||||
private var name_W6:Dictionary;
|
||||
|
||||
public function ParserCollada()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static function parseAnimation(data:XML) : AnimationClip
|
||||
{
|
||||
var document:DaeDocument = new DaeDocument(data,0);
|
||||
var clip:AnimationClip = new AnimationClip();
|
||||
collectAnimation(clip,document.scene.nodes);
|
||||
return clip.numTracks > 0 ? clip : null;
|
||||
}
|
||||
|
||||
private static function collectAnimation(clip:AnimationClip, nodes:Vector.<DaeNode>) : void
|
||||
{
|
||||
var node:DaeNode = null;
|
||||
var animation:AnimationClip = null;
|
||||
var t:int = 0;
|
||||
var numTracks:int = 0;
|
||||
var track:Track = null;
|
||||
for(var i:int = 0, count:int = int(nodes.length); i < count; i++)
|
||||
{
|
||||
node = nodes[i];
|
||||
animation = node.parseAnimation();
|
||||
if(animation != null)
|
||||
{
|
||||
for(t = 0,numTracks = animation.numTracks; t < numTracks; t++)
|
||||
{
|
||||
track = animation.getTrackAt(t);
|
||||
clip.addTrack(track);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(node.createStaticTransformTrack());
|
||||
}
|
||||
collectAnimation(clip,node.nodes);
|
||||
}
|
||||
}
|
||||
|
||||
public function clean() : void
|
||||
{
|
||||
this.objects = null;
|
||||
this.hierarchy = null;
|
||||
this.lights = null;
|
||||
this.name_eL = null;
|
||||
this.materials = null;
|
||||
this.name_W6 = null;
|
||||
}
|
||||
|
||||
public function getObjectLayer(object:Object3D) : String
|
||||
{
|
||||
return this.name_W6[object];
|
||||
}
|
||||
|
||||
private function init(data:XML, units:Number) : DaeDocument
|
||||
{
|
||||
this.clean();
|
||||
this.objects = new Vector.<Object3D>();
|
||||
this.hierarchy = new Vector.<Object3D>();
|
||||
this.lights = new Vector.<Light3D>();
|
||||
this.name_eL = new Vector.<AnimationClip>();
|
||||
this.materials = new Vector.<ParserMaterial>();
|
||||
this.name_W6 = new Dictionary(true);
|
||||
return new DaeDocument(data,units);
|
||||
}
|
||||
|
||||
public function parse(data:XML, baseURL:String = null, trimPaths:Boolean = false) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var document:DaeDocument = this.init(data,0);
|
||||
if(document.scene != null)
|
||||
{
|
||||
this.parseNodes(document.scene.nodes,null,false);
|
||||
this.parseMaterials(document.materials,baseURL,trimPaths);
|
||||
for(i = 0,count = int(this.hierarchy.length); i < count; i++)
|
||||
{
|
||||
this.hierarchy[i].calculateBoundBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addObject(animatedObject:DaeObject, parent:Object3D, layer:String) : Object3D
|
||||
{
|
||||
var object:Object3D = Object3D(animatedObject.object);
|
||||
this.objects.push(object);
|
||||
if(parent == null)
|
||||
{
|
||||
this.hierarchy.push(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.addChild(object);
|
||||
}
|
||||
if(object is Light3D)
|
||||
{
|
||||
this.lights.push(Light3D(object));
|
||||
}
|
||||
if(animatedObject.animation != null)
|
||||
{
|
||||
this.name_eL.push(animatedObject.animation);
|
||||
}
|
||||
if(Boolean(layer))
|
||||
{
|
||||
this.name_W6[object] = layer;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private function addObjects(animatedObjects:Vector.<DaeObject>, parent:Object3D, layer:String) : Object3D
|
||||
{
|
||||
var first:Object3D = this.addObject(animatedObjects[0],parent,layer);
|
||||
for(var i:int = 1, count:int = int(animatedObjects.length); i < count; i++)
|
||||
{
|
||||
this.addObject(animatedObjects[i],parent,layer);
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
private function hasSkinsInChildren(node:DaeNode) : Boolean
|
||||
{
|
||||
var child:DaeNode = null;
|
||||
var nodes:Vector.<DaeNode> = node.nodes;
|
||||
for(var i:int = 0, count:int = int(nodes.length); i < count; )
|
||||
{
|
||||
child = nodes[i];
|
||||
child.parse();
|
||||
if(child.skins != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(this.hasSkinsInChildren(child))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function parseNodes(nodes:Vector.<DaeNode>, parent:Object3D, skinsOnly:Boolean = false) : void
|
||||
{
|
||||
var node:DaeNode = null;
|
||||
var container:Object3D = null;
|
||||
for(var i:int = 0, count:int = int(nodes.length); i < count; )
|
||||
{
|
||||
node = nodes[i];
|
||||
node.parse();
|
||||
container = null;
|
||||
if(node.skins != null)
|
||||
{
|
||||
container = this.addObjects(node.skins,parent,node.layer);
|
||||
}
|
||||
else if(!skinsOnly && !node.skinOrTopmostJoint)
|
||||
{
|
||||
if(node.objects != null)
|
||||
{
|
||||
container = this.addObjects(node.objects,parent,node.layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
container = new Object3D();
|
||||
container.name = node.cloneString(node.name);
|
||||
this.addObject(node.applyAnimation(node.applyTransformations(container)),parent,node.layer);
|
||||
}
|
||||
}
|
||||
else if(this.hasSkinsInChildren(node))
|
||||
{
|
||||
container = new Object3D();
|
||||
container.name = node.cloneString(node.name);
|
||||
this.addObject(node.applyAnimation(node.applyTransformations(container)),parent,node.layer);
|
||||
this.parseNodes(node.nodes,container,skinsOnly || node.skinOrTopmostJoint);
|
||||
}
|
||||
if(container != null)
|
||||
{
|
||||
this.parseNodes(node.nodes,container,skinsOnly || node.skinOrTopmostJoint);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function trimPath(path:String) : String
|
||||
{
|
||||
var index:int = int(path.lastIndexOf("/"));
|
||||
return index < 0 ? path : path.substr(index + 1);
|
||||
}
|
||||
|
||||
private function parseMaterials(materials:Object, baseURL:String, trimPaths:Boolean) : void
|
||||
{
|
||||
var tmaterial:ParserMaterial = null;
|
||||
var material:DaeMaterial = null;
|
||||
var resource:ExternalTextureResource = null;
|
||||
var base:String = null;
|
||||
var end:int = 0;
|
||||
for each(material in materials)
|
||||
{
|
||||
if(material.used)
|
||||
{
|
||||
material.parse();
|
||||
this.materials.push(material.material);
|
||||
}
|
||||
}
|
||||
if(trimPaths)
|
||||
{
|
||||
for each(tmaterial in this.materials)
|
||||
{
|
||||
for each(resource in tmaterial.textures)
|
||||
{
|
||||
if(resource != null && resource.url != null)
|
||||
{
|
||||
resource.url = this.trimPath(this.fixURL(resource.url));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for each(tmaterial in this.materials)
|
||||
{
|
||||
for each(resource in tmaterial.textures)
|
||||
{
|
||||
if(resource != null && resource.url != null)
|
||||
{
|
||||
resource.url = this.fixURL(resource.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(baseURL != null)
|
||||
{
|
||||
baseURL = this.fixURL(baseURL);
|
||||
end = int(baseURL.lastIndexOf("/"));
|
||||
base = end < 0 ? "" : baseURL.substr(0,end);
|
||||
for each(tmaterial in this.materials)
|
||||
{
|
||||
for each(resource in tmaterial.textures)
|
||||
{
|
||||
if(resource != null && resource.url != null)
|
||||
{
|
||||
resource.url = this.resolveURL(resource.url,base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fixURL(url:String) : String
|
||||
{
|
||||
var pathStart:int = int(url.indexOf("://"));
|
||||
pathStart = pathStart < 0 ? 0 : pathStart + 3;
|
||||
var pathEnd:int = int(url.indexOf("?",pathStart));
|
||||
pathEnd = pathEnd < 0 ? int(url.indexOf("#",pathStart)) : pathEnd;
|
||||
var path:String = url.substring(pathStart,pathEnd < 0 ? 2147483647 : pathEnd);
|
||||
path = path.replace(/\\/g,"/");
|
||||
var fileIndex:int = int(url.indexOf("file://"));
|
||||
if(fileIndex >= 0)
|
||||
{
|
||||
if(url.charAt(pathStart) == "/")
|
||||
{
|
||||
return "file://" + path + (pathEnd >= 0 ? url.substring(pathEnd) : "");
|
||||
}
|
||||
return "file:///" + path + (pathEnd >= 0 ? url.substring(pathEnd) : "");
|
||||
}
|
||||
return url.substring(0,pathStart) + path + (pathEnd >= 0 ? url.substring(pathEnd) : "");
|
||||
}
|
||||
|
||||
private function mergePath(path:String, base:String, relative:Boolean = false) : String
|
||||
{
|
||||
var part:String = null;
|
||||
var basePart:String = null;
|
||||
var baseParts:Array = base.split("/");
|
||||
var parts:Array = path.split("/");
|
||||
for(var i:int = 0, count:int = int(parts.length); i < count; i++)
|
||||
{
|
||||
part = parts[i];
|
||||
if(part == "..")
|
||||
{
|
||||
basePart = baseParts.pop();
|
||||
while(basePart == "." || basePart == "" && basePart != null)
|
||||
{
|
||||
basePart = baseParts.pop();
|
||||
}
|
||||
if(relative)
|
||||
{
|
||||
if(basePart == "..")
|
||||
{
|
||||
baseParts.push("..","..");
|
||||
}
|
||||
else if(basePart == null)
|
||||
{
|
||||
baseParts.push("..");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
baseParts.push(part);
|
||||
}
|
||||
}
|
||||
return baseParts.join("/");
|
||||
}
|
||||
|
||||
private function resolveURL(url:String, base:String) : String
|
||||
{
|
||||
var queryAndFragmentIndex:int = 0;
|
||||
var path:String = null;
|
||||
var queryAndFragment:String = null;
|
||||
var bPath:String = null;
|
||||
var bSlashIndex:int = 0;
|
||||
var bShemeIndex:int = 0;
|
||||
var bAuthorityIndex:int = 0;
|
||||
var bSheme:String = null;
|
||||
var _loc13_:String = null;
|
||||
if(base == "")
|
||||
{
|
||||
return url;
|
||||
}
|
||||
if(url.charAt(0) == "." && url.charAt(1) == "/")
|
||||
{
|
||||
return base + url.substr(1);
|
||||
}
|
||||
if(url.charAt(0) == "/")
|
||||
{
|
||||
return url;
|
||||
}
|
||||
if(url.charAt(0) == "." && url.charAt(1) == ".")
|
||||
{
|
||||
queryAndFragmentIndex = int(url.indexOf("?"));
|
||||
queryAndFragmentIndex = queryAndFragmentIndex < 0 ? int(url.indexOf("#")) : queryAndFragmentIndex;
|
||||
if(queryAndFragmentIndex < 0)
|
||||
{
|
||||
queryAndFragment = "";
|
||||
path = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
queryAndFragment = url.substring(queryAndFragmentIndex);
|
||||
path = url.substring(0,queryAndFragmentIndex);
|
||||
}
|
||||
bSlashIndex = int(base.indexOf("/"));
|
||||
bShemeIndex = int(base.indexOf(":"));
|
||||
bAuthorityIndex = int(base.indexOf("//"));
|
||||
if(bAuthorityIndex < 0 || bAuthorityIndex > bSlashIndex)
|
||||
{
|
||||
if(bShemeIndex >= 0 && bShemeIndex < bSlashIndex)
|
||||
{
|
||||
bSheme = base.substring(0,bShemeIndex + 1);
|
||||
bPath = base.substring(bShemeIndex + 1);
|
||||
if(bPath.charAt(0) == "/")
|
||||
{
|
||||
return bSheme + "/" + this.mergePath(path,bPath.substring(1),false) + queryAndFragment;
|
||||
}
|
||||
return bSheme + this.mergePath(path,bPath,false) + queryAndFragment;
|
||||
}
|
||||
if(base.charAt(0) == "/")
|
||||
{
|
||||
return "/" + this.mergePath(path,base.substring(1),false) + queryAndFragment;
|
||||
}
|
||||
return this.mergePath(path,base,true) + queryAndFragment;
|
||||
}
|
||||
bSlashIndex = int(base.indexOf("/",bAuthorityIndex + 2));
|
||||
if(bSlashIndex >= 0)
|
||||
{
|
||||
_loc13_ = base.substring(0,bSlashIndex + 1);
|
||||
bPath = base.substring(bSlashIndex + 1);
|
||||
return _loc13_ + this.mergePath(path,bPath,false) + queryAndFragment;
|
||||
}
|
||||
_loc13_ = base;
|
||||
return _loc13_ + "/" + this.mergePath(path,"",false);
|
||||
}
|
||||
var shemeIndex:int = int(url.indexOf(":"));
|
||||
var slashIndex:int = int(url.indexOf("/"));
|
||||
if(shemeIndex >= 0 && (shemeIndex < slashIndex || slashIndex < 0))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
return base + "/" + url;
|
||||
}
|
||||
|
||||
public function getObjectByName(name:String) : Object3D
|
||||
{
|
||||
var object:Object3D = null;
|
||||
for each(object in this.objects)
|
||||
{
|
||||
if(object.name == name)
|
||||
{
|
||||
return object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAnimationByObject(object:Object) : AnimationClip
|
||||
{
|
||||
var animation:AnimationClip = null;
|
||||
var objects:Array = null;
|
||||
for each(animation in this.name_eL)
|
||||
{
|
||||
objects = animation.name_Kq;
|
||||
if(objects.indexOf(object) >= 0)
|
||||
{
|
||||
return animation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package alternativa.engine3d.loaders
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.materials.*;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.ExternalTextureResource;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.engine3d.resources.TextureResource;
|
||||
import avmplus.getQualifiedClassName;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ParserMaterial extends Material
|
||||
{
|
||||
public var colors:Object;
|
||||
|
||||
public var textures:Object;
|
||||
|
||||
public var transparency:Number = 0;
|
||||
|
||||
public var name_3m:String = "diffuse";
|
||||
|
||||
private var textureMaterial:TextureMaterial;
|
||||
|
||||
private var name_h7:FillMaterial;
|
||||
|
||||
public function ParserMaterial()
|
||||
{
|
||||
super();
|
||||
this.textures = new Object();
|
||||
this.colors = new Object();
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, resourceType:Class) : void
|
||||
{
|
||||
var texture:TextureResource = null;
|
||||
super.alternativa3d::fillResources(resources,resourceType);
|
||||
for each(texture in this.textures)
|
||||
{
|
||||
if(texture != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(texture)) as Class,resourceType)))
|
||||
{
|
||||
resources[texture] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
var map:ExternalTextureResource = null;
|
||||
var colorO:Object = this.colors[this.name_3m];
|
||||
if(colorO != null)
|
||||
{
|
||||
if(this.name_h7 == null)
|
||||
{
|
||||
this.name_h7 = new FillMaterial(int(colorO));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name_h7.color = int(colorO);
|
||||
}
|
||||
this.name_h7.alternativa3d::collectDraws(camera,surface,geometry,lights,lightsLength,objectRenderPriority);
|
||||
}
|
||||
else
|
||||
{
|
||||
map = this.textures[this.name_3m];
|
||||
if(map != null)
|
||||
{
|
||||
if(this.textureMaterial == null)
|
||||
{
|
||||
this.textureMaterial = new TextureMaterial(map);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.textureMaterial.diffuseMap = map;
|
||||
}
|
||||
this.textureMaterial.alternativa3d::collectDraws(camera,surface,geometry,lights,lightsLength,objectRenderPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeArray extends DaeElement
|
||||
{
|
||||
public var array:Array;
|
||||
|
||||
public function DaeArray(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get type() : String
|
||||
{
|
||||
return String(data.localName());
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var count:int = 0;
|
||||
this.array = parseStringArray(data);
|
||||
var countXML:XML = data.@count[0];
|
||||
if(countXML != null)
|
||||
{
|
||||
count = int(parseInt(countXML.toString(),10));
|
||||
if(this.array.length < count)
|
||||
{
|
||||
document.logger.logNotEnoughDataError(data.@count[0]);
|
||||
return false;
|
||||
}
|
||||
this.array.length = count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.animation.keys.NumberKey;
|
||||
import alternativa.engine3d.animation.keys.NumberTrack;
|
||||
import alternativa.engine3d.animation.keys.Track;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DaeChannel extends DaeElement
|
||||
{
|
||||
public static const PARAM_UNDEFINED:String = "undefined";
|
||||
|
||||
public static const PARAM_TRANSLATE_X:String = "x";
|
||||
|
||||
public static const PARAM_TRANSLATE_Y:String = "y";
|
||||
|
||||
public static const PARAM_TRANSLATE_Z:String = "z";
|
||||
|
||||
public static const PARAM_SCALE_X:String = "scaleX";
|
||||
|
||||
public static const PARAM_SCALE_Y:String = "scaleY";
|
||||
|
||||
public static const PARAM_SCALE_Z:String = "scaleZ";
|
||||
|
||||
public static const PARAM_ROTATION_X:String = "rotationX";
|
||||
|
||||
public static const PARAM_ROTATION_Y:String = "rotationY";
|
||||
|
||||
public static const PARAM_ROTATION_Z:String = "rotationZ";
|
||||
|
||||
public static const PARAM_TRANSLATE:String = "translate";
|
||||
|
||||
public static const PARAM_SCALE:String = "scale";
|
||||
|
||||
public static const PARAM_MATRIX:String = "matrix";
|
||||
|
||||
public var tracks:Vector.<Track>;
|
||||
|
||||
public var name_dS:String = "undefined";
|
||||
|
||||
public var animName:String;
|
||||
|
||||
public function DaeChannel(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get node() : DaeNode
|
||||
{
|
||||
var targetParts:Array = null;
|
||||
var node:DaeNode = null;
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var sid:String = null;
|
||||
var targetXML:XML = data.@target[0];
|
||||
if(targetXML != null)
|
||||
{
|
||||
targetParts = targetXML.toString().split("/");
|
||||
node = document.findNodeByID(targetParts[0]);
|
||||
if(node != null)
|
||||
{
|
||||
targetParts.pop();
|
||||
for(i = 1,count = int(targetParts.length); i < count; )
|
||||
{
|
||||
sid = targetParts[i];
|
||||
node = node.getNodeBySid(sid);
|
||||
if(node == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
this.parseTransformationType();
|
||||
this.parseSampler();
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseTransformationType() : void
|
||||
{
|
||||
var transformationXML:XML = null;
|
||||
var child:XML = null;
|
||||
var attr:XML = null;
|
||||
var componentName:String = null;
|
||||
var axis:Array = null;
|
||||
var targetXML:XML = data.@target[0];
|
||||
if(targetXML == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var targetParts:Array = targetXML.toString().split("/");
|
||||
var sid:String = targetParts.pop();
|
||||
var sidParts:Array = sid.split(".");
|
||||
var sidPartsCount:int = int(sidParts.length);
|
||||
var node:DaeNode = this.node;
|
||||
if(node == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.animName = node.animName;
|
||||
var children:XMLList = node.data.children();
|
||||
for(var i:int = 0, count:int = int(children.length()); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
attr = child.@sid[0];
|
||||
if(attr != null && attr.toString() == sidParts[0])
|
||||
{
|
||||
transformationXML = child;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
var transformationName:String = transformationXML != null ? transformationXML.localName() as String : null;
|
||||
if(sidPartsCount > 1)
|
||||
{
|
||||
componentName = sidParts[1];
|
||||
loop1:
|
||||
switch(transformationName)
|
||||
{
|
||||
case "translate":
|
||||
switch(componentName)
|
||||
{
|
||||
case "X":
|
||||
this.name_dS = PARAM_TRANSLATE_X;
|
||||
break loop1;
|
||||
case "Y":
|
||||
this.name_dS = PARAM_TRANSLATE_Y;
|
||||
break loop1;
|
||||
case "Z":
|
||||
this.name_dS = PARAM_TRANSLATE_Z;
|
||||
}
|
||||
break;
|
||||
case "rotate":
|
||||
axis = parseNumbersArray(transformationXML);
|
||||
switch(axis.indexOf(1))
|
||||
{
|
||||
case 0:
|
||||
this.name_dS = PARAM_ROTATION_X;
|
||||
break loop1;
|
||||
case 1:
|
||||
this.name_dS = PARAM_ROTATION_Y;
|
||||
break loop1;
|
||||
case 2:
|
||||
this.name_dS = PARAM_ROTATION_Z;
|
||||
}
|
||||
break;
|
||||
case "scale":
|
||||
switch(componentName)
|
||||
{
|
||||
case "X":
|
||||
this.name_dS = PARAM_SCALE_X;
|
||||
break loop1;
|
||||
case "Y":
|
||||
this.name_dS = PARAM_SCALE_Y;
|
||||
break loop1;
|
||||
case "Z":
|
||||
this.name_dS = PARAM_SCALE_Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(transformationName)
|
||||
{
|
||||
case "translate":
|
||||
this.name_dS = PARAM_TRANSLATE;
|
||||
break;
|
||||
case "scale":
|
||||
this.name_dS = PARAM_SCALE;
|
||||
break;
|
||||
case "matrix":
|
||||
this.name_dS = PARAM_MATRIX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parseSampler() : void
|
||||
{
|
||||
var track:NumberTrack = null;
|
||||
var toRad:Number = NaN;
|
||||
var key:NumberKey = null;
|
||||
var sampler:DaeSampler = document.findSampler(data.@source[0]);
|
||||
if(sampler != null)
|
||||
{
|
||||
sampler.parse();
|
||||
if(this.name_dS == PARAM_MATRIX)
|
||||
{
|
||||
this.tracks = Vector.<Track>([sampler.parseTransformationTrack(this.animName)]);
|
||||
return;
|
||||
}
|
||||
if(this.name_dS == PARAM_TRANSLATE)
|
||||
{
|
||||
this.tracks = sampler.parsePointsTracks(this.animName,"x","y","z");
|
||||
return;
|
||||
}
|
||||
if(this.name_dS == PARAM_SCALE)
|
||||
{
|
||||
this.tracks = sampler.parsePointsTracks(this.animName,"scaleX","scaleY","scaleZ");
|
||||
return;
|
||||
}
|
||||
if(this.name_dS == PARAM_ROTATION_X || this.name_dS == PARAM_ROTATION_Y || this.name_dS == PARAM_ROTATION_Z)
|
||||
{
|
||||
track = sampler.parseNumbersTrack(this.animName,this.name_dS);
|
||||
toRad = Math.PI / 180;
|
||||
for(key = track.name_ku; key != null; key = key.alternativa3d::next)
|
||||
{
|
||||
key.name_4O *= toRad;
|
||||
}
|
||||
this.tracks = Vector.<Track>([track]);
|
||||
return;
|
||||
}
|
||||
if(this.name_dS == PARAM_TRANSLATE_X || this.name_dS == PARAM_TRANSLATE_Y || this.name_dS == PARAM_TRANSLATE_Z || this.name_dS == PARAM_SCALE_X || this.name_dS == PARAM_SCALE_Y || this.name_dS == PARAM_SCALE_Z)
|
||||
{
|
||||
this.tracks = Vector.<Track>([sampler.parseNumbersTrack(this.animName,this.name_dS)]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(data.@source[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,634 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.*;
|
||||
import alternativa.engine3d.animation.AnimationClip;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.loaders.ParserMaterial;
|
||||
import alternativa.engine3d.objects.Joint;
|
||||
import alternativa.engine3d.objects.Skin;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace collada;
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DaeController extends DaeElement
|
||||
{
|
||||
private var name_A6:Vector.<Vector.<Number>>;
|
||||
|
||||
private var name_2j:Array;
|
||||
|
||||
private var indices:Array;
|
||||
|
||||
private var name_4h:DaeInput;
|
||||
|
||||
private var name_NK:DaeInput;
|
||||
|
||||
private var name_5O:int;
|
||||
|
||||
private var geometry:Geometry;
|
||||
|
||||
private var primitives:Vector.<DaePrimitive>;
|
||||
|
||||
private var name_1U:int = 0;
|
||||
|
||||
private var name_I:Vector.<Number>;
|
||||
|
||||
public function DaeController(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
private function get daeGeometry() : DaeGeometry
|
||||
{
|
||||
var geom:DaeGeometry = document.findGeometry(data.skin.@source[0]);
|
||||
if(geom == null)
|
||||
{
|
||||
document.logger.logNotFoundError(data.@source[0]);
|
||||
}
|
||||
return geom;
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var i:int = 0;
|
||||
var j:int = 0;
|
||||
var count:int = 0;
|
||||
var vertices:Vector.<DaeVertex> = null;
|
||||
var source:Geometry = null;
|
||||
var localMaxJointsPerVertex:int = 0;
|
||||
var attributes:Array = null;
|
||||
var numSourceAttributes:int = 0;
|
||||
var index:int = 0;
|
||||
var numMappings:int = 0;
|
||||
var sourceData:ByteArray = null;
|
||||
var data:ByteArray = null;
|
||||
var byteArray:ByteArray = null;
|
||||
var attribute:int = 0;
|
||||
var vertexWeightsXML:XML = this.data.skin.vertex_weights[0];
|
||||
if(vertexWeightsXML == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var vcountsXML:XML = vertexWeightsXML.vcount[0];
|
||||
if(vcountsXML == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.name_2j = parseIntsArray(vcountsXML);
|
||||
var indicesXML:XML = vertexWeightsXML.v[0];
|
||||
if(indicesXML == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.indices = parseIntsArray(indicesXML);
|
||||
this.parseInputs();
|
||||
this.parseJointsBindMatrices();
|
||||
for(i = 0; i < this.name_2j.length; )
|
||||
{
|
||||
count = int(this.name_2j[i]);
|
||||
if(this.name_1U < count)
|
||||
{
|
||||
this.name_1U = count;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
var geom:DaeGeometry = this.daeGeometry;
|
||||
this.name_I = this.getBindShapeMatrix();
|
||||
if(geom != null)
|
||||
{
|
||||
geom.parse();
|
||||
vertices = geom.name_FV;
|
||||
source = geom.geometry;
|
||||
localMaxJointsPerVertex = this.name_1U % 2 != 0 ? this.name_1U + 1 : this.name_1U;
|
||||
this.geometry = new Geometry();
|
||||
this.geometry.alternativa3d::_indices = source.alternativa3d::_indices.slice();
|
||||
attributes = source.getVertexStreamAttributes(0);
|
||||
numSourceAttributes = int(attributes.length);
|
||||
index = numSourceAttributes;
|
||||
for(i = 0; i < localMaxJointsPerVertex; i += 2)
|
||||
{
|
||||
attribute = int(VertexAttributes.JOINTS[int(i / 2)]);
|
||||
attributes[int(index++)] = attribute;
|
||||
attributes[int(index++)] = attribute;
|
||||
attributes[int(index++)] = attribute;
|
||||
attributes[int(index++)] = attribute;
|
||||
}
|
||||
numMappings = int(attributes.length);
|
||||
sourceData = source.alternativa3d::_vertexStreams[0].data;
|
||||
data = new ByteArray();
|
||||
data.endian = Endian.LITTLE_ENDIAN;
|
||||
data.length = 4 * numMappings * source.alternativa3d::_numVertices;
|
||||
sourceData.position = 0;
|
||||
for(i = 0; i < source.alternativa3d::_numVertices; i++)
|
||||
{
|
||||
data.position = 4 * numMappings * i;
|
||||
for(j = 0; j < numSourceAttributes; j++)
|
||||
{
|
||||
data.writeFloat(sourceData.readFloat());
|
||||
}
|
||||
}
|
||||
byteArray = this.createVertexBuffer(vertices,localMaxJointsPerVertex);
|
||||
byteArray.position = 0;
|
||||
for(i = 0; i < source.alternativa3d::_numVertices; i++)
|
||||
{
|
||||
data.position = 4 * (numMappings * i + numSourceAttributes);
|
||||
for(j = 0; j < localMaxJointsPerVertex; j++)
|
||||
{
|
||||
data.writeFloat(byteArray.readFloat());
|
||||
data.writeFloat(byteArray.readFloat());
|
||||
}
|
||||
}
|
||||
this.geometry.addVertexStream(attributes);
|
||||
this.geometry.alternativa3d::_vertexStreams[0].data = data;
|
||||
this.geometry.alternativa3d::_numVertices = source.alternativa3d::_numVertices;
|
||||
this.transformVertices(this.geometry);
|
||||
this.primitives = geom.primitives;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function transformVertices(geometry:Geometry) : void
|
||||
{
|
||||
var x:Number = NaN;
|
||||
var y:Number = NaN;
|
||||
var z:Number = NaN;
|
||||
var data:ByteArray = geometry.alternativa3d::_vertexStreams[0].data;
|
||||
var numMappings:int = int(geometry.alternativa3d::_vertexStreams[0].attributes.length);
|
||||
for(var i:int = 0; i < geometry.alternativa3d::_numVertices; i++)
|
||||
{
|
||||
data.position = 4 * numMappings * i;
|
||||
x = Number(data.readFloat());
|
||||
y = Number(data.readFloat());
|
||||
z = Number(data.readFloat());
|
||||
data.position -= 12;
|
||||
data.writeFloat(x * this.name_I[0] + y * this.name_I[1] + z * this.name_I[2] + this.name_I[3]);
|
||||
data.writeFloat(x * this.name_I[4] + y * this.name_I[5] + z * this.name_I[6] + this.name_I[7]);
|
||||
data.writeFloat(x * this.name_I[8] + y * this.name_I[9] + z * this.name_I[10] + this.name_I[11]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createVertexBuffer(vertices:Vector.<DaeVertex>, localMaxJointsPerVertex:int) : ByteArray
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var vertexOutIndices:Vector.<uint> = null;
|
||||
var vertex:DaeVertex = null;
|
||||
var vec:Vector.<uint> = null;
|
||||
var jointsPerVertex:int = 0;
|
||||
var j:int = 0;
|
||||
var k:int = 0;
|
||||
var index:int = 0;
|
||||
var jointIndex:int = 0;
|
||||
var weightIndex:int = 0;
|
||||
var jointsOffset:int = this.name_4h.offset;
|
||||
var weightsOffset:int = this.name_NK.offset;
|
||||
var weightsSource:DaeSource = this.name_NK.prepareSource(1);
|
||||
var weights:Vector.<Number> = weightsSource.numbers;
|
||||
var weightsStride:int = weightsSource.stride;
|
||||
var verticesDict:Dictionary = new Dictionary();
|
||||
var byteArray:ByteArray = new ByteArray();
|
||||
byteArray.length = vertices.length * localMaxJointsPerVertex * 8;
|
||||
byteArray.endian = Endian.LITTLE_ENDIAN;
|
||||
for(i = 0,count = int(vertices.length); i < count; i++)
|
||||
{
|
||||
vertex = vertices[i];
|
||||
if(vertex != null)
|
||||
{
|
||||
vec = verticesDict[vertex.name_Eq];
|
||||
if(vec == null)
|
||||
{
|
||||
vec = verticesDict[vertex.name_Eq] = new Vector.<uint>();
|
||||
}
|
||||
vec.push(vertex.name_AR);
|
||||
}
|
||||
}
|
||||
var vertexIndex:int = 0;
|
||||
for(i = 0,count = int(this.name_2j.length); i < count; i++)
|
||||
{
|
||||
jointsPerVertex = int(this.name_2j[i]);
|
||||
vertexOutIndices = verticesDict[i];
|
||||
for(j = 0; j < vertexOutIndices.length; j++)
|
||||
{
|
||||
byteArray.position = vertexOutIndices[j] * localMaxJointsPerVertex * 8;
|
||||
for(k = 0; k < jointsPerVertex; k++)
|
||||
{
|
||||
index = this.name_5O * (vertexIndex + k);
|
||||
jointIndex = int(this.indices[int(index + jointsOffset)]);
|
||||
if(jointIndex >= 0)
|
||||
{
|
||||
byteArray.writeFloat(jointIndex * 3);
|
||||
weightIndex = int(this.indices[int(index + weightsOffset)]);
|
||||
byteArray.writeFloat(weights[int(weightsStride * weightIndex)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
byteArray.position += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
vertexIndex += jointsPerVertex;
|
||||
}
|
||||
byteArray.position = 0;
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
private function parseInputs() : void
|
||||
{
|
||||
var input:DaeInput = null;
|
||||
var semantic:String = null;
|
||||
var offset:int = 0;
|
||||
var inputsList:XMLList = data.skin.vertex_weights.input;
|
||||
var maxInputOffset:int = 0;
|
||||
for(var i:int = 0, count:int = int(inputsList.length()); i < count; offset = input.offset,maxInputOffset = offset > maxInputOffset ? offset : maxInputOffset,i++)
|
||||
{
|
||||
input = new DaeInput(inputsList[i],document);
|
||||
semantic = input.semantic;
|
||||
if(semantic == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch(semantic)
|
||||
{
|
||||
case "JOINT":
|
||||
if(this.name_4h == null)
|
||||
{
|
||||
this.name_4h = input;
|
||||
}
|
||||
break;
|
||||
case "WEIGHT":
|
||||
if(this.name_NK == null)
|
||||
{
|
||||
this.name_NK = input;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.name_5O = maxInputOffset + 1;
|
||||
}
|
||||
|
||||
private function parseJointsBindMatrices() : void
|
||||
{
|
||||
var jointsXML:XML = null;
|
||||
var jointsSource:DaeSource = null;
|
||||
var stride:int = 0;
|
||||
var count:int = 0;
|
||||
var i:int = 0;
|
||||
var index:int = 0;
|
||||
var matrix:Vector.<Number> = null;
|
||||
var j:int = 0;
|
||||
jointsXML = data.skin.joints.input.(@semantic == "INV_BIND_MATRIX")[0];
|
||||
if(jointsXML != null)
|
||||
{
|
||||
jointsSource = document.findSource(jointsXML.@source[0]);
|
||||
if(jointsSource != null)
|
||||
{
|
||||
if(jointsSource.parse() && jointsSource.numbers != null && jointsSource.stride >= 16)
|
||||
{
|
||||
stride = jointsSource.stride;
|
||||
count = jointsSource.numbers.length / stride;
|
||||
this.name_A6 = new Vector.<Vector.<Number>>(count);
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
index = stride * i;
|
||||
matrix = new Vector.<Number>(16);
|
||||
this.name_A6[i] = matrix;
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
matrix[j] = jointsSource.numbers[int(index + j)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(jointsXML.@source[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function parseSkin(materials:Object, topmostJoints:Vector.<DaeNode>, skeletons:Vector.<DaeNode>) : DaeObject
|
||||
{
|
||||
var numJoints:int = 0;
|
||||
var skin:Skin = null;
|
||||
var joints:Vector.<DaeObject> = null;
|
||||
var i:int = 0;
|
||||
var p:DaePrimitive = null;
|
||||
var instanceMaterial:DaeInstanceMaterial = null;
|
||||
var material:ParserMaterial = null;
|
||||
var daeMaterial:DaeMaterial = null;
|
||||
var skinXML:XML = data.skin[0];
|
||||
if(skinXML != null)
|
||||
{
|
||||
this.name_I = this.getBindShapeMatrix();
|
||||
numJoints = int(this.name_A6.length);
|
||||
skin = new Skin(this.name_1U,numJoints);
|
||||
skin.geometry = this.geometry;
|
||||
joints = this.addJointsToSkin(skin,topmostJoints,this.findNodes(skeletons));
|
||||
this.setJointsBindMatrices(joints);
|
||||
skin.name_WA = this.collectRenderedJoints(joints,numJoints);
|
||||
if(this.primitives != null)
|
||||
{
|
||||
for(i = 0; i < this.primitives.length; i++)
|
||||
{
|
||||
p = this.primitives[i];
|
||||
instanceMaterial = materials[p.materialSymbol];
|
||||
if(instanceMaterial != null)
|
||||
{
|
||||
daeMaterial = instanceMaterial.material;
|
||||
if(daeMaterial != null)
|
||||
{
|
||||
daeMaterial.parse();
|
||||
material = daeMaterial.material;
|
||||
daeMaterial.used = true;
|
||||
}
|
||||
}
|
||||
skin.addSurface(material,p.indexBegin,p.numTriangles);
|
||||
}
|
||||
}
|
||||
return new DaeObject(skin,this.mergeJointsClips(skin,joints));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function collectRenderedJoints(joints:Vector.<DaeObject>, numJoints:int) : Vector.<Joint>
|
||||
{
|
||||
var result:Vector.<Joint> = new Vector.<Joint>();
|
||||
for(var i:int = 0; i < numJoints; i++)
|
||||
{
|
||||
result[i] = Joint(joints[i].object);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private function mergeJointsClips(skin:Skin, joints:Vector.<DaeObject>) : AnimationClip
|
||||
{
|
||||
var animatedObject:DaeObject = null;
|
||||
var clip:AnimationClip = null;
|
||||
var object:Object3D = null;
|
||||
var t:int = 0;
|
||||
if(!this.hasJointsAnimation(joints))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var result:AnimationClip = new AnimationClip();
|
||||
var resultObjects:Array = [skin];
|
||||
for(var i:int = 0, count:int = int(joints.length); i < count; i++)
|
||||
{
|
||||
animatedObject = joints[i];
|
||||
clip = animatedObject.animation;
|
||||
if(clip != null)
|
||||
{
|
||||
for(t = 0; t < clip.numTracks; t++)
|
||||
{
|
||||
result.addTrack(clip.getTrackAt(t));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.addTrack(animatedObject.jointNode.createStaticTransformTrack());
|
||||
}
|
||||
object = animatedObject.object;
|
||||
object.name = animatedObject.jointNode.animName;
|
||||
resultObjects.push(object);
|
||||
}
|
||||
result.name_Kq = resultObjects;
|
||||
return result;
|
||||
}
|
||||
|
||||
private function hasJointsAnimation(joints:Vector.<DaeObject>) : Boolean
|
||||
{
|
||||
var object:DaeObject = null;
|
||||
for(var i:int = 0, count:int = int(joints.length); i < count; )
|
||||
{
|
||||
object = joints[i];
|
||||
if(object.animation != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setJointsBindMatrices(animatedJoints:Vector.<DaeObject>) : void
|
||||
{
|
||||
var animatedJoint:DaeObject = null;
|
||||
var bindMatrix:Vector.<Number> = null;
|
||||
for(var i:int = 0, count:int = int(this.name_A6.length); i < count; i++)
|
||||
{
|
||||
animatedJoint = animatedJoints[i];
|
||||
bindMatrix = this.name_A6[i];
|
||||
Joint(animatedJoint.object).alternativa3d::setBindPoseMatrix(bindMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
private function addJointsToSkin(skin:Skin, topmostJoints:Vector.<DaeNode>, nodes:Vector.<DaeNode>) : Vector.<DaeObject>
|
||||
{
|
||||
var i:int = 0;
|
||||
var topmostJoint:DaeNode = null;
|
||||
var animatedJoint:DaeObject = null;
|
||||
var nodesDictionary:Dictionary = new Dictionary();
|
||||
var count:int = int(nodes.length);
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
nodesDictionary[nodes[i]] = i;
|
||||
}
|
||||
var animatedJoints:Vector.<DaeObject> = new Vector.<DaeObject>(count);
|
||||
var numTopmostJoints:int = int(topmostJoints.length);
|
||||
for(i = 0; i < numTopmostJoints; i++)
|
||||
{
|
||||
topmostJoint = topmostJoints[i];
|
||||
animatedJoint = this.addRootJointToSkin(skin,topmostJoint,animatedJoints,nodesDictionary);
|
||||
this.addJointChildren(Joint(animatedJoint.object),animatedJoints,topmostJoint,nodesDictionary);
|
||||
}
|
||||
return animatedJoints;
|
||||
}
|
||||
|
||||
private function addRootJointToSkin(skin:Skin, node:DaeNode, animatedJoints:Vector.<DaeObject>, nodes:Dictionary) : DaeObject
|
||||
{
|
||||
var joint:Joint = new Joint();
|
||||
joint.name = cloneString(node.name);
|
||||
skin.addChild(joint);
|
||||
var animatedJoint:DaeObject = node.applyAnimation(node.applyTransformations(joint));
|
||||
animatedJoint.jointNode = node;
|
||||
if(node in nodes)
|
||||
{
|
||||
animatedJoints[nodes[node]] = animatedJoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
animatedJoints.push(animatedJoint);
|
||||
}
|
||||
return animatedJoint;
|
||||
}
|
||||
|
||||
private function addJointChildren(parent:Joint, animatedJoints:Vector.<DaeObject>, parentNode:DaeNode, nodes:Dictionary) : void
|
||||
{
|
||||
var object:DaeObject = null;
|
||||
var child:DaeNode = null;
|
||||
var joint:Joint = null;
|
||||
var children:Vector.<DaeNode> = parentNode.nodes;
|
||||
for(var i:int = 0, count:int = int(children.length); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
if(child in nodes)
|
||||
{
|
||||
joint = new Joint();
|
||||
joint.name = cloneString(child.name);
|
||||
object = child.applyAnimation(child.applyTransformations(joint));
|
||||
object.jointNode = child;
|
||||
animatedJoints[nodes[child]] = object;
|
||||
parent.addChild(joint);
|
||||
this.addJointChildren(joint,animatedJoints,child,nodes);
|
||||
}
|
||||
else if(this.hasJointInDescendants(child,nodes))
|
||||
{
|
||||
joint = new Joint();
|
||||
joint.name = cloneString(child.name);
|
||||
object = child.applyAnimation(child.applyTransformations(joint));
|
||||
object.jointNode = child;
|
||||
animatedJoints.push(object);
|
||||
parent.addChild(joint);
|
||||
this.addJointChildren(joint,animatedJoints,child,nodes);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function hasJointInDescendants(parentNode:DaeNode, nodes:Dictionary) : Boolean
|
||||
{
|
||||
var child:DaeNode = null;
|
||||
var children:Vector.<DaeNode> = parentNode.nodes;
|
||||
for(var i:int = 0, count:int = int(children.length); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
if(child in nodes || this.hasJointInDescendants(child,nodes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getBindShapeMatrix() : Vector.<Number>
|
||||
{
|
||||
var matrix:Array = null;
|
||||
var i:int = 0;
|
||||
var matrixXML:XML = data.skin.bind_shape_matrix[0];
|
||||
var res:Vector.<Number> = new Vector.<Number>(16,true);
|
||||
if(matrixXML != null)
|
||||
{
|
||||
matrix = parseStringArray(matrixXML);
|
||||
for(i = 0; i < matrix.length; i++)
|
||||
{
|
||||
res[i] = Number(matrix[i]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private function isRootJointNode(node:DaeNode, nodes:Dictionary) : Boolean
|
||||
{
|
||||
for(var parent:DaeNode = node.parent; parent != null; )
|
||||
{
|
||||
if(parent in nodes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function findRootJointNodes(skeletons:Vector.<DaeNode>) : Vector.<DaeNode>
|
||||
{
|
||||
var nodesDictionary:Dictionary = null;
|
||||
var rootNodes:Vector.<DaeNode> = null;
|
||||
var node:DaeNode = null;
|
||||
var nodes:Vector.<DaeNode> = this.findNodes(skeletons);
|
||||
var i:int = 0;
|
||||
var count:int = int(nodes.length);
|
||||
if(count > 0)
|
||||
{
|
||||
nodesDictionary = new Dictionary();
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
nodesDictionary[nodes[i]] = i;
|
||||
}
|
||||
rootNodes = new Vector.<DaeNode>();
|
||||
for(i = 0; i < count; )
|
||||
{
|
||||
node = nodes[i];
|
||||
if(this.isRootJointNode(node,nodesDictionary))
|
||||
{
|
||||
rootNodes.push(node);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return rootNodes;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function findNode(nodeName:String, skeletons:Vector.<DaeNode>) : DaeNode
|
||||
{
|
||||
var node:DaeNode = null;
|
||||
var count:int = int(skeletons.length);
|
||||
for(var i:int = 0; i < count; )
|
||||
{
|
||||
node = skeletons[i].getNodeBySid(nodeName);
|
||||
if(node != null)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function findNodes(skeletons:Vector.<DaeNode>) : Vector.<DaeNode>
|
||||
{
|
||||
var jointsXML:XML = null;
|
||||
var jointsSource:DaeSource = null;
|
||||
var stride:int = 0;
|
||||
var count:int = 0;
|
||||
var nodes:Vector.<DaeNode> = null;
|
||||
var i:int = 0;
|
||||
var node:DaeNode = null;
|
||||
jointsXML = data.skin.joints.input.(@semantic == "JOINT")[0];
|
||||
if(jointsXML != null)
|
||||
{
|
||||
jointsSource = document.findSource(jointsXML.@source[0]);
|
||||
if(jointsSource != null)
|
||||
{
|
||||
if(jointsSource.parse() && jointsSource.names != null)
|
||||
{
|
||||
stride = jointsSource.stride;
|
||||
count = jointsSource.names.length / stride;
|
||||
nodes = new Vector.<DaeNode>(count);
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
node = this.findNode(jointsSource.names[int(stride * i)],skeletons);
|
||||
if(node == null)
|
||||
{
|
||||
}
|
||||
nodes[i] = node;
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(jointsXML.@source[0]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeDocument
|
||||
{
|
||||
public var scene:DaeVisualScene;
|
||||
|
||||
private var data:XML;
|
||||
|
||||
internal var name_DR:Object;
|
||||
|
||||
internal var arrays:Object;
|
||||
|
||||
internal var vertices:Object;
|
||||
|
||||
public var geometries:Object;
|
||||
|
||||
internal var nodes:Object;
|
||||
|
||||
internal var lights:Object;
|
||||
|
||||
internal var images:Object;
|
||||
|
||||
internal var effects:Object;
|
||||
|
||||
internal var name_DW:Object;
|
||||
|
||||
internal var name_GB:Object;
|
||||
|
||||
public var materials:Object;
|
||||
|
||||
internal var logger:DaeLogger;
|
||||
|
||||
public var versionMajor:uint;
|
||||
|
||||
public var versionMinor:uint;
|
||||
|
||||
public var unitScaleFactor:Number = 1;
|
||||
|
||||
public function DaeDocument(document:XML, units:Number)
|
||||
{
|
||||
super();
|
||||
this.data = document;
|
||||
var versionComponents:Array = this.data.@version[0].toString().split(/[.,]/);
|
||||
this.versionMajor = parseInt(versionComponents[1],10);
|
||||
this.versionMinor = parseInt(versionComponents[2],10);
|
||||
var colladaUnit:Number = Number(parseFloat(this.data.asset[0].unit[0].@meter));
|
||||
if(units > 0)
|
||||
{
|
||||
this.unitScaleFactor = colladaUnit / units;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.unitScaleFactor = 1;
|
||||
}
|
||||
this.logger = new DaeLogger();
|
||||
this.constructStructures();
|
||||
this.constructScenes();
|
||||
this.registerInstanceControllers();
|
||||
this.constructAnimations();
|
||||
}
|
||||
|
||||
private function getLocalID(url:XML) : String
|
||||
{
|
||||
var path:String = url.toString();
|
||||
if(path.charAt(0) == "#")
|
||||
{
|
||||
return path.substr(1);
|
||||
}
|
||||
this.logger.logExternalError(url);
|
||||
return null;
|
||||
}
|
||||
|
||||
private function constructStructures() : void
|
||||
{
|
||||
var element:XML = null;
|
||||
var source:DaeSource = null;
|
||||
var light:DaeLight = null;
|
||||
var image:DaeImage = null;
|
||||
var effect:DaeEffect = null;
|
||||
var material:DaeMaterial = null;
|
||||
var geom:DaeGeometry = null;
|
||||
var controller:DaeController = null;
|
||||
var node:DaeNode = null;
|
||||
this.name_DR = new Object();
|
||||
this.arrays = new Object();
|
||||
for each(element in this.data..source)
|
||||
{
|
||||
source = new DaeSource(element,this);
|
||||
if(source.id != null)
|
||||
{
|
||||
this.name_DR[source.id] = source;
|
||||
}
|
||||
}
|
||||
this.lights = new Object();
|
||||
for each(element in this.data.library_lights.light)
|
||||
{
|
||||
light = new DaeLight(element,this);
|
||||
if(light.id != null)
|
||||
{
|
||||
this.lights[light.id] = light;
|
||||
}
|
||||
}
|
||||
this.images = new Object();
|
||||
for each(element in this.data.library_images.image)
|
||||
{
|
||||
image = new DaeImage(element,this);
|
||||
if(image.id != null)
|
||||
{
|
||||
this.images[image.id] = image;
|
||||
}
|
||||
}
|
||||
this.effects = new Object();
|
||||
for each(element in this.data.library_effects.effect)
|
||||
{
|
||||
effect = new DaeEffect(element,this);
|
||||
if(effect.id != null)
|
||||
{
|
||||
this.effects[effect.id] = effect;
|
||||
}
|
||||
}
|
||||
this.materials = new Object();
|
||||
for each(element in this.data.library_materials.material)
|
||||
{
|
||||
material = new DaeMaterial(element,this);
|
||||
if(material.id != null)
|
||||
{
|
||||
this.materials[material.id] = material;
|
||||
}
|
||||
}
|
||||
this.geometries = new Object();
|
||||
this.vertices = new Object();
|
||||
for each(element in this.data.library_geometries.geometry)
|
||||
{
|
||||
geom = new DaeGeometry(element,this);
|
||||
if(geom.id != null)
|
||||
{
|
||||
this.geometries[geom.id] = geom;
|
||||
}
|
||||
}
|
||||
this.name_DW = new Object();
|
||||
for each(element in this.data.library_controllers.controller)
|
||||
{
|
||||
controller = new DaeController(element,this);
|
||||
if(controller.id != null)
|
||||
{
|
||||
this.name_DW[controller.id] = controller;
|
||||
}
|
||||
}
|
||||
this.nodes = new Object();
|
||||
for each(element in this.data.library_nodes.node)
|
||||
{
|
||||
node = new DaeNode(element,this);
|
||||
if(node.id != null)
|
||||
{
|
||||
this.nodes[node.id] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function constructScenes() : void
|
||||
{
|
||||
var element:XML = null;
|
||||
var vscene:DaeVisualScene = null;
|
||||
var vsceneURL:XML = this.data.scene.instance_visual_scene.@url[0];
|
||||
var vsceneID:String = this.getLocalID(vsceneURL);
|
||||
for each(element in this.data.library_visual_scenes.visual_scene)
|
||||
{
|
||||
vscene = new DaeVisualScene(element,this);
|
||||
if(vscene.id == vsceneID)
|
||||
{
|
||||
this.scene = vscene;
|
||||
}
|
||||
}
|
||||
if(vsceneID != null && this.scene == null)
|
||||
{
|
||||
this.logger.logNotFoundError(vsceneURL);
|
||||
}
|
||||
}
|
||||
|
||||
private function registerInstanceControllers() : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
if(this.scene != null)
|
||||
{
|
||||
for(i = 0,count = int(this.scene.nodes.length); i < count; i++)
|
||||
{
|
||||
this.scene.nodes[i].registerInstanceControllers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function constructAnimations() : void
|
||||
{
|
||||
var element:XML = null;
|
||||
var sampler:DaeSampler = null;
|
||||
var channel:DaeChannel = null;
|
||||
var node:DaeNode = null;
|
||||
this.name_GB = new Object();
|
||||
for each(element in this.data.library_animations..sampler)
|
||||
{
|
||||
sampler = new DaeSampler(element,this);
|
||||
if(sampler.id != null)
|
||||
{
|
||||
this.name_GB[sampler.id] = sampler;
|
||||
}
|
||||
}
|
||||
for each(element in this.data.library_animations..channel)
|
||||
{
|
||||
channel = new DaeChannel(element,this);
|
||||
node = channel.node;
|
||||
if(node != null)
|
||||
{
|
||||
node.addChannel(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function findArray(url:XML) : DaeArray
|
||||
{
|
||||
return this.arrays[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findSource(url:XML) : DaeSource
|
||||
{
|
||||
return this.name_DR[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findLight(url:XML) : DaeLight
|
||||
{
|
||||
return this.lights[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findImage(url:XML) : DaeImage
|
||||
{
|
||||
return this.images[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findImageByID(id:String) : DaeImage
|
||||
{
|
||||
return this.images[id];
|
||||
}
|
||||
|
||||
public function findEffect(url:XML) : DaeEffect
|
||||
{
|
||||
return this.effects[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findMaterial(url:XML) : DaeMaterial
|
||||
{
|
||||
return this.materials[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findVertices(url:XML) : DaeVertices
|
||||
{
|
||||
return this.vertices[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findGeometry(url:XML) : DaeGeometry
|
||||
{
|
||||
return this.geometries[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findNode(url:XML) : DaeNode
|
||||
{
|
||||
return this.nodes[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findNodeByID(id:String) : DaeNode
|
||||
{
|
||||
return this.nodes[id];
|
||||
}
|
||||
|
||||
public function findController(url:XML) : DaeController
|
||||
{
|
||||
return this.name_DW[this.getLocalID(url)];
|
||||
}
|
||||
|
||||
public function findSampler(url:XML) : DaeSampler
|
||||
{
|
||||
return this.name_GB[this.getLocalID(url)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.loaders.ParserMaterial;
|
||||
import alternativa.engine3d.resources.ExternalTextureResource;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeEffect extends DaeElement
|
||||
{
|
||||
public static var commonAlways:Boolean = false;
|
||||
|
||||
private var name_3x:Object;
|
||||
|
||||
private var name_El:Object;
|
||||
|
||||
private var name_3H:Object;
|
||||
|
||||
private var diffuse:DaeEffectParam;
|
||||
|
||||
private var ambient:DaeEffectParam;
|
||||
|
||||
private var transparent:DaeEffectParam;
|
||||
|
||||
private var transparency:DaeEffectParam;
|
||||
|
||||
private var bump:DaeEffectParam;
|
||||
|
||||
private var reflective:DaeEffectParam;
|
||||
|
||||
private var emission:DaeEffectParam;
|
||||
|
||||
private var specular:DaeEffectParam;
|
||||
|
||||
public function DaeEffect(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
this.constructImages();
|
||||
}
|
||||
|
||||
private function constructImages() : void
|
||||
{
|
||||
var element:XML = null;
|
||||
var image:DaeImage = null;
|
||||
var list:XMLList = data..image;
|
||||
for each(element in list)
|
||||
{
|
||||
image = new DaeImage(element,document);
|
||||
if(image.id != null)
|
||||
{
|
||||
document.images[image.id] = image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var shader:XML;
|
||||
var element:XML = null;
|
||||
var param:DaeParam = null;
|
||||
var technique:XML = null;
|
||||
var bumpXML:XML = null;
|
||||
var diffuseXML:XML = null;
|
||||
var transparentXML:XML = null;
|
||||
var transparencyXML:XML = null;
|
||||
var ambientXML:XML = null;
|
||||
var reflectiveXML:XML = null;
|
||||
var emissionXML:XML = null;
|
||||
var specularXML:XML = null;
|
||||
this.name_3x = new Object();
|
||||
for each(element in data.newparam)
|
||||
{
|
||||
param = new DaeParam(element,document);
|
||||
this.name_3x[param.sid] = param;
|
||||
}
|
||||
this.name_El = new Object();
|
||||
for each(element in data.profile_COMMON.newparam)
|
||||
{
|
||||
param = new DaeParam(element,document);
|
||||
this.name_El[param.sid] = param;
|
||||
}
|
||||
this.name_3H = new Object();
|
||||
technique = data.profile_COMMON.technique[0];
|
||||
if(technique != null)
|
||||
{
|
||||
for each(element in technique.newparam)
|
||||
{
|
||||
param = new DaeParam(element,document);
|
||||
this.name_3H[param.sid] = param;
|
||||
}
|
||||
}
|
||||
shader = data.profile_COMMON.technique.*.(localName() == "constant" || localName() == "lambert" || localName() == "phong" || localName() == "blinn")[0];
|
||||
if(shader != null)
|
||||
{
|
||||
diffuseXML = null;
|
||||
if(shader.localName() == "constant")
|
||||
{
|
||||
diffuseXML = shader.emission[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuseXML = shader.diffuse[0];
|
||||
emissionXML = shader.emission[0];
|
||||
if(emissionXML != null)
|
||||
{
|
||||
this.emission = new DaeEffectParam(emissionXML,this);
|
||||
}
|
||||
}
|
||||
if(diffuseXML != null)
|
||||
{
|
||||
this.diffuse = new DaeEffectParam(diffuseXML,this);
|
||||
}
|
||||
if(shader.localName() == "phong" || shader.localName() == "blinn")
|
||||
{
|
||||
specularXML = shader.specular[0];
|
||||
if(specularXML != null)
|
||||
{
|
||||
this.specular = new DaeEffectParam(specularXML,this);
|
||||
}
|
||||
}
|
||||
transparentXML = shader.transparent[0];
|
||||
if(transparentXML != null)
|
||||
{
|
||||
this.transparent = new DaeEffectParam(transparentXML,this);
|
||||
}
|
||||
transparencyXML = shader.transparency[0];
|
||||
if(transparencyXML != null)
|
||||
{
|
||||
this.transparency = new DaeEffectParam(transparencyXML,this);
|
||||
}
|
||||
ambientXML = shader.ambient[0];
|
||||
if(ambientXML != null)
|
||||
{
|
||||
this.ambient = new DaeEffectParam(ambientXML,this);
|
||||
}
|
||||
reflectiveXML = shader.reflective[0];
|
||||
if(reflectiveXML != null)
|
||||
{
|
||||
this.reflective = new DaeEffectParam(reflectiveXML,this);
|
||||
}
|
||||
}
|
||||
bumpXML = data.profile_COMMON.technique.extra.technique.(Boolean(hasOwnProperty("@profile")) && @profile == "OpenCOLLADA3dsMax").bump[0];
|
||||
if(bumpXML != null)
|
||||
{
|
||||
this.bump = new DaeEffectParam(bumpXML,this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal function getParam(name:String, setparams:Object) : DaeParam
|
||||
{
|
||||
var param:DaeParam = setparams[name];
|
||||
if(param != null)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
param = this.name_3H[name];
|
||||
if(param != null)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
param = this.name_El[name];
|
||||
if(param != null)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
return this.name_3x[name];
|
||||
}
|
||||
|
||||
private function float4ToUint(value:Array, alpha:Boolean = true) : uint
|
||||
{
|
||||
var a:uint = 0;
|
||||
var r:uint = value[0] * 255;
|
||||
var g:uint = value[1] * 255;
|
||||
var b:uint = value[2] * 255;
|
||||
if(alpha)
|
||||
{
|
||||
a = value[3] * 255;
|
||||
return a << 24 | r << 16 | g << 8 | b;
|
||||
}
|
||||
return r << 16 | g << 8 | b;
|
||||
}
|
||||
|
||||
public function getMaterial(setparams:Object) : ParserMaterial
|
||||
{
|
||||
var material:ParserMaterial = null;
|
||||
if(this.diffuse != null)
|
||||
{
|
||||
material = new ParserMaterial();
|
||||
if(Boolean(this.diffuse))
|
||||
{
|
||||
this.pushMap(material,this.diffuse,setparams);
|
||||
}
|
||||
if(this.specular != null)
|
||||
{
|
||||
this.pushMap(material,this.specular,setparams);
|
||||
}
|
||||
if(this.emission != null)
|
||||
{
|
||||
this.pushMap(material,this.emission,setparams);
|
||||
}
|
||||
if(this.transparency != null)
|
||||
{
|
||||
material.transparency = this.transparency.getFloat(setparams);
|
||||
}
|
||||
if(this.transparent != null)
|
||||
{
|
||||
this.pushMap(material,this.transparent,setparams);
|
||||
}
|
||||
if(this.bump != null)
|
||||
{
|
||||
this.pushMap(material,this.bump,setparams);
|
||||
}
|
||||
if(Boolean(this.ambient))
|
||||
{
|
||||
this.pushMap(material,this.ambient,setparams);
|
||||
}
|
||||
if(Boolean(this.reflective))
|
||||
{
|
||||
this.pushMap(material,this.reflective,setparams);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function pushMap(material:ParserMaterial, param:DaeEffectParam, setparams:Object) : void
|
||||
{
|
||||
var _loc5_:DaeImage = null;
|
||||
var color:Array = param.getColor(setparams);
|
||||
if(color != null)
|
||||
{
|
||||
material.colors[cloneString(param.data.localName())] = this.float4ToUint(color,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc5_ = param.getImage(setparams);
|
||||
if(_loc5_ != null)
|
||||
{
|
||||
material.textures[cloneString(param.data.localName())] = new ExternalTextureResource(cloneString(_loc5_.init_from));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get mainTexCoords() : String
|
||||
{
|
||||
var channel:String = null;
|
||||
channel = channel == null && this.diffuse != null ? this.diffuse.texCoord : channel;
|
||||
channel = channel == null && this.transparent != null ? this.transparent.texCoord : channel;
|
||||
channel = channel == null && this.bump != null ? this.bump.texCoord : channel;
|
||||
channel = channel == null && this.emission != null ? this.emission.texCoord : channel;
|
||||
return channel == null && this.specular != null ? this.specular.texCoord : channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeEffectParam extends DaeElement
|
||||
{
|
||||
private var effect:DaeEffect;
|
||||
|
||||
public function DaeEffectParam(data:XML, effect:DaeEffect)
|
||||
{
|
||||
super(data,effect.document);
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
public function getFloat(setparams:Object) : Number
|
||||
{
|
||||
var param:DaeParam = null;
|
||||
var floatXML:XML = data.float[0];
|
||||
if(floatXML != null)
|
||||
{
|
||||
return parseNumber(floatXML);
|
||||
}
|
||||
var paramRef:XML = data.param.@ref[0];
|
||||
if(paramRef != null)
|
||||
{
|
||||
param = this.effect.getParam(paramRef.toString(),setparams);
|
||||
if(param != null)
|
||||
{
|
||||
return param.getFloat();
|
||||
}
|
||||
}
|
||||
return NaN;
|
||||
}
|
||||
|
||||
public function getColor(setparams:Object) : Array
|
||||
{
|
||||
var param:DaeParam = null;
|
||||
var colorXML:XML = data.color[0];
|
||||
if(colorXML != null)
|
||||
{
|
||||
return parseNumbersArray(colorXML);
|
||||
}
|
||||
var paramRef:XML = data.param.@ref[0];
|
||||
if(paramRef != null)
|
||||
{
|
||||
param = this.effect.getParam(paramRef.toString(),setparams);
|
||||
if(param != null)
|
||||
{
|
||||
return param.getFloat4();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function get texture() : String
|
||||
{
|
||||
var attr:XML = data.texture.@texture[0];
|
||||
return attr == null ? null : attr.toString();
|
||||
}
|
||||
|
||||
public function getSampler(setparams:Object) : DaeParam
|
||||
{
|
||||
var sid:String = this.texture;
|
||||
if(sid != null)
|
||||
{
|
||||
return this.effect.getParam(sid,setparams);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getImage(setparams:Object) : DaeImage
|
||||
{
|
||||
var surfaceSID:String = null;
|
||||
var surface:DaeParam = null;
|
||||
var sampler:DaeParam = this.getSampler(setparams);
|
||||
if(sampler != null)
|
||||
{
|
||||
surfaceSID = sampler.surfaceSID;
|
||||
if(surfaceSID != null)
|
||||
{
|
||||
surface = this.effect.getParam(surfaceSID,setparams);
|
||||
if(surface != null)
|
||||
{
|
||||
return surface.image;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return sampler.image;
|
||||
}
|
||||
return document.findImageByID(this.texture);
|
||||
}
|
||||
|
||||
public function get texCoord() : String
|
||||
{
|
||||
var attr:XML = data.texture.@texcoord[0];
|
||||
return attr == null ? null : attr.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeElement
|
||||
{
|
||||
private static var _byteArray:ByteArray = new ByteArray();
|
||||
|
||||
public var document:DaeDocument;
|
||||
|
||||
public var data:XML;
|
||||
|
||||
private var name_Ba:int = -1;
|
||||
|
||||
public function DaeElement(data:XML, document:DaeDocument)
|
||||
{
|
||||
super();
|
||||
this.document = document;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public function cloneString(str:String) : String
|
||||
{
|
||||
if(str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
_byteArray.position = 0;
|
||||
_byteArray.writeUTF(str);
|
||||
_byteArray.position = 0;
|
||||
return _byteArray.readUTF();
|
||||
}
|
||||
|
||||
public function parse() : Boolean
|
||||
{
|
||||
if(this.name_Ba < 0)
|
||||
{
|
||||
this.name_Ba = this.parseImplementation() ? 1 : 0;
|
||||
return this.name_Ba != 0;
|
||||
}
|
||||
return this.name_Ba != 0;
|
||||
}
|
||||
|
||||
protected function parseImplementation() : Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function parseStringArray(element:XML) : Array
|
||||
{
|
||||
return element.text().toString().split(/\s+/);
|
||||
}
|
||||
|
||||
protected function parseNumbersArray(element:XML) : Array
|
||||
{
|
||||
var value:String = null;
|
||||
var arr:Array = element.text().toString().split(/\s+/);
|
||||
for(var i:int = 0, count:int = int(arr.length); i < count; i++)
|
||||
{
|
||||
value = arr[i];
|
||||
if(value.indexOf(",") != -1)
|
||||
{
|
||||
value = value.replace(/,/,".");
|
||||
}
|
||||
arr[i] = parseFloat(value);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
protected function parseIntsArray(element:XML) : Array
|
||||
{
|
||||
var value:String = null;
|
||||
var arr:Array = element.text().toString().split(/\s+/);
|
||||
for(var i:int = 0, count:int = int(arr.length); i < count; i++)
|
||||
{
|
||||
value = arr[i];
|
||||
arr[i] = parseInt(value,10);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
protected function parseNumber(element:XML) : Number
|
||||
{
|
||||
var value:String = element.toString().replace(/,/,".");
|
||||
return parseFloat(value);
|
||||
}
|
||||
|
||||
public function get id() : String
|
||||
{
|
||||
var idXML:XML = this.data.@id[0];
|
||||
return idXML == null ? null : idXML.toString();
|
||||
}
|
||||
|
||||
public function get sid() : String
|
||||
{
|
||||
var attr:XML = this.data.@sid[0];
|
||||
return attr == null ? null : attr.toString();
|
||||
}
|
||||
|
||||
public function get name() : String
|
||||
{
|
||||
var nameXML:XML = this.data.@name[0];
|
||||
return nameXML == null ? null : nameXML.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.loaders.ParserMaterial;
|
||||
import alternativa.engine3d.objects.Mesh;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace collada;
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DaeGeometry extends DaeElement
|
||||
{
|
||||
internal var name_FV:Vector.<DaeVertex>;
|
||||
|
||||
internal var primitives:Vector.<DaePrimitive>;
|
||||
|
||||
internal var geometry:Geometry;
|
||||
|
||||
private var vertices:DaeVertices;
|
||||
|
||||
public function DaeGeometry(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
this.constructVertices();
|
||||
}
|
||||
|
||||
private function constructVertices() : void
|
||||
{
|
||||
var verticesXML:XML = data.mesh.vertices[0];
|
||||
if(verticesXML != null)
|
||||
{
|
||||
this.vertices = new DaeVertices(verticesXML,document);
|
||||
document.vertices[this.vertices.id] = this.vertices;
|
||||
}
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var numVertices:int = 0;
|
||||
var i:int = 0;
|
||||
var p:DaePrimitive = null;
|
||||
var channels:uint = 0;
|
||||
var attributes:Array = null;
|
||||
var index:int = 0;
|
||||
var data:ByteArray = null;
|
||||
var numMappings:int = 0;
|
||||
var vertex:DaeVertex = null;
|
||||
var j:int = 0;
|
||||
if(this.vertices != null)
|
||||
{
|
||||
this.parsePrimitives();
|
||||
this.vertices.parse();
|
||||
numVertices = this.vertices.name_E6.numbers.length / this.vertices.name_E6.stride;
|
||||
this.geometry = new Geometry();
|
||||
this.name_FV = new Vector.<DaeVertex>(numVertices);
|
||||
channels = 0;
|
||||
for(i = 0; i < this.primitives.length; )
|
||||
{
|
||||
p = this.primitives[i];
|
||||
p.parse();
|
||||
if(p.verticesEquals(this.vertices))
|
||||
{
|
||||
numVertices = int(this.name_FV.length);
|
||||
channels |= p.fillGeometry(this.geometry,this.name_FV);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
attributes = new Array(3);
|
||||
attributes[0] = VertexAttributes.POSITION;
|
||||
attributes[1] = VertexAttributes.POSITION;
|
||||
attributes[2] = VertexAttributes.POSITION;
|
||||
index = 3;
|
||||
if(Boolean(channels & DaePrimitive.NORMALS))
|
||||
{
|
||||
var _loc11_:* = index++;
|
||||
attributes[_loc11_] = VertexAttributes.NORMAL;
|
||||
var _loc12_:* = index++;
|
||||
attributes[_loc12_] = VertexAttributes.NORMAL;
|
||||
var _loc13_:* = index++;
|
||||
attributes[_loc13_] = VertexAttributes.NORMAL;
|
||||
}
|
||||
if(Boolean(channels & DaePrimitive.TANGENT4))
|
||||
{
|
||||
_loc11_ = index++;
|
||||
attributes[_loc11_] = VertexAttributes.TANGENT4;
|
||||
_loc12_ = index++;
|
||||
attributes[_loc12_] = VertexAttributes.TANGENT4;
|
||||
_loc13_ = index++;
|
||||
attributes[_loc13_] = VertexAttributes.TANGENT4;
|
||||
var _loc14_:* = index++;
|
||||
attributes[_loc14_] = VertexAttributes.TANGENT4;
|
||||
}
|
||||
for(i = 0; i < 8; )
|
||||
{
|
||||
if(Boolean(channels & DaePrimitive.TEXCOORDS[i]))
|
||||
{
|
||||
_loc11_ = index++;
|
||||
attributes[_loc11_] = VertexAttributes.TEXCOORDS[i];
|
||||
_loc12_ = index++;
|
||||
attributes[_loc12_] = VertexAttributes.TEXCOORDS[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this.geometry.addVertexStream(attributes);
|
||||
numVertices = int(this.name_FV.length);
|
||||
data = new ByteArray();
|
||||
data.endian = Endian.LITTLE_ENDIAN;
|
||||
numMappings = int(attributes.length);
|
||||
data.length = 4 * numMappings * numVertices;
|
||||
for(i = 0; i < numVertices; )
|
||||
{
|
||||
vertex = this.name_FV[i];
|
||||
if(vertex != null)
|
||||
{
|
||||
data.position = 4 * numMappings * i;
|
||||
data.writeFloat(vertex.x);
|
||||
data.writeFloat(vertex.y);
|
||||
data.writeFloat(vertex.z);
|
||||
if(vertex.normal != null)
|
||||
{
|
||||
data.writeFloat(vertex.normal.x);
|
||||
data.writeFloat(vertex.normal.y);
|
||||
data.writeFloat(vertex.normal.z);
|
||||
}
|
||||
if(vertex.name_hC != null)
|
||||
{
|
||||
data.writeFloat(vertex.name_hC.x);
|
||||
data.writeFloat(vertex.name_hC.y);
|
||||
data.writeFloat(vertex.name_hC.z);
|
||||
data.writeFloat(vertex.name_hC.w);
|
||||
}
|
||||
for(j = 0; j < vertex.uvs.length; )
|
||||
{
|
||||
data.writeFloat(vertex.uvs[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
this.geometry.alternativa3d::_vertexStreams[0].data = data;
|
||||
this.geometry.alternativa3d::_numVertices = numVertices;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function parsePrimitives() : void
|
||||
{
|
||||
var child:XML = null;
|
||||
var _loc5_:DaePrimitive = null;
|
||||
this.primitives = new Vector.<DaePrimitive>();
|
||||
var children:XMLList = data.mesh.children();
|
||||
for(var i:int = 0, count:int = int(children.length()); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
switch(child.localName())
|
||||
{
|
||||
case "polygons":
|
||||
case "polylist":
|
||||
case "triangles":
|
||||
case "trifans":
|
||||
case "tristrips":
|
||||
_loc5_ = new DaePrimitive(child,document);
|
||||
this.primitives.push(_loc5_);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public function parseMesh(materials:Object) : Mesh
|
||||
{
|
||||
var mesh:Mesh = null;
|
||||
var i:int = 0;
|
||||
var p:DaePrimitive = null;
|
||||
var instanceMaterial:DaeInstanceMaterial = null;
|
||||
var material:ParserMaterial = null;
|
||||
var daeMaterial:DaeMaterial = null;
|
||||
if(data.mesh.length() > 0)
|
||||
{
|
||||
mesh = new Mesh();
|
||||
mesh.geometry = this.geometry;
|
||||
for(i = 0; i < this.primitives.length; i++)
|
||||
{
|
||||
p = this.primitives[i];
|
||||
instanceMaterial = materials[p.materialSymbol];
|
||||
if(instanceMaterial != null)
|
||||
{
|
||||
daeMaterial = instanceMaterial.material;
|
||||
if(daeMaterial != null)
|
||||
{
|
||||
daeMaterial.parse();
|
||||
material = daeMaterial.material;
|
||||
daeMaterial.used = true;
|
||||
}
|
||||
}
|
||||
mesh.addSurface(material,p.indexBegin,p.numTriangles);
|
||||
}
|
||||
mesh.calculateBoundBox();
|
||||
return mesh;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeImage extends DaeElement
|
||||
{
|
||||
public function DaeImage(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get init_from() : String
|
||||
{
|
||||
var refXML:XML = null;
|
||||
var element:XML = data.init_from[0];
|
||||
if(element != null)
|
||||
{
|
||||
if(document.versionMajor > 4)
|
||||
{
|
||||
refXML = element.ref[0];
|
||||
return refXML == null ? null : refXML.text().toString();
|
||||
}
|
||||
return element.text().toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeInput extends DaeElement
|
||||
{
|
||||
public function DaeInput(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get semantic() : String
|
||||
{
|
||||
var attribute:XML = data.@semantic[0];
|
||||
return attribute == null ? null : attribute.toString();
|
||||
}
|
||||
|
||||
public function get source() : XML
|
||||
{
|
||||
return data.@source[0];
|
||||
}
|
||||
|
||||
public function get offset() : int
|
||||
{
|
||||
var attr:XML = data.@offset[0];
|
||||
return attr == null ? 0 : int(parseInt(attr.toString(),10));
|
||||
}
|
||||
|
||||
public function get setNum() : int
|
||||
{
|
||||
var attr:XML = data.@set[0];
|
||||
return attr == null ? 0 : int(parseInt(attr.toString(),10));
|
||||
}
|
||||
|
||||
public function prepareSource(minComponents:int) : DaeSource
|
||||
{
|
||||
var source:DaeSource = document.findSource(this.source);
|
||||
if(source != null)
|
||||
{
|
||||
source.parse();
|
||||
if(source.numbers != null && source.stride >= minComponents)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(data.@source[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeInstanceController extends DaeElement
|
||||
{
|
||||
public var node:DaeNode;
|
||||
|
||||
public var topmostJoints:Vector.<DaeNode>;
|
||||
|
||||
public function DaeInstanceController(data:XML, document:DaeDocument, node:DaeNode)
|
||||
{
|
||||
super(data,document);
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var controller:DaeController = this.controller;
|
||||
if(controller != null)
|
||||
{
|
||||
this.topmostJoints = controller.findRootJointNodes(this.skeletons);
|
||||
if(this.topmostJoints != null && this.topmostJoints.length > 1)
|
||||
{
|
||||
this.replaceNodesByTopmost(this.topmostJoints);
|
||||
}
|
||||
}
|
||||
return this.topmostJoints != null;
|
||||
}
|
||||
|
||||
private function replaceNodesByTopmost(nodes:Vector.<DaeNode>) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var node:DaeNode = null;
|
||||
var parent:DaeNode = null;
|
||||
var numNodes:int = int(nodes.length);
|
||||
var parents:Dictionary = new Dictionary();
|
||||
for(i = 0; i < numNodes; i++)
|
||||
{
|
||||
node = nodes[i];
|
||||
for(parent = node.parent; parent != null; parent = parent.parent)
|
||||
{
|
||||
if(Boolean(parents[parent]))
|
||||
{
|
||||
parents[parent]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
parents[parent] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i = 0; i < numNodes; i++)
|
||||
{
|
||||
node = nodes[i];
|
||||
while(true)
|
||||
{
|
||||
parent = node.parent;
|
||||
if(!(parent != null && parents[parent] != numNodes))
|
||||
{
|
||||
break;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
nodes[i] = node;
|
||||
}
|
||||
}
|
||||
|
||||
private function get controller() : DaeController
|
||||
{
|
||||
var controller:DaeController = document.findController(data.@url[0]);
|
||||
if(controller == null)
|
||||
{
|
||||
document.logger.logNotFoundError(data.@url[0]);
|
||||
}
|
||||
return controller;
|
||||
}
|
||||
|
||||
private function get skeletons() : Vector.<DaeNode>
|
||||
{
|
||||
var skeletons:Vector.<DaeNode> = null;
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var skeletonXML:XML = null;
|
||||
var skel:DaeNode = null;
|
||||
var list:XMLList = data.skeleton;
|
||||
if(list.length() > 0)
|
||||
{
|
||||
skeletons = new Vector.<DaeNode>();
|
||||
for(i = 0,count = int(list.length()); i < count; i++)
|
||||
{
|
||||
skeletonXML = list[i];
|
||||
skel = document.findNode(skeletonXML.text()[0]);
|
||||
if(skel != null)
|
||||
{
|
||||
skeletons.push(skel);
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(skeletonXML);
|
||||
}
|
||||
}
|
||||
return skeletons;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function parseSkin(materials:Object) : DaeObject
|
||||
{
|
||||
var controller:DaeController = this.controller;
|
||||
if(controller != null)
|
||||
{
|
||||
controller.parse();
|
||||
return controller.parseSkin(materials,this.topmostJoints,this.skeletons);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeInstanceMaterial extends DaeElement
|
||||
{
|
||||
public function DaeInstanceMaterial(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get symbol() : String
|
||||
{
|
||||
var attribute:XML = data.@symbol[0];
|
||||
return attribute == null ? null : attribute.toString();
|
||||
}
|
||||
|
||||
private function get target() : XML
|
||||
{
|
||||
return data.@target[0];
|
||||
}
|
||||
|
||||
public function get material() : DaeMaterial
|
||||
{
|
||||
var mat:DaeMaterial = document.findMaterial(this.target);
|
||||
if(mat == null)
|
||||
{
|
||||
document.logger.logNotFoundError(this.target);
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
public function getBindVertexInputSetNum(semantic:String) : int
|
||||
{
|
||||
var bindVertexInputXML:XML = null;
|
||||
var setNumXML:XML = null;
|
||||
bindVertexInputXML = data.bind_vertex_input.(@semantic == semantic)[0];
|
||||
if(bindVertexInputXML == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
setNumXML = bindVertexInputXML.@input_set[0];
|
||||
return setNumXML == null ? 0 : int(parseInt(setNumXML.toString(),10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.lights.AmbientLight;
|
||||
import alternativa.engine3d.lights.DirectionalLight;
|
||||
import alternativa.engine3d.lights.OmniLight;
|
||||
import alternativa.engine3d.lights.SpotLight;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeLight extends DaeElement
|
||||
{
|
||||
public function DaeLight(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
private function float4ToUint(value:Array) : uint
|
||||
{
|
||||
var r:uint = value[0] * 255;
|
||||
var g:uint = value[1] * 255;
|
||||
var b:uint = value[2] * 255;
|
||||
return r << 16 | g << 8 | b | 4278190080;
|
||||
}
|
||||
|
||||
public function get revertDirection() : Boolean
|
||||
{
|
||||
var info:XML = data.technique_common.children()[0];
|
||||
return info == null ? false : info.localName() == "directional" || info.localName() == "spot";
|
||||
}
|
||||
|
||||
public function parseLight() : Light3D
|
||||
{
|
||||
var info:XML = null;
|
||||
var extra:XML = null;
|
||||
var light:Light3D = null;
|
||||
var color:uint = 0;
|
||||
var constantAttenuationXML:XML = null;
|
||||
var linearAttenuationXML:XML = null;
|
||||
var linearAttenuation:Number = NaN;
|
||||
var attenuationStart:Number = NaN;
|
||||
var attenuationEnd:Number = NaN;
|
||||
var dLight:DirectionalLight = null;
|
||||
var oLight:OmniLight = null;
|
||||
var hotspot:Number = NaN;
|
||||
var fallof:Number = NaN;
|
||||
var DEG2RAD:Number = NaN;
|
||||
var sLight:SpotLight = null;
|
||||
info = data.technique_common.children()[0];
|
||||
extra = data.extra.technique.(@profile[0] == "OpenCOLLADA3dsMax").light[0];
|
||||
light = null;
|
||||
if(info != null)
|
||||
{
|
||||
color = this.float4ToUint(parseNumbersArray(info.color[0]));
|
||||
linearAttenuation = 0;
|
||||
attenuationStart = 0;
|
||||
attenuationEnd = 1;
|
||||
switch(info.localName())
|
||||
{
|
||||
case "ambient":
|
||||
light = new AmbientLight(color);
|
||||
break;
|
||||
case "directional":
|
||||
dLight = new DirectionalLight(color);
|
||||
light = dLight;
|
||||
break;
|
||||
case "point":
|
||||
if(extra != null)
|
||||
{
|
||||
attenuationStart = parseNumber(extra.attenuation_far_start[0]);
|
||||
attenuationEnd = parseNumber(extra.attenuation_far_end[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
constantAttenuationXML = info.constant_attenuation[0];
|
||||
linearAttenuationXML = info.linear_attenuation[0];
|
||||
if(constantAttenuationXML != null)
|
||||
{
|
||||
attenuationStart = -parseNumber(constantAttenuationXML);
|
||||
}
|
||||
if(linearAttenuationXML != null)
|
||||
{
|
||||
linearAttenuation = parseNumber(linearAttenuationXML);
|
||||
}
|
||||
if(linearAttenuation > 0)
|
||||
{
|
||||
attenuationEnd = 1 / linearAttenuation + attenuationStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
attenuationEnd = attenuationStart + 1;
|
||||
}
|
||||
}
|
||||
oLight = new OmniLight(color,attenuationStart,attenuationEnd);
|
||||
light = oLight;
|
||||
break;
|
||||
case "spot":
|
||||
hotspot = 0;
|
||||
fallof = Math.PI / 4;
|
||||
DEG2RAD = Math.PI / 180;
|
||||
if(extra != null)
|
||||
{
|
||||
attenuationStart = parseNumber(extra.attenuation_far_start[0]);
|
||||
attenuationEnd = parseNumber(extra.attenuation_far_end[0]);
|
||||
hotspot = DEG2RAD * parseNumber(extra.hotspot_beam[0]);
|
||||
fallof = DEG2RAD * parseNumber(extra.falloff[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
constantAttenuationXML = info.constant_attenuation[0];
|
||||
linearAttenuationXML = info.linear_attenuation[0];
|
||||
if(constantAttenuationXML != null)
|
||||
{
|
||||
attenuationStart = -parseNumber(constantAttenuationXML);
|
||||
}
|
||||
if(linearAttenuationXML != null)
|
||||
{
|
||||
linearAttenuation = parseNumber(linearAttenuationXML);
|
||||
}
|
||||
if(linearAttenuation > 0)
|
||||
{
|
||||
attenuationEnd = 1 / linearAttenuation + attenuationStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
attenuationEnd = attenuationStart + 1;
|
||||
}
|
||||
}
|
||||
sLight = new SpotLight(color,attenuationStart,attenuationEnd,hotspot,fallof);
|
||||
light = sLight;
|
||||
}
|
||||
}
|
||||
return light;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
public class DaeLogger
|
||||
{
|
||||
public function DaeLogger()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private function logMessage(message:String, element:XML) : void
|
||||
{
|
||||
var name:String = element.nodeKind() == "attribute" ? "@" + element.localName() : element.localName() + "";
|
||||
for(var parent:* = element.parent(); parent != null; )
|
||||
{
|
||||
name = parent.localName() + "" + "." + name;
|
||||
parent = parent.parent();
|
||||
}
|
||||
trace(message,"| \"" + name + "\"");
|
||||
}
|
||||
|
||||
private function logError(message:String, element:XML) : void
|
||||
{
|
||||
this.logMessage("[ERROR] " + message,element);
|
||||
}
|
||||
|
||||
public function logExternalError(element:XML) : void
|
||||
{
|
||||
this.logError("External urls don\'t supported",element);
|
||||
}
|
||||
|
||||
public function logSkewError(element:XML) : void
|
||||
{
|
||||
this.logError("<skew> don\'t supported",element);
|
||||
}
|
||||
|
||||
public function logJointInAnotherSceneError(element:XML) : void
|
||||
{
|
||||
this.logError("Joints in different scenes don\'t supported",element);
|
||||
}
|
||||
|
||||
public function logInstanceNodeError(element:XML) : void
|
||||
{
|
||||
this.logError("<instance_node> don\'t supported",element);
|
||||
}
|
||||
|
||||
public function logNotFoundError(element:XML) : void
|
||||
{
|
||||
this.logError("Element with url \"" + element.toString() + "\" not found",element);
|
||||
}
|
||||
|
||||
public function logNotEnoughDataError(element:XML) : void
|
||||
{
|
||||
this.logError("Not enough data",element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.loaders.ParserMaterial;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeMaterial extends DaeElement
|
||||
{
|
||||
public var material:ParserMaterial;
|
||||
|
||||
public var mainTexCoords:String;
|
||||
|
||||
public var used:Boolean = false;
|
||||
|
||||
public function DaeMaterial(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
private function parseSetParams() : Object
|
||||
{
|
||||
var element:XML = null;
|
||||
var param:DaeParam = null;
|
||||
var params:Object = new Object();
|
||||
var list:XMLList = data.instance_effect.setparam;
|
||||
for each(element in list)
|
||||
{
|
||||
param = new DaeParam(element,document);
|
||||
params[param.ref] = param;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
private function get effectURL() : XML
|
||||
{
|
||||
return data.instance_effect.@url[0];
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var effect:DaeEffect = document.findEffect(this.effectURL);
|
||||
if(effect != null)
|
||||
{
|
||||
effect.parse();
|
||||
this.material = effect.getMaterial(this.parseSetParams());
|
||||
this.mainTexCoords = effect.mainTexCoords;
|
||||
if(this.material != null)
|
||||
{
|
||||
this.material.name = cloneString(name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.animation.AnimationClip;
|
||||
import alternativa.engine3d.animation.keys.NumberTrack;
|
||||
import alternativa.engine3d.animation.keys.Track;
|
||||
import alternativa.engine3d.animation.keys.TransformTrack;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.objects.Mesh;
|
||||
import alternativa.engine3d.objects.Skin;
|
||||
import flash.geom.Matrix3D;
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeNode extends DaeElement
|
||||
{
|
||||
public var scene:DaeVisualScene;
|
||||
|
||||
public var parent:DaeNode;
|
||||
|
||||
public var skinOrTopmostJoint:Boolean = false;
|
||||
|
||||
private var channels:Vector.<DaeChannel>;
|
||||
|
||||
private var name_DE:Vector.<DaeInstanceController>;
|
||||
|
||||
public var nodes:Vector.<DaeNode>;
|
||||
|
||||
public var objects:Vector.<DaeObject>;
|
||||
|
||||
public var skins:Vector.<DaeObject>;
|
||||
|
||||
public function DaeNode(data:XML, document:DaeDocument, scene:DaeVisualScene = null, parent:DaeNode = null)
|
||||
{
|
||||
super(data,document);
|
||||
this.scene = scene;
|
||||
this.parent = parent;
|
||||
this.constructNodes();
|
||||
}
|
||||
|
||||
public function get animName() : String
|
||||
{
|
||||
var n:String = this.name;
|
||||
return n == null ? this.id : n;
|
||||
}
|
||||
|
||||
private function constructNodes() : void
|
||||
{
|
||||
var node:DaeNode = null;
|
||||
var nodesList:XMLList = data.node;
|
||||
var count:int = int(nodesList.length());
|
||||
this.nodes = new Vector.<DaeNode>(count);
|
||||
for(var i:int = 0; i < count; i++)
|
||||
{
|
||||
node = new DaeNode(nodesList[i],document,this.scene,this);
|
||||
if(node.id != null)
|
||||
{
|
||||
document.nodes[node.id] = node;
|
||||
}
|
||||
this.nodes[i] = node;
|
||||
}
|
||||
}
|
||||
|
||||
internal function registerInstanceControllers() : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var instanceControllerXML:XML = null;
|
||||
var instanceController:DaeInstanceController = null;
|
||||
var jointNodes:Vector.<DaeNode> = null;
|
||||
var numNodes:int = 0;
|
||||
var jointNode:DaeNode = null;
|
||||
var j:int = 0;
|
||||
var instanceControllerXMLs:XMLList = data.instance_controller;
|
||||
var count:int = int(instanceControllerXMLs.length());
|
||||
for(i = 0; i < count; )
|
||||
{
|
||||
this.skinOrTopmostJoint = true;
|
||||
instanceControllerXML = instanceControllerXMLs[i];
|
||||
instanceController = new DaeInstanceController(instanceControllerXML,document,this);
|
||||
if(instanceController.parse())
|
||||
{
|
||||
jointNodes = instanceController.topmostJoints;
|
||||
numNodes = int(jointNodes.length);
|
||||
if(numNodes > 0)
|
||||
{
|
||||
jointNode = jointNodes[0];
|
||||
jointNode.addInstanceController(instanceController);
|
||||
for(j = 0; j < numNodes; j++)
|
||||
{
|
||||
jointNodes[j].skinOrTopmostJoint = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
count = int(this.nodes.length);
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
this.nodes[i].registerInstanceControllers();
|
||||
}
|
||||
}
|
||||
|
||||
public function addChannel(channel:DaeChannel) : void
|
||||
{
|
||||
if(this.channels == null)
|
||||
{
|
||||
this.channels = new Vector.<DaeChannel>();
|
||||
}
|
||||
this.channels.push(channel);
|
||||
}
|
||||
|
||||
public function addInstanceController(controller:DaeInstanceController) : void
|
||||
{
|
||||
if(this.name_DE == null)
|
||||
{
|
||||
this.name_DE = new Vector.<DaeInstanceController>();
|
||||
}
|
||||
this.name_DE.push(controller);
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
this.skins = this.parseSkins();
|
||||
this.objects = this.parseObjects();
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseInstanceMaterials(geometry:XML) : Object
|
||||
{
|
||||
var instance:DaeInstanceMaterial = null;
|
||||
var instances:Object = new Object();
|
||||
var list:XMLList = geometry.bind_material.technique_common.instance_material;
|
||||
for(var i:int = 0, count:int = int(list.length()); i < count; i++)
|
||||
{
|
||||
instance = new DaeInstanceMaterial(list[i],document);
|
||||
instances[instance.symbol] = instance;
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
public function getNodeBySid(sid:String) : DaeNode
|
||||
{
|
||||
var i:int = 0;
|
||||
var temp:Vector.<Vector.<DaeNode>> = null;
|
||||
var children:Vector.<DaeNode> = null;
|
||||
var count:int = 0;
|
||||
var j:int = 0;
|
||||
var node:DaeNode = null;
|
||||
if(sid == this.sid)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
var levelNodes:Vector.<Vector.<DaeNode>> = new Vector.<Vector.<DaeNode>>();
|
||||
var levelNodes2:Vector.<Vector.<DaeNode>> = new Vector.<Vector.<DaeNode>>();
|
||||
levelNodes.push(this.nodes);
|
||||
for(var len:int = int(levelNodes.length); len > 0; )
|
||||
{
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
children = levelNodes[i];
|
||||
count = int(children.length);
|
||||
for(j = 0; j < count; )
|
||||
{
|
||||
node = children[j];
|
||||
if(node.sid == sid)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
if(node.nodes.length > 0)
|
||||
{
|
||||
levelNodes2.push(node.nodes);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
temp = levelNodes;
|
||||
levelNodes = levelNodes2;
|
||||
levelNodes2 = temp;
|
||||
levelNodes2.length = 0;
|
||||
len = int(levelNodes.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function parseSkins() : Vector.<DaeObject>
|
||||
{
|
||||
var instanceController:DaeInstanceController = null;
|
||||
var skinAndAnimatedJoints:DaeObject = null;
|
||||
var skin:Skin = null;
|
||||
if(this.name_DE == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var skins:Vector.<DaeObject> = new Vector.<DaeObject>();
|
||||
for(var i:int = 0, count:int = int(this.name_DE.length); i < count; )
|
||||
{
|
||||
instanceController = this.name_DE[i];
|
||||
instanceController.parse();
|
||||
skinAndAnimatedJoints = instanceController.parseSkin(this.parseInstanceMaterials(instanceController.data));
|
||||
if(skinAndAnimatedJoints != null)
|
||||
{
|
||||
skin = Skin(skinAndAnimatedJoints.object);
|
||||
skin.name = cloneString(instanceController.node.name);
|
||||
skins.push(skinAndAnimatedJoints);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return skins.length > 0 ? skins : null;
|
||||
}
|
||||
|
||||
public function parseObjects() : Vector.<DaeObject>
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var child:XML = null;
|
||||
var _loc6_:DaeLight = null;
|
||||
var _loc7_:DaeGeometry = null;
|
||||
var light:Light3D = null;
|
||||
var rotXMatrix:Matrix3D = null;
|
||||
var mesh:Mesh = null;
|
||||
var objects:Vector.<DaeObject> = new Vector.<DaeObject>();
|
||||
var children:XMLList = data.children();
|
||||
for(i = 0,count = int(children.length()); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
switch(child.localName())
|
||||
{
|
||||
case "instance_light":
|
||||
_loc6_ = document.findLight(child.@url[0]);
|
||||
if(_loc6_ != null)
|
||||
{
|
||||
light = _loc6_.parseLight();
|
||||
if(light != null)
|
||||
{
|
||||
light.name = cloneString(name);
|
||||
if(_loc6_.revertDirection)
|
||||
{
|
||||
rotXMatrix = new Matrix3D();
|
||||
rotXMatrix.appendRotation(180,Vector3D.X_AXIS);
|
||||
objects.push(new DaeObject(this.applyTransformations(light,rotXMatrix)));
|
||||
}
|
||||
else
|
||||
{
|
||||
objects.push(this.applyAnimation(this.applyTransformations(light)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(child.@url[0]);
|
||||
}
|
||||
break;
|
||||
case "instance_geometry":
|
||||
_loc7_ = document.findGeometry(child.@url[0]);
|
||||
if(_loc7_ != null)
|
||||
{
|
||||
_loc7_.parse();
|
||||
mesh = _loc7_.parseMesh(this.parseInstanceMaterials(child));
|
||||
if(mesh != null)
|
||||
{
|
||||
mesh.name = cloneString(name);
|
||||
objects.push(this.applyAnimation(this.applyTransformations(mesh)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(child.@url[0]);
|
||||
}
|
||||
break;
|
||||
case "instance_node":
|
||||
document.logger.logInstanceNodeError(child);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return objects.length > 0 ? objects : null;
|
||||
}
|
||||
|
||||
private function getMatrix(initialMatrix:Matrix3D = null) : Matrix3D
|
||||
{
|
||||
var components:Array = null;
|
||||
var child:XML = null;
|
||||
var sid:XML = null;
|
||||
var matrix:Matrix3D = initialMatrix == null ? new Matrix3D() : initialMatrix;
|
||||
var children:XMLList = data.children();
|
||||
for(var i:int = children.length() - 1; i >= 0; i--)
|
||||
{
|
||||
child = children[i];
|
||||
sid = child.@sid[0];
|
||||
if(sid != null && sid.toString() == "post-rotationY")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch(child.localName())
|
||||
{
|
||||
case "scale":
|
||||
components = parseNumbersArray(child);
|
||||
matrix.appendScale(components[0],components[1],components[2]);
|
||||
break;
|
||||
case "rotate":
|
||||
components = parseNumbersArray(child);
|
||||
matrix.appendRotation(components[3],new Vector3D(components[0],components[1],components[2]));
|
||||
break;
|
||||
case "translate":
|
||||
components = parseNumbersArray(child);
|
||||
matrix.appendTranslation(components[0] * document.unitScaleFactor,components[1] * document.unitScaleFactor,components[2] * document.unitScaleFactor);
|
||||
break;
|
||||
case "matrix":
|
||||
components = parseNumbersArray(child);
|
||||
matrix.append(new Matrix3D(Vector.<Number>([components[0],components[4],components[8],components[12],components[1],components[5],components[9],components[13],components[2],components[6],components[10],components[14],components[3] * document.unitScaleFactor,components[7] * document.unitScaleFactor,components[11] * document.unitScaleFactor,components[15]])));
|
||||
break;
|
||||
case "lookat":
|
||||
break;
|
||||
case "skew":
|
||||
document.logger.logSkewError(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public function applyTransformations(object:Object3D, prepend:Matrix3D = null, append:Matrix3D = null) : Object3D
|
||||
{
|
||||
var matrix:Matrix3D = this.getMatrix(prepend);
|
||||
if(append != null)
|
||||
{
|
||||
matrix.append(append);
|
||||
}
|
||||
var vs:Vector.<Vector3D> = matrix.decompose();
|
||||
var t:Vector3D = vs[0];
|
||||
var r:Vector3D = vs[1];
|
||||
var s:Vector3D = vs[2];
|
||||
object.x = t.x;
|
||||
object.y = t.y;
|
||||
object.z = t.z;
|
||||
object.rotationX = r.x;
|
||||
object.rotationY = r.y;
|
||||
object.rotationZ = r.z;
|
||||
object.scaleX = s.x;
|
||||
object.scaleY = s.y;
|
||||
object.scaleZ = s.z;
|
||||
return object;
|
||||
}
|
||||
|
||||
public function applyAnimation(object:Object3D) : DaeObject
|
||||
{
|
||||
var animation:AnimationClip = this.parseAnimation(object);
|
||||
if(animation == null)
|
||||
{
|
||||
return new DaeObject(object);
|
||||
}
|
||||
object.name = this.animName;
|
||||
animation.attach(object,false);
|
||||
return new DaeObject(object,animation);
|
||||
}
|
||||
|
||||
public function parseAnimation(object:Object3D = null) : AnimationClip
|
||||
{
|
||||
if(this.channels == null || !this.hasTransformationAnimation())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var channel:DaeChannel = this.getChannel(DaeChannel.PARAM_MATRIX);
|
||||
if(channel != null)
|
||||
{
|
||||
return this.createClip(channel.tracks);
|
||||
}
|
||||
var clip:AnimationClip = new AnimationClip();
|
||||
var components:Vector.<Vector3D> = object != null ? null : this.getMatrix().decompose();
|
||||
channel = this.getChannel(DaeChannel.PARAM_TRANSLATE);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = this.getChannel(DaeChannel.PARAM_TRANSLATE_X);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("x",object == null ? Number(components[0].x) : object.x));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_TRANSLATE_Y);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("y",object == null ? Number(components[0].y) : object.y));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_TRANSLATE_Z);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("z",object == null ? Number(components[0].z) : object.z));
|
||||
}
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_ROTATION_X);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("rotationX",object == null ? Number(components[1].x) : object.rotationX));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_ROTATION_Y);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("rotationY",object == null ? Number(components[1].y) : object.rotationY));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_ROTATION_Z);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("rotationZ",object == null ? Number(components[1].z) : object.rotationZ));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_SCALE);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = this.getChannel(DaeChannel.PARAM_SCALE_X);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("scaleX",object == null ? Number(components[2].x) : object.scaleX));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_SCALE_Y);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("scaleY",object == null ? Number(components[2].y) : object.scaleY));
|
||||
}
|
||||
channel = this.getChannel(DaeChannel.PARAM_SCALE_Z);
|
||||
if(channel != null)
|
||||
{
|
||||
this.addTracksToClip(clip,channel.tracks);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.addTrack(this.createValueStaticTrack("scaleZ",object == null ? Number(components[2].z) : object.scaleZ));
|
||||
}
|
||||
}
|
||||
if(clip.numTracks > 0)
|
||||
{
|
||||
return clip;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createClip(tracks:Vector.<Track>) : AnimationClip
|
||||
{
|
||||
var clip:AnimationClip = new AnimationClip();
|
||||
for(var i:int = 0, count:int = int(tracks.length); i < count; i++)
|
||||
{
|
||||
clip.addTrack(tracks[i]);
|
||||
}
|
||||
return clip;
|
||||
}
|
||||
|
||||
private function addTracksToClip(clip:AnimationClip, tracks:Vector.<Track>) : void
|
||||
{
|
||||
for(var i:int = 0, count:int = int(tracks.length); i < count; i++)
|
||||
{
|
||||
clip.addTrack(tracks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private function hasTransformationAnimation() : Boolean
|
||||
{
|
||||
var channel:DaeChannel = null;
|
||||
var result:Boolean = false;
|
||||
for(var i:int = 0, count:int = int(this.channels.length); i < count; )
|
||||
{
|
||||
channel = this.channels[i];
|
||||
channel.parse();
|
||||
result = channel.name_dS == DaeChannel.PARAM_MATRIX;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_TRANSLATE;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_TRANSLATE_X;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_TRANSLATE_Y;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_TRANSLATE_Z;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_ROTATION_X;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_ROTATION_Y;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_ROTATION_Z;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_SCALE;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_SCALE_X;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_SCALE_Y;
|
||||
result ||= channel.name_dS == DaeChannel.PARAM_SCALE_Z;
|
||||
if(result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getChannel(param:String) : DaeChannel
|
||||
{
|
||||
var channel:DaeChannel = null;
|
||||
for(var i:int = 0, count:int = int(this.channels.length); i < count; )
|
||||
{
|
||||
channel = this.channels[i];
|
||||
channel.parse();
|
||||
if(channel.name_dS == param)
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function concatTracks(source:Vector.<Track>, dest:Vector.<Track>) : void
|
||||
{
|
||||
for(var i:int = 0, count:int = int(source.length); i < count; i++)
|
||||
{
|
||||
dest.push(source[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createValueStaticTrack(property:String, value:Number) : Track
|
||||
{
|
||||
var track:NumberTrack = new NumberTrack(this.animName,property);
|
||||
track.addKey(0,value);
|
||||
return track;
|
||||
}
|
||||
|
||||
public function createStaticTransformTrack() : TransformTrack
|
||||
{
|
||||
var track:TransformTrack = new TransformTrack(this.animName);
|
||||
track.addKey(0,this.getMatrix());
|
||||
return track;
|
||||
}
|
||||
|
||||
public function get layer() : String
|
||||
{
|
||||
var layerXML:XML = data.@layer[0];
|
||||
return layerXML == null ? null : layerXML.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.animation.AnimationClip;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
|
||||
public class DaeObject
|
||||
{
|
||||
public var object:Object3D;
|
||||
|
||||
public var animation:AnimationClip;
|
||||
|
||||
public var jointNode:DaeNode;
|
||||
|
||||
public function DaeObject(object:Object3D, animation:AnimationClip = null)
|
||||
{
|
||||
super();
|
||||
this.object = object;
|
||||
this.animation = animation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeParam extends DaeElement
|
||||
{
|
||||
public function DaeParam(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
public function get ref() : String
|
||||
{
|
||||
var attribute:XML = data.@ref[0];
|
||||
return attribute == null ? null : attribute.toString();
|
||||
}
|
||||
|
||||
public function getFloat() : Number
|
||||
{
|
||||
var floatXML:XML = data.float[0];
|
||||
if(floatXML != null)
|
||||
{
|
||||
return parseNumber(floatXML);
|
||||
}
|
||||
return NaN;
|
||||
}
|
||||
|
||||
public function getFloat4() : Array
|
||||
{
|
||||
var components:Array = null;
|
||||
var element:XML = data.float4[0];
|
||||
if(element == null)
|
||||
{
|
||||
element = data.float3[0];
|
||||
if(element != null)
|
||||
{
|
||||
components = parseNumbersArray(element);
|
||||
components[3] = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
components = parseNumbersArray(element);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
public function get surfaceSID() : String
|
||||
{
|
||||
var element:XML = data.sampler2D.source[0];
|
||||
return element == null ? null : element.text().toString();
|
||||
}
|
||||
|
||||
public function get wrap_s() : String
|
||||
{
|
||||
var element:XML = data.sampler2D.wrap_s[0];
|
||||
return element == null ? null : element.text().toString();
|
||||
}
|
||||
|
||||
public function get image() : DaeImage
|
||||
{
|
||||
var image:DaeImage = null;
|
||||
var init_from:XML = null;
|
||||
var _loc4_:XML = null;
|
||||
var surface:XML = data.surface[0];
|
||||
if(surface != null)
|
||||
{
|
||||
init_from = surface.init_from[0];
|
||||
if(init_from == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
image = document.findImageByID(init_from.text().toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc4_ = data.instance_image.@url[0];
|
||||
if(_loc4_ == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
image = document.findImage(_loc4_);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
|
||||
use namespace collada;
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class DaePrimitive extends DaeElement
|
||||
{
|
||||
internal static const NORMALS:int = 1;
|
||||
|
||||
internal static const TANGENT4:int = 2;
|
||||
|
||||
internal static const TEXCOORDS:Vector.<uint> = Vector.<uint>([8,16,32,64,128,256,512,1024]);
|
||||
|
||||
internal var name_2g:DaeInput;
|
||||
|
||||
internal var name_aL:Vector.<DaeInput>;
|
||||
|
||||
internal var name_Fl:DaeInput;
|
||||
|
||||
internal var name_jU:Vector.<DaeInput>;
|
||||
|
||||
internal var name_ly:Vector.<DaeInput>;
|
||||
|
||||
internal var indices:Vector.<uint>;
|
||||
|
||||
internal var name_5O:int;
|
||||
|
||||
public var indexBegin:int;
|
||||
|
||||
public var numTriangles:int;
|
||||
|
||||
public function DaePrimitive(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
this.parseInputs();
|
||||
this.parseIndices();
|
||||
return true;
|
||||
}
|
||||
|
||||
private function get type() : String
|
||||
{
|
||||
return data.localName() as String;
|
||||
}
|
||||
|
||||
private function parseInputs() : void
|
||||
{
|
||||
var input:DaeInput = null;
|
||||
var semantic:String = null;
|
||||
var offset:int = 0;
|
||||
this.name_aL = new Vector.<DaeInput>();
|
||||
this.name_ly = new Vector.<DaeInput>();
|
||||
this.name_jU = new Vector.<DaeInput>();
|
||||
var inputsList:XMLList = data.input;
|
||||
var maxInputOffset:int = 0;
|
||||
for(var i:int = 0, count:int = int(inputsList.length()); i < count; offset = input.offset,maxInputOffset = offset > maxInputOffset ? offset : maxInputOffset,i++)
|
||||
{
|
||||
input = new DaeInput(inputsList[i],document);
|
||||
semantic = input.semantic;
|
||||
if(semantic == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch(semantic)
|
||||
{
|
||||
case "VERTEX":
|
||||
if(this.name_2g == null)
|
||||
{
|
||||
this.name_2g = input;
|
||||
}
|
||||
break;
|
||||
case "TEXCOORD":
|
||||
this.name_aL.push(input);
|
||||
break;
|
||||
case "NORMAL":
|
||||
if(this.name_Fl == null)
|
||||
{
|
||||
this.name_Fl = input;
|
||||
}
|
||||
break;
|
||||
case "TEXTANGENT":
|
||||
this.name_ly.push(input);
|
||||
break;
|
||||
case "TEXBINORMAL":
|
||||
this.name_jU.push(input);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.name_5O = maxInputOffset + 1;
|
||||
}
|
||||
|
||||
private function parseIndices() : void
|
||||
{
|
||||
var array:Array = null;
|
||||
var _loc5_:XMLList = null;
|
||||
var _loc6_:XMLList = null;
|
||||
var j:int = 0;
|
||||
this.indices = new Vector.<uint>();
|
||||
var vcount:Vector.<int> = new Vector.<int>();
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
switch(data.localName())
|
||||
{
|
||||
case "polylist":
|
||||
case "polygons":
|
||||
_loc5_ = data.vcount;
|
||||
array = parseStringArray(_loc5_[0]);
|
||||
i = 0;
|
||||
count = int(array.length);
|
||||
while(true)
|
||||
{
|
||||
if(i < count)
|
||||
{
|
||||
vcount.push(parseInt(array[i]));
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
case "triangles":
|
||||
_loc6_ = data.p;
|
||||
for(i = 0,count = int(_loc6_.length()); i < count; )
|
||||
{
|
||||
array = parseStringArray(_loc6_[i]);
|
||||
for(j = 0; j < array.length; j++)
|
||||
{
|
||||
this.indices.push(parseInt(array[j],10));
|
||||
}
|
||||
if(vcount.length > 0)
|
||||
{
|
||||
this.indices = this.triangulate(this.indices,vcount);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function triangulate(input:Vector.<uint>, vcount:Vector.<int>) : Vector.<uint>
|
||||
{
|
||||
var indexIn:uint = 0;
|
||||
var i:int = 0;
|
||||
var j:int = 0;
|
||||
var k:int = 0;
|
||||
var count:int = 0;
|
||||
var verticesCount:int = 0;
|
||||
var attributesCount:int = 0;
|
||||
var res:Vector.<uint> = new Vector.<uint>();
|
||||
var indexOut:uint = 0;
|
||||
for(i = 0,count = int(vcount.length); i < count; i++)
|
||||
{
|
||||
verticesCount = vcount[i];
|
||||
attributesCount = verticesCount * this.name_5O;
|
||||
if(verticesCount == 3)
|
||||
{
|
||||
j = 0;
|
||||
while(j < attributesCount)
|
||||
{
|
||||
res[indexOut] = input[indexIn];
|
||||
j++;
|
||||
indexIn++;
|
||||
indexOut++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(j = 1; j < verticesCount - 1; )
|
||||
{
|
||||
for(k = 0; k < this.name_5O; k++,indexOut++)
|
||||
{
|
||||
res[indexOut] = input[int(indexIn + k)];
|
||||
}
|
||||
for(k = 0; k < this.name_5O; k++,indexOut++)
|
||||
{
|
||||
res[indexOut] = input[int(indexIn + this.name_5O * j + k)];
|
||||
}
|
||||
for(k = 0; k < this.name_5O; k++,indexOut++)
|
||||
{
|
||||
res[indexOut] = input[int(indexIn + this.name_5O * (j + 1) + k)];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
indexIn += this.name_5O * verticesCount;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public function fillGeometry(geometry:Geometry, vertices:Vector.<DaeVertex>) : uint
|
||||
{
|
||||
var tangentSource:DaeSource = null;
|
||||
var binormalSource:DaeSource = null;
|
||||
var normalSource:DaeSource = null;
|
||||
var index:uint = 0;
|
||||
var vertex:DaeVertex = null;
|
||||
var s:DaeSource = null;
|
||||
var j:int = 0;
|
||||
if(this.name_2g == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
this.name_2g.parse();
|
||||
var numIndices:int = int(this.indices.length);
|
||||
var daeVertices:DaeVertices = document.findVertices(this.name_2g.source);
|
||||
if(daeVertices == null)
|
||||
{
|
||||
document.logger.logNotFoundError(this.name_2g.source);
|
||||
return 0;
|
||||
}
|
||||
daeVertices.parse();
|
||||
var positionSource:DaeSource = daeVertices.name_E6;
|
||||
var vertexStride:int = 3;
|
||||
var mainSource:DaeSource = positionSource;
|
||||
var mainInput:DaeInput = this.name_2g;
|
||||
var channels:uint = 0;
|
||||
var inputOffsets:Vector.<int> = new Vector.<int>();
|
||||
inputOffsets.push(this.name_2g.offset);
|
||||
if(this.name_Fl != null)
|
||||
{
|
||||
normalSource = this.name_Fl.prepareSource(3);
|
||||
inputOffsets.push(this.name_Fl.offset);
|
||||
vertexStride += 3;
|
||||
channels |= NORMALS;
|
||||
if(this.name_ly.length > 0 && this.name_jU.length > 0)
|
||||
{
|
||||
tangentSource = this.name_ly[0].prepareSource(3);
|
||||
inputOffsets.push(this.name_ly[0].offset);
|
||||
binormalSource = this.name_jU[0].prepareSource(3);
|
||||
inputOffsets.push(this.name_jU[0].offset);
|
||||
vertexStride += 4;
|
||||
channels |= TANGENT4;
|
||||
}
|
||||
}
|
||||
var textureSources:Vector.<DaeSource> = new Vector.<DaeSource>();
|
||||
var numTexCoordsInputs:int = int(this.name_aL.length);
|
||||
if(numTexCoordsInputs > 8)
|
||||
{
|
||||
numTexCoordsInputs = 8;
|
||||
}
|
||||
for(var i:int = 0; i < numTexCoordsInputs; )
|
||||
{
|
||||
s = this.name_aL[i].prepareSource(2);
|
||||
textureSources.push(s);
|
||||
inputOffsets.push(this.name_aL[i].offset);
|
||||
vertexStride += 2;
|
||||
channels |= TEXCOORDS[i];
|
||||
i++;
|
||||
}
|
||||
var verticesLength:int = int(vertices.length);
|
||||
this.indexBegin = geometry.alternativa3d::_indices.length;
|
||||
for(i = 0; i < numIndices; i += this.name_5O)
|
||||
{
|
||||
index = this.indices[int(i + mainInput.offset)];
|
||||
vertex = vertices[index];
|
||||
if(vertex == null || !this.isEqual(vertex,this.indices,i,inputOffsets))
|
||||
{
|
||||
if(vertex != null)
|
||||
{
|
||||
index = uint(verticesLength++);
|
||||
}
|
||||
vertex = new DaeVertex();
|
||||
vertices[index] = vertex;
|
||||
vertex.name_Eq = this.indices[int(i + this.name_2g.offset)];
|
||||
vertex.addPosition(positionSource.numbers,vertex.name_Eq,positionSource.stride,document.unitScaleFactor);
|
||||
if(normalSource != null)
|
||||
{
|
||||
vertex.addNormal(normalSource.numbers,this.indices[int(i + this.name_Fl.offset)],normalSource.stride);
|
||||
}
|
||||
if(tangentSource != null)
|
||||
{
|
||||
vertex.addTangentBiDirection(tangentSource.numbers,this.indices[int(i + this.name_ly[0].offset)],tangentSource.stride,binormalSource.numbers,this.indices[int(i + this.name_jU[0].offset)],binormalSource.stride);
|
||||
}
|
||||
for(j = 0; j < textureSources.length; )
|
||||
{
|
||||
vertex.appendUV(textureSources[j].numbers,this.indices[int(i + this.name_aL[j].offset)],textureSources[j].stride);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
vertex.name_AR = index;
|
||||
geometry.alternativa3d::_indices.push(index);
|
||||
}
|
||||
this.numTriangles = (geometry.alternativa3d::_indices.length - this.indexBegin) / 3;
|
||||
return channels;
|
||||
}
|
||||
|
||||
private function isEqual(vertex:DaeVertex, indices:Vector.<uint>, index:int, offsets:Vector.<int>) : Boolean
|
||||
{
|
||||
var numOffsets:int = int(offsets.length);
|
||||
for(var j:int = 0; j < numOffsets; )
|
||||
{
|
||||
if(vertex.indices[j] != indices[int(index + offsets[j])])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function findInputBySet(inputs:Vector.<DaeInput>, setNum:int) : DaeInput
|
||||
{
|
||||
var input:DaeInput = null;
|
||||
for(var i:int = 0, numInputs:int = int(inputs.length); i < numInputs; )
|
||||
{
|
||||
input = inputs[i];
|
||||
if(input.setNum == setNum)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getTexCoordsDatas(mainSetNum:int) : Vector.<VertexChannelData>
|
||||
{
|
||||
var i:int = 0;
|
||||
var texCoordsInput:DaeInput = null;
|
||||
var texCoordsSource:DaeSource = null;
|
||||
var data:VertexChannelData = null;
|
||||
var mainInput:DaeInput = this.findInputBySet(this.name_aL,mainSetNum);
|
||||
var numInputs:int = int(this.name_aL.length);
|
||||
var datas:Vector.<VertexChannelData> = new Vector.<VertexChannelData>();
|
||||
for(i = 0; i < numInputs; )
|
||||
{
|
||||
texCoordsInput = this.name_aL[i];
|
||||
texCoordsSource = texCoordsInput.prepareSource(2);
|
||||
if(texCoordsSource != null)
|
||||
{
|
||||
data = new VertexChannelData(texCoordsSource.numbers,texCoordsSource.stride,texCoordsInput.offset,texCoordsInput.setNum);
|
||||
if(texCoordsInput == mainInput)
|
||||
{
|
||||
datas.unshift(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
datas.push(data);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return datas.length > 0 ? datas : null;
|
||||
}
|
||||
|
||||
public function verticesEquals(otherVertices:DaeVertices) : Boolean
|
||||
{
|
||||
var vertices:DaeVertices = document.findVertices(this.name_2g.source);
|
||||
if(vertices == null)
|
||||
{
|
||||
document.logger.logNotFoundError(this.name_2g.source);
|
||||
}
|
||||
return vertices == otherVertices;
|
||||
}
|
||||
|
||||
public function get materialSymbol() : String
|
||||
{
|
||||
var attr:XML = data.@material[0];
|
||||
return attr == null ? null : attr.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import flash.geom.Point;
|
||||
|
||||
class VertexChannelData
|
||||
{
|
||||
public var values:Vector.<Number>;
|
||||
|
||||
public var stride:int;
|
||||
|
||||
public var offset:int;
|
||||
|
||||
public var index:int;
|
||||
|
||||
public var channel:Vector.<Point>;
|
||||
|
||||
public var inputSet:int;
|
||||
|
||||
public function VertexChannelData(values:Vector.<Number>, stride:int, offset:int, inputSet:int = 0)
|
||||
{
|
||||
super();
|
||||
this.values = values;
|
||||
this.stride = stride;
|
||||
this.offset = offset;
|
||||
this.inputSet = inputSet;
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.animation.keys.NumberTrack;
|
||||
import alternativa.engine3d.animation.keys.Track;
|
||||
import alternativa.engine3d.animation.keys.TransformTrack;
|
||||
import flash.geom.Matrix3D;
|
||||
|
||||
use namespace collada;
|
||||
|
||||
public class DaeSampler extends DaeElement
|
||||
{
|
||||
private var name_G6:Vector.<Number>;
|
||||
|
||||
private var values:Vector.<Number>;
|
||||
|
||||
private var name_JC:int;
|
||||
|
||||
private var name_7i:int;
|
||||
|
||||
public function DaeSampler(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var inputSource:DaeSource = null;
|
||||
var outputSource:DaeSource = null;
|
||||
var input:DaeInput = null;
|
||||
var semantic:String = null;
|
||||
var inputsList:XMLList = data.input;
|
||||
for(var i:int = 0, count:int = int(inputsList.length()); i < count; i++)
|
||||
{
|
||||
input = new DaeInput(inputsList[i],document);
|
||||
semantic = input.semantic;
|
||||
if(semantic == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch(semantic)
|
||||
{
|
||||
case "INPUT":
|
||||
inputSource = input.prepareSource(1);
|
||||
if(inputSource != null)
|
||||
{
|
||||
this.name_G6 = inputSource.numbers;
|
||||
this.name_JC = inputSource.stride;
|
||||
}
|
||||
break;
|
||||
case "OUTPUT":
|
||||
outputSource = input.prepareSource(1);
|
||||
if(outputSource != null)
|
||||
{
|
||||
this.values = outputSource.numbers;
|
||||
this.name_7i = outputSource.stride;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function parseNumbersTrack(objectName:String, property:String) : NumberTrack
|
||||
{
|
||||
var track:NumberTrack = null;
|
||||
var count:int = 0;
|
||||
var i:int = 0;
|
||||
if(this.name_G6 != null && this.values != null && this.name_JC > 0)
|
||||
{
|
||||
track = new NumberTrack(objectName,property);
|
||||
count = this.name_G6.length / this.name_JC;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
track.addKey(this.name_G6[int(this.name_JC * i)],this.values[int(this.name_7i * i)]);
|
||||
}
|
||||
return track;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function parseTransformationTrack(objectName:String) : Track
|
||||
{
|
||||
var track:TransformTrack = null;
|
||||
var count:int = 0;
|
||||
var i:int = 0;
|
||||
var index:int = 0;
|
||||
var matrix:Matrix3D = null;
|
||||
if(this.name_G6 != null && this.values != null && this.name_JC != 0)
|
||||
{
|
||||
track = new TransformTrack(objectName);
|
||||
count = this.name_G6.length / this.name_JC;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
index = this.name_7i * i;
|
||||
matrix = new Matrix3D(Vector.<Number>([this.values[index],this.values[index + 4],this.values[index + 8],this.values[index + 12],this.values[index + 1],this.values[index + 5],this.values[index + 9],this.values[index + 13],this.values[index + 2],this.values[index + 6],this.values[index + 10],this.values[index + 14],this.values[index + 3],this.values[index + 7],this.values[index + 11],this.values[index + 15]]));
|
||||
track.addKey(this.name_G6[i * this.name_JC],matrix);
|
||||
}
|
||||
return track;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function parsePointsTracks(objectName:String, xProperty:String, yProperty:String, zProperty:String) : Vector.<Track>
|
||||
{
|
||||
var xTrack:NumberTrack = null;
|
||||
var yTrack:NumberTrack = null;
|
||||
var zTrack:NumberTrack = null;
|
||||
var count:int = 0;
|
||||
var i:int = 0;
|
||||
var index:int = 0;
|
||||
var time:Number = NaN;
|
||||
if(this.name_G6 != null && this.values != null && this.name_JC != 0)
|
||||
{
|
||||
xTrack = new NumberTrack(objectName,xProperty);
|
||||
xTrack.object = objectName;
|
||||
yTrack = new NumberTrack(objectName,yProperty);
|
||||
yTrack.object = objectName;
|
||||
zTrack = new NumberTrack(objectName,zProperty);
|
||||
zTrack.object = objectName;
|
||||
count = this.name_G6.length / this.name_JC;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
index = i * this.name_7i;
|
||||
time = this.name_G6[i * this.name_JC];
|
||||
xTrack.addKey(time,this.values[index]);
|
||||
yTrack.addKey(time,this.values[index + 1]);
|
||||
zTrack.addKey(time,this.values[index + 2]);
|
||||
}
|
||||
return Vector.<Track>([xTrack,yTrack,zTrack]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeSource extends DaeElement
|
||||
{
|
||||
private const name_XM:String = "float_array";
|
||||
|
||||
private const name_g6:String = "int_array";
|
||||
|
||||
private const name_ZJ:String = "Name_array";
|
||||
|
||||
public var numbers:Vector.<Number>;
|
||||
|
||||
public var name_op:Vector.<int>;
|
||||
|
||||
public var names:Vector.<String>;
|
||||
|
||||
public var stride:int;
|
||||
|
||||
public function DaeSource(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
this.constructArrays();
|
||||
}
|
||||
|
||||
private function constructArrays() : void
|
||||
{
|
||||
var child:XML = null;
|
||||
var _loc5_:DaeArray = null;
|
||||
var children:XMLList = data.children();
|
||||
for(var i:int = 0, count:int = int(children.length()); i < count; )
|
||||
{
|
||||
child = children[i];
|
||||
switch(child.localName())
|
||||
{
|
||||
case this.name_XM:
|
||||
case this.name_g6:
|
||||
case this.name_ZJ:
|
||||
_loc5_ = new DaeArray(child,document);
|
||||
if(_loc5_.id != null)
|
||||
{
|
||||
document.arrays[_loc5_.id] = _loc5_;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function get accessor() : XML
|
||||
{
|
||||
return data.technique_common.accessor[0];
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var arrayXML:XML = null;
|
||||
var array:DaeArray = null;
|
||||
var countXML:String = null;
|
||||
var count:int = 0;
|
||||
var offsetXML:XML = null;
|
||||
var strideXML:XML = null;
|
||||
var offset:int = 0;
|
||||
var stride:int = 0;
|
||||
var accessor:XML = this.accessor;
|
||||
if(accessor != null)
|
||||
{
|
||||
arrayXML = accessor.@source[0];
|
||||
array = arrayXML == null ? null : document.findArray(arrayXML);
|
||||
if(array != null)
|
||||
{
|
||||
countXML = accessor.@count[0];
|
||||
if(countXML != null)
|
||||
{
|
||||
count = int(parseInt(countXML.toString(),10));
|
||||
offsetXML = accessor.@offset[0];
|
||||
strideXML = accessor.@stride[0];
|
||||
offset = offsetXML == null ? 0 : int(parseInt(offsetXML.toString(),10));
|
||||
stride = strideXML == null ? 1 : int(parseInt(strideXML.toString(),10));
|
||||
array.parse();
|
||||
if(array.array.length < offset + count * stride)
|
||||
{
|
||||
document.logger.logNotEnoughDataError(accessor);
|
||||
return false;
|
||||
}
|
||||
this.stride = this.parseArray(offset,count,stride,array.array,array.type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.logger.logNotFoundError(arrayXML);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function numValidParams(params:XMLList) : int
|
||||
{
|
||||
var res:int = 0;
|
||||
for(var i:int = 0, count:int = int(params.length()); i < count; )
|
||||
{
|
||||
if(params[i].@name[0] != null)
|
||||
{
|
||||
res++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private function parseArray(offset:int, count:int, stride:int, array:Array, type:String) : int
|
||||
{
|
||||
var param:XML = null;
|
||||
var j:int = 0;
|
||||
var value:String = null;
|
||||
var params:XMLList = this.accessor.param;
|
||||
var arrStride:int = int(Math.max(this.numValidParams(params),stride));
|
||||
switch(type)
|
||||
{
|
||||
case this.name_XM:
|
||||
this.numbers = new Vector.<Number>(int(arrStride * count));
|
||||
break;
|
||||
case this.name_g6:
|
||||
this.name_op = new Vector.<int>(int(arrStride * count));
|
||||
break;
|
||||
case this.name_ZJ:
|
||||
this.names = new Vector.<String>(int(arrStride * count));
|
||||
}
|
||||
var curr:int = 0;
|
||||
for(var i:int = 0; i < arrStride; )
|
||||
{
|
||||
param = params[i];
|
||||
if(param == null || Boolean(param.hasOwnProperty("@name")))
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case this.name_XM:
|
||||
for(j = 0; j < count; j++)
|
||||
{
|
||||
value = array[int(offset + stride * j + i)];
|
||||
if(value.indexOf(",") != -1)
|
||||
{
|
||||
value = value.replace(/,/,".");
|
||||
}
|
||||
this.numbers[int(arrStride * j + curr)] = parseFloat(value);
|
||||
}
|
||||
break;
|
||||
case this.name_g6:
|
||||
for(j = 0; j < count; j++)
|
||||
{
|
||||
this.name_op[int(arrStride * j + curr)] = parseInt(array[int(offset + stride * j + i)],10);
|
||||
}
|
||||
break;
|
||||
case this.name_ZJ:
|
||||
for(j = 0; j < count; j++)
|
||||
{
|
||||
this.names[int(arrStride * j + curr)] = array[int(offset + stride * j + i)];
|
||||
}
|
||||
}
|
||||
curr++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return arrStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import flash.geom.Vector3D;
|
||||
|
||||
public class DaeVertex
|
||||
{
|
||||
public var name_Eq:int;
|
||||
|
||||
public var name_AR:int;
|
||||
|
||||
public var indices:Vector.<int> = new Vector.<int>();
|
||||
|
||||
public var x:Number;
|
||||
|
||||
public var y:Number;
|
||||
|
||||
public var z:Number;
|
||||
|
||||
public var uvs:Vector.<Number> = new Vector.<Number>();
|
||||
|
||||
public var normal:Vector3D;
|
||||
|
||||
public var name_hC:Vector3D;
|
||||
|
||||
public function DaeVertex()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function addPosition(data:Vector.<Number>, dataIndex:int, stride:int, unitScaleFactor:Number) : void
|
||||
{
|
||||
this.indices.push(dataIndex);
|
||||
var offset:int = stride * dataIndex;
|
||||
this.x = data[int(offset)] * unitScaleFactor;
|
||||
this.y = data[int(offset + 1)] * unitScaleFactor;
|
||||
this.z = data[int(offset + 2)] * unitScaleFactor;
|
||||
}
|
||||
|
||||
public function addNormal(data:Vector.<Number>, dataIndex:int, stride:int) : void
|
||||
{
|
||||
this.indices.push(dataIndex);
|
||||
var offset:int = stride * dataIndex;
|
||||
this.normal = new Vector3D();
|
||||
this.normal.x = data[int(offset++)];
|
||||
this.normal.y = data[int(offset++)];
|
||||
this.normal.z = data[offset];
|
||||
}
|
||||
|
||||
public function addTangentBiDirection(tangentData:Vector.<Number>, tangentDataIndex:int, tangentStride:int, biNormalData:Vector.<Number>, biNormalDataIndex:int, biNormalStride:int) : void
|
||||
{
|
||||
this.indices.push(tangentDataIndex);
|
||||
this.indices.push(biNormalDataIndex);
|
||||
var tangentOffset:int = tangentStride * tangentDataIndex;
|
||||
var biNormalOffset:int = biNormalStride * biNormalDataIndex;
|
||||
var biNormalX:Number = biNormalData[int(biNormalOffset++)];
|
||||
var biNormalY:Number = biNormalData[int(biNormalOffset++)];
|
||||
var biNormalZ:Number = biNormalData[biNormalOffset];
|
||||
this.name_hC = new Vector3D(tangentData[int(tangentOffset++)],tangentData[int(tangentOffset++)],tangentData[tangentOffset]);
|
||||
var crossX:Number = this.normal.y * this.name_hC.z - this.normal.z * this.name_hC.y;
|
||||
var crossY:Number = this.normal.z * this.name_hC.x - this.normal.x * this.name_hC.z;
|
||||
var crossZ:Number = this.normal.x * this.name_hC.y - this.normal.y * this.name_hC.x;
|
||||
var dot:Number = crossX * biNormalX + crossY * biNormalY + crossZ * biNormalZ;
|
||||
this.name_hC.w = dot < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
public function appendUV(data:Vector.<Number>, dataIndex:int, stride:int) : void
|
||||
{
|
||||
this.indices.push(dataIndex);
|
||||
this.uvs.push(data[int(dataIndex * stride)]);
|
||||
this.uvs.push(1 - data[int(dataIndex * stride + 1)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
|
||||
use namespace alternativa3d;
|
||||
use namespace collada;
|
||||
|
||||
public class DaeVertices extends DaeElement
|
||||
{
|
||||
public var name_E6:DaeSource;
|
||||
|
||||
public function DaeVertices(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
}
|
||||
|
||||
override protected function parseImplementation() : Boolean
|
||||
{
|
||||
var inputXML:XML = null;
|
||||
inputXML = data.input.(@semantic == "POSITION")[0];
|
||||
if(inputXML != null)
|
||||
{
|
||||
this.name_E6 = new DaeInput(inputXML,document).prepareSource(3);
|
||||
if(this.name_E6 != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
use namespace collada;
|
||||
|
||||
public class DaeVisualScene extends DaeElement
|
||||
{
|
||||
public var nodes:Vector.<DaeNode>;
|
||||
|
||||
public function DaeVisualScene(data:XML, document:DaeDocument)
|
||||
{
|
||||
super(data,document);
|
||||
this.constructNodes();
|
||||
}
|
||||
|
||||
public function constructNodes() : void
|
||||
{
|
||||
var node:DaeNode = null;
|
||||
var nodesList:XMLList = data.node;
|
||||
var count:int = int(nodesList.length());
|
||||
this.nodes = new Vector.<DaeNode>(count);
|
||||
for(var i:int = 0; i < count; i++)
|
||||
{
|
||||
node = new DaeNode(nodesList[i],document,this);
|
||||
if(node.id != null)
|
||||
{
|
||||
document.nodes[node.id] = node;
|
||||
}
|
||||
this.nodes[i] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package alternativa.engine3d.loaders.collada
|
||||
{
|
||||
public namespace collada = "http://www.collada.org/2005/11/COLLADASchema";
|
||||
}
|
||||
|
||||
@@ -1,387 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.materials.compiler.CommandType;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import avmplus.getQualifiedSuperclassName;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.display3D.Context3DTextureFormat;
|
||||
import flash.display3D.IndexBuffer3D;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.display3D.textures.Texture;
|
||||
import flash.geom.Point;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Endian;
|
||||
import flash.utils.getDefinitionByName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class A3DUtils
|
||||
{
|
||||
private static var twoOperandsCommands:Dictionary;
|
||||
|
||||
private static const DXT1:ByteArray = getDXT1();
|
||||
|
||||
private static const PVRTC:ByteArray = getPVRTC();
|
||||
|
||||
private static const ETC1:ByteArray = getETC1();
|
||||
|
||||
private static var programType:Vector.<String> = Vector.<String>(["VERTEX","FRAGMENT"]);
|
||||
|
||||
private static var samplerDimension:Vector.<String> = Vector.<String>(["2D","cube","3D"]);
|
||||
|
||||
private static var samplerWraping:Vector.<String> = Vector.<String>(["clamp","repeat"]);
|
||||
|
||||
private static var samplerMipmap:Vector.<String> = Vector.<String>(["mipnone","mipnearest","miplinear"]);
|
||||
|
||||
private static var samplerFilter:Vector.<String> = Vector.<String>(["nearest","linear"]);
|
||||
|
||||
private static var swizzleType:Vector.<String> = Vector.<String>(["x","y","z","w"]);
|
||||
|
||||
private static const O_CODE:uint = "o".charCodeAt(0);
|
||||
|
||||
public function A3DUtils()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private static function getDXT1() : ByteArray
|
||||
{
|
||||
var DXT1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,71,2,2,2,3,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
|
||||
return getData(DXT1Data);
|
||||
}
|
||||
|
||||
private static function getETC1() : ByteArray
|
||||
{
|
||||
var ETC1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,104,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208
|
||||
,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0]);
|
||||
return getData(ETC1Data);
|
||||
}
|
||||
|
||||
private static function getPVRTC() : ByteArray
|
||||
{
|
||||
var PVRTCData:Vector.<int> = Vector.<int>([65,84,70,0,2,173,2,2,2,3,0,0,0,0,0,0,0,0,13,0,0,0,16,0,0,0,104,190,153,255,0,0,0,0,15,91,0,0,16,0,0,102,12,228,2,255,225,0,0,0,0,0,223,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,132,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,165,192,0,7,227,99,186,53,197,40,185,134,182,32,130,98,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,143,192,120,64,6,16,34,52,192,196,65,132,90,98,68,16,17,68,60,91,8,48,76,35,192,97,132,71,76,33,164,97,1,2,194,12,19,8,240,29,132,24,38,17,224,48,194,35,166,16,210,48,128,128,24,68,121,132,52,204,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0
|
||||
,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0]);
|
||||
return getData(PVRTCData);
|
||||
}
|
||||
|
||||
private static function getData(source:Vector.<int>) : ByteArray
|
||||
{
|
||||
var result:ByteArray = new ByteArray();
|
||||
for(var i:int = 0, length:int = int(source.length); i < length; i++)
|
||||
{
|
||||
result.writeByte(source[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function getSizeFromATF(byteArray:ByteArray, size:Point) : void
|
||||
{
|
||||
byteArray.position = 7;
|
||||
var w:int = int(byteArray.readByte());
|
||||
var h:int = int(byteArray.readByte());
|
||||
size.x = 1 << w;
|
||||
size.y = 1 << h;
|
||||
byteArray.position = 0;
|
||||
}
|
||||
|
||||
public static function getSupportedTextureFormat(context3D:Context3D) : String
|
||||
{
|
||||
var testTexture:Texture = context3D.createTexture(4,4,Context3DTextureFormat.COMPRESSED,false);
|
||||
var result:String = TextureFormat.NONE;
|
||||
try
|
||||
{
|
||||
testTexture.uploadCompressedTextureFromByteArray(DXT1,0);
|
||||
result = TextureFormat.DXT1;
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
result = TextureFormat.NONE;
|
||||
}
|
||||
if(result == TextureFormat.NONE)
|
||||
{
|
||||
try
|
||||
{
|
||||
testTexture.uploadCompressedTextureFromByteArray(PVRTC,0);
|
||||
result = TextureFormat.PVRTC;
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
result = TextureFormat.NONE;
|
||||
}
|
||||
}
|
||||
if(result == TextureFormat.NONE)
|
||||
{
|
||||
try
|
||||
{
|
||||
testTexture.uploadCompressedTextureFromByteArray(ETC1,0);
|
||||
result = TextureFormat.ETC1;
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
result = TextureFormat.NONE;
|
||||
}
|
||||
}
|
||||
testTexture.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function vectorNumberToByteArray(vector:Vector.<Number>) : ByteArray
|
||||
{
|
||||
var result:ByteArray = new ByteArray();
|
||||
result.endian = Endian.LITTLE_ENDIAN;
|
||||
for(var i:int = 0; i < vector.length; i++)
|
||||
{
|
||||
result.writeFloat(vector[i]);
|
||||
}
|
||||
result.position = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function byteArrayToVectorUint(byteArray:ByteArray) : Vector.<uint>
|
||||
{
|
||||
var result:Vector.<uint> = new Vector.<uint>();
|
||||
var length:uint = 0;
|
||||
byteArray.position = 0;
|
||||
for(byteArray.endian = Endian.LITTLE_ENDIAN; byteArray.bytesAvailable > 0; )
|
||||
{
|
||||
var _loc4_:* = length++;
|
||||
result[_loc4_] = byteArray.readUnsignedShort();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function createVertexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numVertices:uint, stride:uint = 3) : VertexBuffer3D
|
||||
{
|
||||
if(context == null)
|
||||
{
|
||||
throw new ReferenceError("context is not set");
|
||||
}
|
||||
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices,stride);
|
||||
buffer.uploadFromByteArray(byteArray,0,0,numVertices);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static function createVertexBufferFromVector(context:Context3D, vector:Vector.<Number>, numVertices:uint, stride:uint = 3) : VertexBuffer3D
|
||||
{
|
||||
if(context == null)
|
||||
{
|
||||
throw new ReferenceError("context is not set");
|
||||
}
|
||||
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices,stride);
|
||||
var byteArray:ByteArray = A3DUtils.vectorNumberToByteArray(vector);
|
||||
buffer.uploadFromByteArray(byteArray,0,0,numVertices);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static function createTextureFromByteArray(context:Context3D, byteArray:ByteArray, width:Number, height:Number, format:String) : Texture
|
||||
{
|
||||
if(context == null)
|
||||
{
|
||||
throw new ReferenceError("context is not set");
|
||||
}
|
||||
var texture:Texture = context.createTexture(width,height,format,false);
|
||||
texture.uploadCompressedTextureFromByteArray(byteArray,0);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static function createIndexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numIndices:uint) : IndexBuffer3D
|
||||
{
|
||||
if(context == null)
|
||||
{
|
||||
throw new ReferenceError("context is not set");
|
||||
}
|
||||
var buffer:IndexBuffer3D = context.createIndexBuffer(numIndices);
|
||||
buffer.uploadFromByteArray(byteArray,0,0,numIndices);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static function createIndexBufferFromVector(context:Context3D, vector:Vector.<uint>, numIndices:int = -1) : IndexBuffer3D
|
||||
{
|
||||
if(context == null)
|
||||
{
|
||||
throw new ReferenceError("context is not set");
|
||||
}
|
||||
var count:uint = numIndices > 0 ? uint(numIndices) : uint(vector.length);
|
||||
var buffer:IndexBuffer3D = context.createIndexBuffer(count);
|
||||
buffer.uploadFromVector(vector,0,count);
|
||||
var byteArray:ByteArray = new ByteArray();
|
||||
byteArray.endian = Endian.LITTLE_ENDIAN;
|
||||
for(var i:int = 0; i < count; i++)
|
||||
{
|
||||
byteArray.writeInt(vector[i]);
|
||||
}
|
||||
byteArray.position = 0;
|
||||
buffer.uploadFromVector(vector,0,count);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static function disassemble(byteCode:ByteArray) : String
|
||||
{
|
||||
if(!twoOperandsCommands)
|
||||
{
|
||||
twoOperandsCommands = new Dictionary();
|
||||
twoOperandsCommands[1] = true;
|
||||
twoOperandsCommands[2] = true;
|
||||
twoOperandsCommands[3] = true;
|
||||
twoOperandsCommands[4] = true;
|
||||
twoOperandsCommands[6] = true;
|
||||
twoOperandsCommands[11] = true;
|
||||
twoOperandsCommands[17] = true;
|
||||
twoOperandsCommands[18] = true;
|
||||
twoOperandsCommands[19] = true;
|
||||
twoOperandsCommands[23] = true;
|
||||
twoOperandsCommands[24] = true;
|
||||
twoOperandsCommands[25] = true;
|
||||
twoOperandsCommands[40] = true;
|
||||
twoOperandsCommands[41] = true;
|
||||
twoOperandsCommands[42] = true;
|
||||
}
|
||||
var res:String = "";
|
||||
byteCode.position = 0;
|
||||
if(byteCode.bytesAvailable < 7)
|
||||
{
|
||||
return "error in byteCode header";
|
||||
}
|
||||
res += "magic = " + byteCode.readUnsignedByte().toString(16);
|
||||
res += "\nversion = " + byteCode.readInt().toString(10);
|
||||
res += "\nshadertypeid = " + byteCode.readUnsignedByte().toString(16);
|
||||
var pType:String = programType[byteCode.readByte()];
|
||||
res += "\nshadertype = " + pType;
|
||||
res += "\nsource\n";
|
||||
pType = pType.substring(0,1).toLowerCase();
|
||||
for(var lineNumber:uint = 1; byteCode.bytesAvailable - 24 >= 0; )
|
||||
{
|
||||
res += (lineNumber++).toString() + ": " + getCommand(byteCode,pType) + "\n";
|
||||
}
|
||||
if(byteCode.bytesAvailable > 0)
|
||||
{
|
||||
res += "\nunexpected byteCode length. extra bytes:" + byteCode.bytesAvailable;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static function getCommand(byteCode:ByteArray, programType:String) : String
|
||||
{
|
||||
var result:String = null;
|
||||
var cmd:uint = uint(byteCode.readUnsignedInt());
|
||||
var command:String = CommandType.COMMAND_NAMES[cmd];
|
||||
var destNumber:uint = uint(byteCode.readUnsignedShort());
|
||||
var swizzle:uint = uint(byteCode.readByte());
|
||||
var s:String = "";
|
||||
var destSwizzle:uint = 0;
|
||||
if(swizzle < 15)
|
||||
{
|
||||
s += ".";
|
||||
s += (swizzle & 1) > 0 ? "x" : "";
|
||||
s += (swizzle & 2) > 0 ? "y" : "";
|
||||
s += (swizzle & 4) > 0 ? "z" : "";
|
||||
s += (swizzle & 8) > 0 ? "w" : "";
|
||||
destSwizzle = uint(s.length);
|
||||
}
|
||||
var destType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
|
||||
if(destType.charCodeAt(0) == O_CODE)
|
||||
{
|
||||
result = command + " " + attachProgramPrefix(destType,programType) + s + ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = command + " " + attachProgramPrefix(destType,programType) + destNumber.toString() + s + ", ";
|
||||
}
|
||||
result += attachProgramPrefix(getSourceVariable(byteCode,destSwizzle),programType);
|
||||
if(Boolean(twoOperandsCommands[cmd]))
|
||||
{
|
||||
if(cmd == 40)
|
||||
{
|
||||
result += ", " + attachProgramPrefix(getSamplerVariable(byteCode),programType);
|
||||
}
|
||||
else
|
||||
{
|
||||
result += ", " + attachProgramPrefix(getSourceVariable(byteCode,destSwizzle),programType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byteCode.readDouble();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static function attachProgramPrefix(variable:String, programType:String) : String
|
||||
{
|
||||
var char:uint = uint(variable.charCodeAt(0));
|
||||
if(char == "o".charCodeAt(0))
|
||||
{
|
||||
return variable + (programType == "f" ? "c" : "p");
|
||||
}
|
||||
if(char != "v".charCodeAt(0))
|
||||
{
|
||||
return programType + variable;
|
||||
}
|
||||
return variable;
|
||||
}
|
||||
|
||||
private static function getSamplerVariable(byteCode:ByteArray) : String
|
||||
{
|
||||
var number:uint = uint(byteCode.readUnsignedInt());
|
||||
byteCode.readByte();
|
||||
var dim:uint = uint(byteCode.readByte() >> 4);
|
||||
var wraping:uint = uint(byteCode.readByte() >> 4);
|
||||
var n:uint = uint(byteCode.readByte());
|
||||
return "s" + number.toString() + " <" + samplerDimension[dim] + ", " + samplerWraping[wraping] + ", " + samplerFilter[n >> 4 & 0x0F] + ", " + samplerMipmap[n & 0x0F] + ">";
|
||||
}
|
||||
|
||||
private static function getSourceVariable(byteCode:ByteArray, destSwizzle:uint) : String
|
||||
{
|
||||
var s1Number:uint = uint(byteCode.readUnsignedShort());
|
||||
var offset:uint = uint(byteCode.readUnsignedByte());
|
||||
var s:String = getSourceSwizzle(byteCode.readUnsignedByte(),destSwizzle);
|
||||
var s1Type:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
|
||||
var indexType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
|
||||
var comp:String = swizzleType[byteCode.readUnsignedByte()];
|
||||
if(byteCode.readUnsignedByte() > 0)
|
||||
{
|
||||
return s1Type + "[" + indexType + s1Number.toString() + "." + comp + (offset > 0 ? "+" + offset.toString() : "") + "]" + s;
|
||||
}
|
||||
return s1Type + s1Number.toString() + s;
|
||||
}
|
||||
|
||||
private static function getSourceSwizzle(swizzle:uint, destSwizzle:uint) : String
|
||||
{
|
||||
var s:String = "";
|
||||
if(swizzle != 228)
|
||||
{
|
||||
s += ".";
|
||||
s += swizzleType[swizzle & 3];
|
||||
s += swizzleType[swizzle >> 2 & 3];
|
||||
s += swizzleType[swizzle >> 4 & 3];
|
||||
s += swizzleType[swizzle >> 6 & 3];
|
||||
s = s.substring(0,destSwizzle > 0 ? destSwizzle : Number(s.length));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
alternativa3d static function checkParent(child:Class, parent:Class) : Boolean
|
||||
{
|
||||
var className:String = null;
|
||||
var current:Class = child;
|
||||
if(parent == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
while(current != parent)
|
||||
{
|
||||
className = getQualifiedSuperclassName(current);
|
||||
if(className == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
current = getDefinitionByName(className) as Class;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,486 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.BitmapTextureResource;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.engine3d.resources.TextureResource;
|
||||
import avmplus.getQualifiedClassName;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class EnviromentMaterial extends TextureMaterial
|
||||
{
|
||||
alternativa3d static var fogTexture:TextureResource;
|
||||
|
||||
private static var _programs:Dictionary = new Dictionary();
|
||||
|
||||
alternativa3d static const DISABLED:int = 0;
|
||||
|
||||
alternativa3d static const SIMPLE:int = 1;
|
||||
|
||||
alternativa3d static const ADVANCED:int = 2;
|
||||
|
||||
alternativa3d static var fogMode:int = alternativa3d::DISABLED;
|
||||
|
||||
alternativa3d static var fogNear:Number = 1000;
|
||||
|
||||
alternativa3d static var fogFar:Number = 5000;
|
||||
|
||||
alternativa3d static var fogMaxDensity:Number = 1;
|
||||
|
||||
alternativa3d static var fogColorR:Number = 200 / 255;
|
||||
|
||||
alternativa3d static var fogColorG:Number = 162 / 255;
|
||||
|
||||
alternativa3d static var fogColorB:Number = 200 / 255;
|
||||
|
||||
alternativa3d static const _passReflectionProcedure:Procedure = new Procedure(["#v1=vNormal","#v0=vPosition","mov v0, i0","mov v1, i1"],"passReflectionProcedure");
|
||||
|
||||
alternativa3d static const _applyReflectionProcedure:Procedure = new Procedure(["#v1=vNormal","#v0=vPosition","#s0=sCubeMap","#c0=cCamera","sub t0, v0, c0","dp3 t1.x, v1, t0","add t1.x, t1.x, t1.x","mul t1, v1, t1.x","sub t1, t0, t1","nrm t1.xyz, t1.xyz","tex o0, t1, s0 <cube,clamp,linear,nomip>"],"applyReflectionProcedure");
|
||||
|
||||
alternativa3d static const _applyReflectionNormalMapProcedure:Procedure = new Procedure(["#s0=sCubeMap","#c0=cCamera","#v0=vPosition","sub t0, v0, c0","dp3 t1.x, i0.xyz, t0","add t1.x, t1.x, t1.x","mul t1, i0.xyz, t1.x","sub t1, t0, t1","nrm t1.xyz, t1.xyz","tex o0, t1, s0 <cube,clamp,linear,nomip>"],"applyReflectionNormalMapProcedure");
|
||||
|
||||
alternativa3d static const _blendReflection:Procedure = new Procedure(["#c0=cAlpha","mul t1, i0, c0.y","mul t0.xyz, i1, c0.z","add t0.xyz, t1, t0","mov t0.w, i0.w","mov o0, t0"],"blendReflection");
|
||||
|
||||
alternativa3d static const _blendReflectionMap:Procedure = new Procedure(["#c0=cCamera","#c1=cAlpha","#s0=sReflection","#v0=vUV","tex t0, v0, s0 <2d,repeat,linear,miplinear>","mul t0, t0, c1.z","mul t1.xyz, i1, t0","sub t0, c0.www, t0","mul t2, i0, t0","add t0.xyz, t1, t2","mov t0.w, i0.w","mov o0, t0"],"blendReflectionMap");
|
||||
|
||||
private static const _passTBNRightProcedure:Procedure = getPassTBNProcedure(true);
|
||||
|
||||
private static const _passTBNLeftProcedure:Procedure = getPassTBNProcedure(false);
|
||||
|
||||
private static const _getNormalTangentProcedure:Procedure = new Procedure(["#v0=vTangent","#v1=vBinormal","#v2=vNormal","#v3=vUV","#c0=cCamera","#s0=sBump","tex t0, v3, s0 <2d,repeat,linear,miplinear>","add t0, t0, t0","sub t0.xyz, t0.xyz, c0.www","nrm t1.xyz, v0.xyz","dp3 o0.x, t0.xyz, t1.xyz","nrm t1.xyz, v1.xyz","dp3 o0.y, t0.xyz, t1.xyz","nrm t1.xyz, v2.xyz","dp3 o0.z, t0.xyz, t1.xyz","nrm o0.xyz, o0.xyz"],"getNormalTangentProcedure");
|
||||
|
||||
private static const _getNormalObjectProcedure:Procedure = new Procedure(["#v3=vUV","#c0=cCamera","#s0=sBump","tex t0, v3, s0 <2d,repeat,linear,miplinear>","add t0, t0, t0","sub t0.xyz, t0.xyz, c0.www","nrm o0.xyz, t0.xyz"],"getNormalObjectProcedure");
|
||||
|
||||
private static const passSimpleFogConstProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogSpace","dp4 t0.z, i0, c0","mov v0, t0.zzzz","sub v0.y, i0.w, t0.z"],"passSimpleFogConst");
|
||||
|
||||
private static const outputWithSimpleFogProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogColor","#c1=cFogRange","min t0.xy, v0.xy, c1.xy","max t0.xy, t0.xy, c1.zw","mul i0.xyz, i0.xyz, t0.y","mul t0.xyz, c0.xyz, t0.x","add i0.xyz, i0.xyz, t0.xyz","mov o0, i0"],"outputWithSimpleFog");
|
||||
|
||||
private static const postPassAdvancedFogConstProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogSpace","dp4 t0.z, i0, c0","mov v0, t0.zzzz","sub v0.y, i0.w, t0.z","mov v0.zw, i1.xwxw","mov o0, i1"],"postPassAdvancedFogConst");
|
||||
|
||||
private static const outputWithAdvancedFogProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogConsts","#c1=cFogRange","#s0=sFogTexture","min t0.xy, v0.xy, c1.xy","max t0.xy, t0.xy, c1.zw","mul i0.xyz, i0.xyz, t0.y","mov t1.xyzw, c0.yyzw","div t0.z, v0.z, v0.w","mul t0.z, t0.z, c0.x","add t1.x, t1.x, t0.z","tex t1, t1, s0 <2d, repeat, linear, miplinear>","mul t0.xyz, t1.xyz, t0.x","add i0.xyz, i0.xyz, t0.xyz","mov o0, i0"],"outputWithAdvancedFog");
|
||||
|
||||
private static const _applyLightMapProcedure:Procedure = new Procedure(["#v0=vUV1","#s0=sLightMap","tex t0, v0, s0 <2d,repeat,linear,mipnone>","add t0, t0, t0","mul i0.xyz, i0.xyz, t0.xyz","mov o0, i0"],"applyLightMapProcedure");
|
||||
|
||||
private static const _passLightMapUVProcedure:Procedure = new Procedure(["#a0=aUV1","#v0=vUV1","mov v0, a0"],"passLightMapUVProcedure");
|
||||
|
||||
private var name_NH:int = 0;
|
||||
|
||||
public var normalMap:TextureResource;
|
||||
|
||||
public var environmentMap:TextureResource;
|
||||
|
||||
public var reflection:Number = 1;
|
||||
|
||||
public var reflectionMap:TextureResource;
|
||||
|
||||
public var lightMap:TextureResource;
|
||||
|
||||
public var lightMapChannel:uint = 1;
|
||||
|
||||
public function EnviromentMaterial(diffuseMap:TextureResource = null, environmentMap:TextureResource = null, normalMap:TextureResource = null, reflectionMap:TextureResource = null, lightMap:TextureResource = null, opacityMap:TextureResource = null, alpha:Number = 1)
|
||||
{
|
||||
super(diffuseMap,opacityMap,alpha);
|
||||
this.environmentMap = environmentMap;
|
||||
this.normalMap = normalMap;
|
||||
this.reflectionMap = reflectionMap;
|
||||
this.lightMap = lightMap;
|
||||
}
|
||||
|
||||
private static function getPassTBNProcedure(right:Boolean) : Procedure
|
||||
{
|
||||
var crsInSpace:String = right ? "crs t1.xyz, i0, i1" : "crs t1.xyz, i1, i0";
|
||||
return new Procedure(["#v0=vTangent","#v1=vBinormal","#v2=vNormal",crsInSpace,"mul t1.xyz, t1.xyz, i0.w","mov v0.x, i0.x","mov v0.y, t1.x","mov v0.z, i1.x","mov v0.w, i1.w","mov v1.x, i0.y","mov v1.y, t1.y","mov v1.z, i1.y","mov v1.w, i1.w","mov v2.x, i0.z","mov v2.y, t1.z","mov v2.z, i1.z","mov v2.w, i1.w"],"passTBNProcedure");
|
||||
}
|
||||
|
||||
public function get normalMapSpace() : int
|
||||
{
|
||||
return this.name_NH;
|
||||
}
|
||||
|
||||
public function set normalMapSpace(value:int) : void
|
||||
{
|
||||
if(value != NormalMapSpace.TANGENT_RIGHT_HANDED && value != NormalMapSpace.TANGENT_LEFT_HANDED && value != NormalMapSpace.OBJECT)
|
||||
{
|
||||
throw new ArgumentError("Value must be a constant from the NormalMapSpace class");
|
||||
}
|
||||
this.name_NH = value;
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, resourceType:Class) : void
|
||||
{
|
||||
super.alternativa3d::fillResources(resources,resourceType);
|
||||
if(this.environmentMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.environmentMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.environmentMap] = true;
|
||||
}
|
||||
if(this.normalMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.normalMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.normalMap] = true;
|
||||
}
|
||||
if(this.reflectionMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.reflectionMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.reflectionMap] = true;
|
||||
}
|
||||
if(this.lightMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.lightMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.lightMap] = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function final(targetObject:Object3D) : EnvironmentMaterialShaderProgram
|
||||
{
|
||||
var procedure:Procedure = null;
|
||||
var outputProcedure:Procedure = null;
|
||||
var nrmProcedure:Procedure = null;
|
||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||
var positionVar:String = "aPosition";
|
||||
var normalVar:String = "aNormal";
|
||||
var tangentVar:String = "aTangent";
|
||||
vertexLinker.declareVariable(positionVar,VariableType.ATTRIBUTE);
|
||||
vertexLinker.declareVariable(normalVar,VariableType.ATTRIBUTE);
|
||||
if(targetObject.alternativa3d::transformProcedure != null)
|
||||
{
|
||||
positionVar = alternativa3d::appendPositionTransformProcedure(targetObject.alternativa3d::transformProcedure,vertexLinker);
|
||||
}
|
||||
if(targetObject.alternativa3d::deltaTransformProcedure != null)
|
||||
{
|
||||
vertexLinker.declareVariable("tTransformedNormal");
|
||||
procedure = targetObject.alternativa3d::deltaTransformProcedure.newInstance();
|
||||
vertexLinker.addProcedure(procedure);
|
||||
vertexLinker.setInputParams(procedure,normalVar);
|
||||
vertexLinker.setOutputParams(procedure,"tTransformedNormal");
|
||||
normalVar = "tTransformedNormal";
|
||||
if((this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED) && this.normalMap != null)
|
||||
{
|
||||
vertexLinker.declareVariable(tangentVar,VariableType.ATTRIBUTE);
|
||||
vertexLinker.declareVariable("tTransformedTangent");
|
||||
procedure = targetObject.alternativa3d::deltaTransformProcedure.newInstance();
|
||||
vertexLinker.addProcedure(procedure);
|
||||
vertexLinker.setInputParams(procedure,tangentVar);
|
||||
vertexLinker.setOutputParams(procedure,"tTransformedTangent");
|
||||
tangentVar = "tTransformedTangent";
|
||||
}
|
||||
}
|
||||
else if((this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED) && this.normalMap != null)
|
||||
{
|
||||
vertexLinker.declareVariable(tangentVar,VariableType.ATTRIBUTE);
|
||||
}
|
||||
vertexLinker.addProcedure(_passLightMapUVProcedure);
|
||||
vertexLinker.addProcedure(alternativa3d::_passReflectionProcedure);
|
||||
vertexLinker.setInputParams(alternativa3d::_passReflectionProcedure,positionVar,normalVar);
|
||||
vertexLinker.addProcedure(alternativa3d::_projectProcedure);
|
||||
vertexLinker.setInputParams(alternativa3d::_projectProcedure,positionVar);
|
||||
vertexLinker.addProcedure(alternativa3d::_passUVProcedure);
|
||||
if(this.normalMap != null)
|
||||
{
|
||||
fragmentLinker.declareVariable("tNormal");
|
||||
if(this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED)
|
||||
{
|
||||
nrmProcedure = this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED ? _passTBNRightProcedure : _passTBNLeftProcedure;
|
||||
vertexLinker.addProcedure(nrmProcedure);
|
||||
vertexLinker.setInputParams(nrmProcedure,tangentVar,normalVar);
|
||||
fragmentLinker.addProcedure(_getNormalTangentProcedure);
|
||||
fragmentLinker.setOutputParams(_getNormalTangentProcedure,"tNormal");
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(_getNormalObjectProcedure);
|
||||
fragmentLinker.setOutputParams(_getNormalObjectProcedure,"tNormal");
|
||||
}
|
||||
}
|
||||
vertexLinker.link();
|
||||
fragmentLinker.declareVariable("tColor");
|
||||
if(name_L4)
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_samplerSetProcedureDiffuseAlpha);
|
||||
fragmentLinker.setOutputParams(alternativa3d::_samplerSetProcedureDiffuseAlpha,"tColor");
|
||||
}
|
||||
else if(opacityMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_samplerSetProcedureOpacity);
|
||||
fragmentLinker.setOutputParams(alternativa3d::_samplerSetProcedureOpacity,"tColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_samplerSetProcedure);
|
||||
fragmentLinker.setOutputParams(alternativa3d::_samplerSetProcedure,"tColor");
|
||||
}
|
||||
fragmentLinker.declareVariable("tReflection");
|
||||
if(this.normalMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_applyReflectionNormalMapProcedure);
|
||||
fragmentLinker.setInputParams(alternativa3d::_applyReflectionNormalMapProcedure,"tNormal");
|
||||
fragmentLinker.setOutputParams(alternativa3d::_applyReflectionNormalMapProcedure,"tReflection");
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_applyReflectionProcedure);
|
||||
fragmentLinker.setOutputParams(alternativa3d::_applyReflectionProcedure,"tReflection");
|
||||
}
|
||||
fragmentLinker.addProcedure(_applyLightMapProcedure);
|
||||
fragmentLinker.setInputParams(_applyLightMapProcedure,"tColor");
|
||||
fragmentLinker.setOutputParams(_applyLightMapProcedure,"tColor");
|
||||
if(this.reflectionMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_blendReflectionMap);
|
||||
fragmentLinker.setInputParams(alternativa3d::_blendReflectionMap,"tColor","tReflection");
|
||||
outputProcedure = alternativa3d::_blendReflectionMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(alternativa3d::_blendReflection);
|
||||
fragmentLinker.setInputParams(alternativa3d::_blendReflection,"tColor","tReflection");
|
||||
outputProcedure = alternativa3d::_blendReflection;
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE || alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
fragmentLinker.declareVariable("outColor");
|
||||
fragmentLinker.setOutputParams(outputProcedure,"outColor");
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE)
|
||||
{
|
||||
vertexLinker.addProcedure(passSimpleFogConstProcedure);
|
||||
vertexLinker.setInputParams(passSimpleFogConstProcedure,positionVar);
|
||||
fragmentLinker.addProcedure(outputWithSimpleFogProcedure);
|
||||
fragmentLinker.setInputParams(outputWithSimpleFogProcedure,"outColor");
|
||||
}
|
||||
else if(alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
vertexLinker.declareVariable("tProjected");
|
||||
vertexLinker.setOutputParams(alternativa3d::_projectProcedure,"tProjected");
|
||||
vertexLinker.addProcedure(postPassAdvancedFogConstProcedure);
|
||||
vertexLinker.setInputParams(postPassAdvancedFogConstProcedure,positionVar,"tProjected");
|
||||
fragmentLinker.addProcedure(outputWithAdvancedFogProcedure);
|
||||
fragmentLinker.setInputParams(outputWithAdvancedFogProcedure,"outColor");
|
||||
}
|
||||
fragmentLinker.link();
|
||||
fragmentLinker.setOppositeLinker(vertexLinker);
|
||||
return new EnvironmentMaterialShaderProgram(vertexLinker,fragmentLinker);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
var program:ShaderProgram = null;
|
||||
var i:int = 0;
|
||||
var lm:Transform3D = null;
|
||||
var dist:Number = NaN;
|
||||
var cLocal:Transform3D = null;
|
||||
var halfW:Number = NaN;
|
||||
var leftX:Number = NaN;
|
||||
var leftY:Number = NaN;
|
||||
var rightX:Number = NaN;
|
||||
var rightY:Number = NaN;
|
||||
var angle:Number = NaN;
|
||||
var dx:Number = NaN;
|
||||
var dy:Number = NaN;
|
||||
var lens:Number = NaN;
|
||||
var uScale:Number = NaN;
|
||||
var uRight:Number = NaN;
|
||||
var bmd:BitmapData = null;
|
||||
if(diffuseMap == null || this.environmentMap == null || diffuseMap.alternativa3d::_texture == null || this.environmentMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!name_L4 && opacityMap != null && opacityMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var object:Object3D = surface.alternativa3d::object;
|
||||
var positionBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.POSITION);
|
||||
var uvBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||
var normalsBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.NORMAL);
|
||||
var tangentsBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.TANGENT4);
|
||||
if(positionBuffer == null || uvBuffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var key:String = alternativa3d::fogMode.toString() + this.name_NH.toString() + (this.normalMap != null ? "N" : "n") + (opacityMap != null ? "O" : "o") + (name_L4 ? "D" : "d");
|
||||
var programs:Dictionary = _programs[object.alternativa3d::transformProcedure];
|
||||
if(programs == null)
|
||||
{
|
||||
programs = new Dictionary(false);
|
||||
_programs[object.alternativa3d::transformProcedure] = programs;
|
||||
program = this.final(object);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
programs[key] = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
program = programs[key];
|
||||
if(program == null)
|
||||
{
|
||||
program = this.final(object);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
programs[key] = program;
|
||||
}
|
||||
}
|
||||
var drawUnit:DrawUnit = camera.alternativa3d::renderer.alternativa3d::createDrawUnit(object,program.program,geometry.name_EM,surface.indexBegin,surface.numTriangles,program);
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sLightMap"),this.lightMap.alternativa3d::_texture);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"),positionBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.POSITION],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.POSITION]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"),uvBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TEXCOORDS[0]],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aUV1"),uvBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TEXCOORDS[this.lightMapChannel]],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TEXCOORDS[this.lightMapChannel]]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aNormal"),normalsBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.NORMAL],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.NORMAL]);
|
||||
object.alternativa3d::setTransformConstants(drawUnit,surface,program.vertexShader,camera);
|
||||
drawUnit.alternativa3d::setProjectionConstants(camera,program.vertexShader.getVariableIndex("cProjMatrix"),object.alternativa3d::localToCameraTransform);
|
||||
var camTransform:Transform3D = object.alternativa3d::cameraToLocalTransform;
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cCamera"),camTransform.d,camTransform.h,camTransform.l);
|
||||
var envProgram:EnvironmentMaterialShaderProgram = program as EnvironmentMaterialShaderProgram;
|
||||
if(this.normalMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(envProgram.sBump,this.normalMap.alternativa3d::_texture);
|
||||
if(this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED)
|
||||
{
|
||||
drawUnit.alternativa3d::setVertexBufferAt(envProgram.aTangent,tangentsBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TANGENT4],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TANGENT4]);
|
||||
}
|
||||
}
|
||||
if(this.reflectionMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(envProgram.sReflection,this.reflectionMap.alternativa3d::_texture);
|
||||
}
|
||||
drawUnit.alternativa3d::setTextureAt(envProgram.sTexture,diffuseMap.alternativa3d::_texture);
|
||||
drawUnit.alternativa3d::setTextureAt(envProgram.sCubeMap,this.environmentMap.alternativa3d::_texture);
|
||||
var cameraToLocalTransform:Transform3D = object.alternativa3d::cameraToLocalTransform;
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(envProgram.cCamera,cameraToLocalTransform.d,cameraToLocalTransform.h,cameraToLocalTransform.l);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(envProgram.cAlpha,0,1 - this.reflection,this.reflection,alpha);
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sTexture"),diffuseMap.alternativa3d::_texture);
|
||||
if(!name_L4 && opacityMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"),opacityMap.alternativa3d::_texture);
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE || alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
lm = object.alternativa3d::localToCameraTransform;
|
||||
dist = alternativa3d::fogFar - alternativa3d::fogNear;
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(program.vertexShader.getVariableIndex("cFogSpace"),lm.i / dist,lm.j / dist,lm.k / dist,(lm.l - alternativa3d::fogNear) / dist);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogRange"),alternativa3d::fogMaxDensity,1,0,1 - alternativa3d::fogMaxDensity);
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE)
|
||||
{
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogColor"),alternativa3d::fogColorR,alternativa3d::fogColorG,alternativa3d::fogColorB);
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
if(alternativa3d::fogTexture == null)
|
||||
{
|
||||
bmd = new BitmapData(32,1,false,16711680);
|
||||
for(i = 0; i < 32; i++)
|
||||
{
|
||||
bmd.setPixel(i,0,i / 32 * 255 << 16);
|
||||
}
|
||||
alternativa3d::fogTexture = new BitmapTextureResource(bmd);
|
||||
alternativa3d::fogTexture.upload(camera.alternativa3d::context3D);
|
||||
}
|
||||
cLocal = camera.alternativa3d::localToGlobalTransform;
|
||||
halfW = camera.view.width / 2;
|
||||
leftX = -halfW * cLocal.a + camera.alternativa3d::focalLength * cLocal.c;
|
||||
leftY = -halfW * cLocal.e + camera.alternativa3d::focalLength * cLocal.g;
|
||||
rightX = halfW * cLocal.a + camera.alternativa3d::focalLength * cLocal.c;
|
||||
rightY = halfW * cLocal.e + camera.alternativa3d::focalLength * cLocal.g;
|
||||
angle = Math.atan2(leftY,leftX) - Math.PI / 2;
|
||||
if(angle < 0)
|
||||
{
|
||||
angle += Math.PI * 2;
|
||||
}
|
||||
dx = rightX - leftX;
|
||||
dy = rightY - leftY;
|
||||
lens = Number(Math.sqrt(dx * dx + dy * dy));
|
||||
leftX /= lens;
|
||||
leftY /= lens;
|
||||
rightX /= lens;
|
||||
rightY /= lens;
|
||||
uScale = Math.acos(leftX * rightX + leftY * rightY) / Math.PI / 2;
|
||||
uRight = angle / Math.PI / 2;
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogConsts"),0.5 * uScale,0.5 - uRight,0);
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sFogTexture"),alternativa3d::fogTexture.alternativa3d::_texture);
|
||||
}
|
||||
if(name_L4 || opacityMap != null || alpha < 1)
|
||||
{
|
||||
drawUnit.alternativa3d::blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
||||
drawUnit.alternativa3d::blendDestination = Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA;
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.TRANSPARENT_SORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.OPAQUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.ShaderProgram;
|
||||
|
||||
class EnvironmentMaterialShaderProgram extends ShaderProgram
|
||||
{
|
||||
public var aTangent:int = -1;
|
||||
|
||||
public var aNormal:int = -1;
|
||||
|
||||
public var aPosition:int = -1;
|
||||
|
||||
public var aUV:int = -1;
|
||||
|
||||
public var cCamera:int = -1;
|
||||
|
||||
public var cAlpha:int = -1;
|
||||
|
||||
public var cProjMatrix:int = -1;
|
||||
|
||||
public var sBump:int = -1;
|
||||
|
||||
public var sTexture:int = -1;
|
||||
|
||||
public var sOpacity:int = -1;
|
||||
|
||||
public var sCubeMap:int = -1;
|
||||
|
||||
public var sReflection:int = -1;
|
||||
|
||||
public function EnvironmentMaterialShaderProgram(vertexShader:Linker, fragmentShader:Linker)
|
||||
{
|
||||
super(vertexShader,fragmentShader);
|
||||
this.aPosition = vertexShader.getVariableIndex("aPosition");
|
||||
this.aNormal = vertexShader.getVariableIndex("aNormal");
|
||||
this.aUV = vertexShader.getVariableIndex("aUV");
|
||||
if(fragmentShader.containsVariable("sBump"))
|
||||
{
|
||||
this.sBump = fragmentShader.getVariableIndex("sBump");
|
||||
}
|
||||
if(vertexShader.containsVariable("aTangent"))
|
||||
{
|
||||
this.aTangent = vertexShader.getVariableIndex("aTangent");
|
||||
}
|
||||
if(fragmentShader.containsVariable("sReflection"))
|
||||
{
|
||||
this.sReflection = fragmentShader.getVariableIndex("sReflection");
|
||||
}
|
||||
this.cProjMatrix = vertexShader.getVariableIndex("cProjMatrix");
|
||||
this.sTexture = fragmentShader.getVariableIndex("sTexture");
|
||||
this.sCubeMap = fragmentShader.getVariableIndex("sCubeMap");
|
||||
this.cCamera = fragmentShader.getVariableIndex("cCamera");
|
||||
this.cAlpha = fragmentShader.getVariableIndex("cAlpha");
|
||||
if(fragmentShader.containsVariable("sOpacity"))
|
||||
{
|
||||
this.sOpacity = fragmentShader.getVariableIndex("sOpacity");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class FillMaterial extends Material
|
||||
{
|
||||
private static var outColorProcedure:Procedure = new Procedure(["#c0=cColor","mov o0, c0"],"outColorProcedure");
|
||||
|
||||
private static var _programs:Dictionary = new Dictionary();
|
||||
|
||||
public var alpha:Number = 1;
|
||||
|
||||
private var red:Number;
|
||||
|
||||
private var green:Number;
|
||||
|
||||
private var blue:Number;
|
||||
|
||||
public function FillMaterial(color:uint = 8355711, alpha:Number = 1)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
this.alpha = alpha;
|
||||
alternativa3d::priority = 1;
|
||||
}
|
||||
|
||||
public function get color() : uint
|
||||
{
|
||||
return (this.red * 255 << 16) + (this.green * 255 << 8) + this.blue * 255;
|
||||
}
|
||||
|
||||
public function set color(value:uint) : void
|
||||
{
|
||||
this.red = (value >> 16 & 0xFF) / 255;
|
||||
this.green = (value >> 8 & 0xFF) / 255;
|
||||
this.blue = (value & 0xFF) / 255;
|
||||
}
|
||||
|
||||
private function final(object:Object3D) : ShaderProgram
|
||||
{
|
||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||
var positionVar:String = "aPosition";
|
||||
vertexLinker.declareVariable(positionVar,VariableType.ATTRIBUTE);
|
||||
if(object.alternativa3d::transformProcedure != null)
|
||||
{
|
||||
positionVar = alternativa3d::appendPositionTransformProcedure(object.alternativa3d::transformProcedure,vertexLinker);
|
||||
}
|
||||
vertexLinker.addProcedure(alternativa3d::_projectProcedure);
|
||||
vertexLinker.setInputParams(alternativa3d::_projectProcedure,positionVar);
|
||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||
fragmentLinker.addProcedure(outColorProcedure);
|
||||
fragmentLinker.setOppositeLinker(vertexLinker);
|
||||
return new ShaderProgram(vertexLinker,fragmentLinker);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
var object:Object3D = surface.alternativa3d::object;
|
||||
var positionBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.POSITION);
|
||||
if(positionBuffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var program:ShaderProgram = _programs[object.alternativa3d::transformProcedure];
|
||||
if(program == null)
|
||||
{
|
||||
program = this.final(object);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
_programs[object.alternativa3d::transformProcedure] = program;
|
||||
}
|
||||
var drawUnit:DrawUnit = camera.alternativa3d::renderer.alternativa3d::createDrawUnit(object,program.program,geometry.name_EM,surface.indexBegin,surface.numTriangles,program);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"),positionBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.POSITION],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.POSITION]);
|
||||
object.alternativa3d::setTransformConstants(drawUnit,surface,program.vertexShader,camera);
|
||||
drawUnit.alternativa3d::setProjectionConstants(camera,program.vertexShader.getVariableIndex("cProjMatrix"),object.alternativa3d::localToCameraTransform);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cColor"),this.red,this.green,this.blue,this.alpha);
|
||||
if(this.alpha < 1)
|
||||
{
|
||||
drawUnit.alternativa3d::blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
||||
drawUnit.alternativa3d::blendDestination = Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA;
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.TRANSPARENT_SORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.OPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Material
|
||||
{
|
||||
var res:FillMaterial = new FillMaterial(this.color,this.alpha);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
public class FogMode
|
||||
{
|
||||
public static const DISABLED:int = 0;
|
||||
|
||||
public static const SIMPLE:int = 1;
|
||||
|
||||
public static const ADVANCED:int = 2;
|
||||
|
||||
public function FogMode()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Resource;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Material
|
||||
{
|
||||
alternativa3d static const _projectProcedure:Procedure = getPojectProcedure();
|
||||
|
||||
public var name:String;
|
||||
|
||||
alternativa3d var priority:int = 0;
|
||||
|
||||
public function Material()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private static function getPojectProcedure() : Procedure
|
||||
{
|
||||
var res:Procedure = new Procedure(["m44 o0, i0, c0"],"projectProcedure");
|
||||
res.assignVariableName(VariableType.CONSTANT,0,"cProjMatrix",4);
|
||||
return res;
|
||||
}
|
||||
|
||||
alternativa3d function get canDrawInShadowMap() : Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
alternativa3d function appendPositionTransformProcedure(transformProcedure:Procedure, vertexShader:Linker) : String
|
||||
{
|
||||
vertexShader.declareVariable("tTransformedPosition");
|
||||
vertexShader.addProcedure(transformProcedure);
|
||||
vertexShader.setInputParams(transformProcedure,"aPosition");
|
||||
vertexShader.setOutputParams(transformProcedure,"tTransformedPosition");
|
||||
return "tTransformedPosition";
|
||||
}
|
||||
|
||||
public function getResources(resourceType:Class = null) : Vector.<Resource>
|
||||
{
|
||||
var key:* = undefined;
|
||||
var res:Vector.<Resource> = new Vector.<Resource>();
|
||||
var dict:Dictionary = new Dictionary();
|
||||
var count:int = 0;
|
||||
this.alternativa3d::fillResources(dict,resourceType);
|
||||
for(key in dict)
|
||||
{
|
||||
var _loc8_:* = count++;
|
||||
res[_loc8_] = key as Resource;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
alternativa3d function fillResources(resources:Dictionary, resourceType:Class) : void
|
||||
{
|
||||
}
|
||||
|
||||
alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
}
|
||||
|
||||
public function clone() : Material
|
||||
{
|
||||
var res:Material = new Material();
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
protected function clonePropertiesFrom(source:Material) : void
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
public class NormalMapSpace
|
||||
{
|
||||
public static const TANGENT_RIGHT_HANDED:int = 0;
|
||||
|
||||
public static const TANGENT_LEFT_HANDED:int = 1;
|
||||
|
||||
public static const OBJECT:int = 2;
|
||||
|
||||
public function NormalMapSpace()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.display3D.Program3D;
|
||||
|
||||
public class ShaderProgram
|
||||
{
|
||||
public var program:Program3D;
|
||||
|
||||
public var vertexShader:Linker;
|
||||
|
||||
public var fragmentShader:Linker;
|
||||
|
||||
public function ShaderProgram(vertexShader:Linker, fragmentShader:Linker)
|
||||
{
|
||||
super();
|
||||
this.vertexShader = vertexShader;
|
||||
this.fragmentShader = fragmentShader;
|
||||
}
|
||||
|
||||
public function upload(context3D:Context3D) : void
|
||||
{
|
||||
if(this.program != null)
|
||||
{
|
||||
this.program.dispose();
|
||||
}
|
||||
if(this.vertexShader != null && this.fragmentShader != null)
|
||||
{
|
||||
this.program = context3D.createProgram();
|
||||
try
|
||||
{
|
||||
this.program.upload(this.vertexShader.getByteCode(),this.fragmentShader.getByteCode());
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
trace(A3DUtils.disassemble(fragmentShader.getByteCode()));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.program = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function dispose() : void
|
||||
{
|
||||
if(this.program != null)
|
||||
{
|
||||
this.program.dispose();
|
||||
this.program = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,590 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.lights.DirectionalLight;
|
||||
import alternativa.engine3d.lights.OmniLight;
|
||||
import alternativa.engine3d.lights.SpotLight;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.BitmapTextureResource;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.engine3d.resources.TextureResource;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
import flash.utils.getQualifiedClassName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class StandardMaterial extends TextureMaterial
|
||||
{
|
||||
alternativa3d static var fogTexture:TextureResource;
|
||||
|
||||
alternativa3d static const DISABLED:int = 0;
|
||||
|
||||
alternativa3d static const SIMPLE:int = 1;
|
||||
|
||||
alternativa3d static const ADVANCED:int = 2;
|
||||
|
||||
alternativa3d static var fogMode:int = alternativa3d::DISABLED;
|
||||
|
||||
alternativa3d static var fogNear:Number = 1000;
|
||||
|
||||
alternativa3d static var fogFar:Number = 5000;
|
||||
|
||||
alternativa3d static var fogMaxDensity:Number = 1;
|
||||
|
||||
alternativa3d static var fogColorR:Number = 200 / 255;
|
||||
|
||||
alternativa3d static var fogColorG:Number = 162 / 255;
|
||||
|
||||
alternativa3d static var fogColorB:Number = 200 / 255;
|
||||
|
||||
private static const _programs:Dictionary = new Dictionary();
|
||||
|
||||
private static const _lightFragmentProcedures:Dictionary = new Dictionary();
|
||||
|
||||
private static const _passVaryingsProcedure:Procedure = new Procedure(["#v0=vPosition","#v1=vViewVector","#c0=cCameraPosition","mov v0, i0","sub t0, c0, i0","mov v1.xyz, t0.xyz","mov v1.w, c0.w"]);
|
||||
|
||||
private static const _passTBNRightProcedure:Procedure = getPassTBNProcedure(true);
|
||||
|
||||
private static const _passTBNLeftProcedure:Procedure = getPassTBNProcedure(false);
|
||||
|
||||
private static const _ambientLightProcedure:Procedure = new Procedure(["#c0=cSurface","mov o0, i0","mov o1, c0.xxxx"],"ambientLightProcedure");
|
||||
|
||||
private static const _setGlossinessFromConstantProcedure:Procedure = new Procedure(["#c0=cSurface","mov o0.w, c0.y"],"setGlossinessFromConstantProcedure");
|
||||
|
||||
private static const _setGlossinessFromTextureProcedure:Procedure = new Procedure(["#v0=vUV","#c0=cSurface","#s0=sGlossiness","tex t0, v0, s0 <2d, repeat, linear, miplinear>","mul o0.w, t0.x, c0.y"],"setGlossinessFromTextureProcedure");
|
||||
|
||||
private static const _getNormalAndViewTangentProcedure:Procedure = new Procedure(["#v0=vTangent","#v1=vBinormal","#v2=vNormal","#v3=vUV","#v4=vViewVector","#c0=cAmbientColor","#s0=sBump","tex t0, v3, s0 <2d,repeat,linear,miplinear>","add t0, t0, t0","sub t0.xyz, t0.xyz, c0.www","nrm t1.xyz, v0.xyz","dp3 o0.x, t0.xyz, t1.xyz","nrm t1.xyz, v1.xyz","dp3 o0.y, t0.xyz, t1.xyz","nrm t1.xyz, v2.xyz","dp3 o0.z, t0.xyz, t1.xyz","nrm o0.xyz, o0.xyz","nrm o1.xyz, v4"],"getNormalAndViewTangentProcedure");
|
||||
|
||||
private static const _getNormalAndViewObjectProcedure:Procedure = new Procedure(["#v3=vUV","#v4=vViewVector","#c0=cAmbientColor","#s0=sBump","tex t0, v3, s0 <2d,repeat,linear,miplinear>","add t0, t0, t0","sub t0.xyz, t0.xyz, c0.www","nrm o0.xyz, t0.xyz","nrm o1.xyz, v4"],"getNormalAndViewObjectProcedure");
|
||||
|
||||
private static const _applySpecularProcedure:Procedure = new Procedure(["#v0=vUV","#s0=sSpecular","tex t0, v0, s0 <2d, repeat,linear,miplinear>","mul o0.xyz, o0.xyz, t0.xyz"],"applySpecularProcedure");
|
||||
|
||||
private static const _mulLightingProcedure:Procedure = new Procedure(["#s0=sTexture","#v0=vUV","#c0=cSurface","tex t0, v0, s0 <2d, repeat, linear, miplinear>","mul t0.xyz, t0.xyz, i0.xyz","mul t1.xyz, i1.xyz, c0.z","add t0.xyz, t0.xyz, t1.xyz","mov o0, t0"],"mulLightingProcedure");
|
||||
|
||||
private static const passSimpleFogConstProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogSpace","dp4 t0.z, i0, c0","mov v0, t0.zzzz","sub v0.y, i0.w, t0.z"],"passSimpleFogConst");
|
||||
|
||||
private static const outputWithSimpleFogProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogColor","#c1=cFogRange","min t0.xy, v0.xy, c1.xy","max t0.xy, t0.xy, c1.zw","mul i0.xyz, i0.xyz, t0.y","mul t0.xyz, c0.xyz, t0.x","add i0.xyz, i0.xyz, t0.xyz","mov o0, i0"],"outputWithSimpleFog");
|
||||
|
||||
private static const postPassAdvancedFogConstProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogSpace","dp4 t0.z, i0, c0","mov v0, t0.zzzz","sub v0.y, i0.w, t0.z","mov v0.zw, i1.xwxw","mov o0, i1"],"postPassAdvancedFogConst");
|
||||
|
||||
private static const outputWithAdvancedFogProcedure:Procedure = new Procedure(["#v0=vZDistance","#c0=cFogConsts","#c1=cFogRange","#s0=sFogTexture","min t0.xy, v0.xy, c1.xy","max t0.xy, t0.xy, c1.zw","mul i0.xyz, i0.xyz, t0.y","mov t1.xyzw, c0.yyzw","div t0.z, v0.z, v0.w","mul t0.z, t0.z, c0.x","add t1.x, t1.x, t0.z","tex t1, t1, s0 <2d, repeat, linear, miplinear>","mul t0.xyz, t1.xyz, t0.x","add i0.xyz, i0.xyz, t0.xyz","mov o0, i0"],"outputWithAdvancedFog");
|
||||
|
||||
alternativa3d var name_ES:Boolean = false;
|
||||
|
||||
alternativa3d var outputAlpha:Procedure = new Procedure(["#c0=cSurface","mov i0.w, c0.w","mov o0, i0"],"outputAlpha");
|
||||
|
||||
alternativa3d var outputDiffuseAlpha:Procedure = new Procedure(["#c0=cSurface","mul i0.w, i0.w, c0.w","mov o0, i0"],"outputDiffuseAlpha");
|
||||
|
||||
alternativa3d var outputOpacity:Procedure = new Procedure(["#c0=cSurface","#s0=sOpacity","#v0=vUV","tex t0, v0, s0 <2d, repeat,linear,miplinear>","mul i0.w, t0.x, c0.w","mov o0, i0"],"outputOpacity");
|
||||
|
||||
public var normalMap:TextureResource;
|
||||
|
||||
private var name_NH:int = 0;
|
||||
|
||||
public var specularMap:TextureResource;
|
||||
|
||||
public var glossinessMap:TextureResource;
|
||||
|
||||
public var glossiness:Number = 100;
|
||||
|
||||
public var name_kj:Number = 1;
|
||||
|
||||
public function StandardMaterial(diffuseMap:TextureResource, normalMap:TextureResource, specularMap:TextureResource = null, glossinessMap:TextureResource = null, opacityMap:TextureResource = null)
|
||||
{
|
||||
super(diffuseMap);
|
||||
this.normalMap = normalMap;
|
||||
this.specularMap = specularMap;
|
||||
this.glossinessMap = glossinessMap;
|
||||
this.opacityMap = opacityMap;
|
||||
}
|
||||
|
||||
private static function getPassTBNProcedure(right:Boolean) : Procedure
|
||||
{
|
||||
var crsInSpace:String = right ? "crs t1.xyz, i0, i1" : "crs t1.xyz, i1, i0";
|
||||
return new Procedure(["#v0=vTangent","#v1=vBinormal","#v2=vNormal",crsInSpace,"mul t1.xyz, t1.xyz, i0.w","mov v0.x, i0.x","mov v0.y, t1.x","mov v0.z, i1.x","mov v0.w, i1.w","mov v1.x, i0.y","mov v1.y, t1.y","mov v1.z, i1.y","mov v1.w, i1.w","mov v2.x, i0.z","mov v2.y, t1.z","mov v2.z, i1.z","mov v2.w, i1.w"],"passTBNProcedure");
|
||||
}
|
||||
|
||||
public function get normalMapSpace() : int
|
||||
{
|
||||
return this.name_NH;
|
||||
}
|
||||
|
||||
public function set normalMapSpace(value:int) : void
|
||||
{
|
||||
if(value != NormalMapSpace.TANGENT_RIGHT_HANDED && value != NormalMapSpace.TANGENT_LEFT_HANDED && value != NormalMapSpace.OBJECT)
|
||||
{
|
||||
throw new ArgumentError("Value must be a constant from the NormalMapSpace class");
|
||||
}
|
||||
this.name_NH = value;
|
||||
}
|
||||
|
||||
alternativa3d function getPassUVProcedure() : Procedure
|
||||
{
|
||||
return alternativa3d::_passUVProcedure;
|
||||
}
|
||||
|
||||
alternativa3d function setPassUVProcedureConstants(destination:DrawUnit, vertexLinker:Linker) : void
|
||||
{
|
||||
}
|
||||
|
||||
private function final(object:Object3D, lights:Vector.<Light3D>, directional:DirectionalLight, lightsLength:int) : ShaderProgram
|
||||
{
|
||||
var i:int = 0;
|
||||
var outputProcedure:Procedure = null;
|
||||
var procedure:Procedure = null;
|
||||
var nrmProcedure:Procedure = null;
|
||||
var shadowProc:Procedure = null;
|
||||
var dirMulShadowProcedure:Procedure = null;
|
||||
var light:Light3D = null;
|
||||
var lightFragmentProcedure:Procedure = null;
|
||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||
fragmentLinker.declareVariable("tTotalLight");
|
||||
fragmentLinker.declareVariable("tTotalHighLight");
|
||||
fragmentLinker.declareVariable("tNormal");
|
||||
fragmentLinker.declareVariable("cAmbientColor",VariableType.CONSTANT);
|
||||
fragmentLinker.addProcedure(_ambientLightProcedure);
|
||||
fragmentLinker.setInputParams(_ambientLightProcedure,"cAmbientColor");
|
||||
fragmentLinker.setOutputParams(_ambientLightProcedure,"tTotalLight","tTotalHighLight");
|
||||
var positionVar:String = "aPosition";
|
||||
var normalVar:String = "aNormal";
|
||||
var tangentVar:String = "aTangent";
|
||||
vertexLinker.declareVariable(positionVar,VariableType.ATTRIBUTE);
|
||||
vertexLinker.declareVariable(tangentVar,VariableType.ATTRIBUTE);
|
||||
vertexLinker.declareVariable(normalVar,VariableType.ATTRIBUTE);
|
||||
if(object.alternativa3d::transformProcedure != null)
|
||||
{
|
||||
positionVar = alternativa3d::appendPositionTransformProcedure(object.alternativa3d::transformProcedure,vertexLinker);
|
||||
}
|
||||
vertexLinker.addProcedure(alternativa3d::_projectProcedure);
|
||||
vertexLinker.setInputParams(alternativa3d::_projectProcedure,positionVar);
|
||||
vertexLinker.addProcedure(this.alternativa3d::getPassUVProcedure());
|
||||
if(this.glossinessMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(_setGlossinessFromTextureProcedure);
|
||||
fragmentLinker.setOutputParams(_setGlossinessFromTextureProcedure,"tTotalHighLight");
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(_setGlossinessFromConstantProcedure);
|
||||
fragmentLinker.setOutputParams(_setGlossinessFromConstantProcedure,"tTotalHighLight");
|
||||
}
|
||||
if(lightsLength > 0)
|
||||
{
|
||||
if(object.alternativa3d::deltaTransformProcedure != null)
|
||||
{
|
||||
vertexLinker.declareVariable("tTransformedNormal");
|
||||
procedure = object.alternativa3d::deltaTransformProcedure.newInstance();
|
||||
vertexLinker.addProcedure(procedure);
|
||||
vertexLinker.setInputParams(procedure,normalVar);
|
||||
vertexLinker.setOutputParams(procedure,"tTransformedNormal");
|
||||
normalVar = "tTransformedNormal";
|
||||
vertexLinker.declareVariable("tTransformedTangent");
|
||||
procedure = object.alternativa3d::deltaTransformProcedure.newInstance();
|
||||
vertexLinker.addProcedure(procedure);
|
||||
vertexLinker.setInputParams(procedure,tangentVar);
|
||||
vertexLinker.setOutputParams(procedure,"tTransformedTangent");
|
||||
tangentVar = "tTransformedTangent";
|
||||
}
|
||||
vertexLinker.addProcedure(_passVaryingsProcedure);
|
||||
vertexLinker.setInputParams(_passVaryingsProcedure,positionVar);
|
||||
fragmentLinker.declareVariable("tViewVector");
|
||||
if(this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED)
|
||||
{
|
||||
nrmProcedure = this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED ? _passTBNRightProcedure : _passTBNLeftProcedure;
|
||||
vertexLinker.addProcedure(nrmProcedure);
|
||||
vertexLinker.setInputParams(nrmProcedure,tangentVar,normalVar);
|
||||
fragmentLinker.addProcedure(_getNormalAndViewTangentProcedure);
|
||||
fragmentLinker.setOutputParams(_getNormalAndViewTangentProcedure,"tNormal","tViewVector");
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(_getNormalAndViewObjectProcedure);
|
||||
fragmentLinker.setOutputParams(_getNormalAndViewObjectProcedure,"tNormal","tViewVector");
|
||||
}
|
||||
if(directional != null)
|
||||
{
|
||||
vertexLinker.addProcedure(directional.shadow.getVShader());
|
||||
shadowProc = directional.shadow.getFShader();
|
||||
fragmentLinker.addProcedure(shadowProc);
|
||||
fragmentLinker.setOutputParams(shadowProc,"tTotalLight");
|
||||
dirMulShadowProcedure = _lightFragmentProcedures[directional.shadow];
|
||||
if(dirMulShadowProcedure == null)
|
||||
{
|
||||
dirMulShadowProcedure = new Procedure();
|
||||
this.formDirectionalProcedure(dirMulShadowProcedure,directional,true);
|
||||
}
|
||||
fragmentLinker.addProcedure(dirMulShadowProcedure);
|
||||
fragmentLinker.setInputParams(dirMulShadowProcedure,"tNormal","tViewVector","tTotalLight","cAmbientColor");
|
||||
fragmentLinker.setOutputParams(dirMulShadowProcedure,"tTotalLight","tTotalHighLight");
|
||||
}
|
||||
for(i = 0; i < lightsLength; )
|
||||
{
|
||||
light = lights[i];
|
||||
if(light != directional)
|
||||
{
|
||||
lightFragmentProcedure = _lightFragmentProcedures[light];
|
||||
if(lightFragmentProcedure == null)
|
||||
{
|
||||
lightFragmentProcedure = new Procedure();
|
||||
lightFragmentProcedure.name = "light" + i.toString();
|
||||
if(light is DirectionalLight)
|
||||
{
|
||||
this.formDirectionalProcedure(lightFragmentProcedure,light,false);
|
||||
lightFragmentProcedure.name += "Directional";
|
||||
}
|
||||
else if(light is OmniLight)
|
||||
{
|
||||
lightFragmentProcedure.compileFromArray(["#c0=c" + light.name_oG + "Position","#c1=c" + light.name_oG + "Color","#c2=c" + light.name_oG + "Radius","#v0=vPosition","sub t0, c0, v0","dp3 t0.w, t0.xyz, t0.xyz","nrm t0.xyz, t0.xyz","add t1.xyz, i1.xyz, t0.xyz","mov t1.w, c0.w","nrm t1.xyz, t1.xyz","dp3 t1.w, t1.xyz, i0.xyz","pow t1.w, t1.w, o1.w","sqt t1.x, t0.w","dp3 t0.w, t0.xyz, i0.xyz","sub t0.x, t1.x, c2.z","div t0.y, t0.x, c2.y","sub t0.x, c2.x, t0.y","sat t0.xw, t0.xw","mul t0.xyz, c1.xyz, t0.xxx","mul t1.xyz, t0.xyz, t1.w","add o1.xyz, o1.xyz, t1.xyz","mul t0.xyz, t0.xyz, t0.www","add o0.xyz, o0.xyz, t0.xyz"]);
|
||||
lightFragmentProcedure.name += "Omni";
|
||||
}
|
||||
else if(light is SpotLight)
|
||||
{
|
||||
lightFragmentProcedure.compileFromArray(["#c0=c" + light.name_oG + "Position","#c1=c" + light.name_oG + "Color","#c2=c" + light.name_oG + "Radius","#c3=c" + light.name_oG + "Axis","#v0=vPosition","sub t0, c0, v0","dp3 t0.w, t0, t0","nrm t0.xyz,t0.xyz","add t2.xyz, i1.xyz, t0.xyz","nrm t2.xyz, t2.xyz","dp3 t2.x, t2.xyz, i0.xyz","pow t2.x, t2.x, o1.w","dp3 t1.x, t0.xyz, c3.xyz","dp3 t0.x, t0, i0.xyz","sqt t0.w, t0.w","sub t0.w, t0.w, c2.y","div t0.y, t0.w, c2.x","sub t0.w, c0.w, t0.y","sub t0.y, t1.x, c2.w","div t0.y, t0.y, c2.z","sat t0.xyw,t0.xyw","mul t1.xyz,c1.xyz,t0.yyy","mul t1.xyz,t1.xyz,t0.www","mul t2.xyz, t2.x, t1.xyz","add o1.xyz, o1.xyz, t2.xyz","mul t1.xyz, t1.xyz, t0.xxx","add o0.xyz, o0.xyz, t1.xyz"]);
|
||||
lightFragmentProcedure.name += "Spot";
|
||||
}
|
||||
}
|
||||
fragmentLinker.addProcedure(lightFragmentProcedure);
|
||||
fragmentLinker.setInputParams(lightFragmentProcedure,"tNormal","tViewVector");
|
||||
fragmentLinker.setOutputParams(lightFragmentProcedure,"tTotalLight","tTotalHighLight");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if(this.specularMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(_applySpecularProcedure);
|
||||
fragmentLinker.setOutputParams(_applySpecularProcedure,"tTotalHighLight");
|
||||
outputProcedure = _applySpecularProcedure;
|
||||
}
|
||||
fragmentLinker.declareVariable("outColor");
|
||||
fragmentLinker.addProcedure(_mulLightingProcedure);
|
||||
fragmentLinker.setInputParams(_mulLightingProcedure,"tTotalLight","tTotalHighLight");
|
||||
fragmentLinker.setOutputParams(_mulLightingProcedure,"outColor");
|
||||
if(name_L4)
|
||||
{
|
||||
fragmentLinker.addProcedure(this.alternativa3d::outputDiffuseAlpha);
|
||||
fragmentLinker.setInputParams(this.alternativa3d::outputDiffuseAlpha,"outColor");
|
||||
outputProcedure = this.alternativa3d::outputDiffuseAlpha;
|
||||
}
|
||||
else if(opacityMap != null)
|
||||
{
|
||||
fragmentLinker.addProcedure(this.alternativa3d::outputOpacity);
|
||||
fragmentLinker.setInputParams(this.alternativa3d::outputOpacity,"outColor");
|
||||
outputProcedure = this.alternativa3d::outputOpacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentLinker.addProcedure(this.alternativa3d::outputAlpha);
|
||||
fragmentLinker.setInputParams(this.alternativa3d::outputAlpha,"outColor");
|
||||
outputProcedure = this.alternativa3d::outputAlpha;
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE || alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
fragmentLinker.setOutputParams(outputProcedure,"outColor");
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE)
|
||||
{
|
||||
vertexLinker.addProcedure(passSimpleFogConstProcedure);
|
||||
vertexLinker.setInputParams(passSimpleFogConstProcedure,positionVar);
|
||||
fragmentLinker.addProcedure(outputWithSimpleFogProcedure);
|
||||
fragmentLinker.setInputParams(outputWithSimpleFogProcedure,"outColor");
|
||||
}
|
||||
else if(alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
vertexLinker.declareVariable("tProjected");
|
||||
vertexLinker.setOutputParams(alternativa3d::_projectProcedure,"tProjected");
|
||||
vertexLinker.addProcedure(postPassAdvancedFogConstProcedure);
|
||||
vertexLinker.setInputParams(postPassAdvancedFogConstProcedure,positionVar,"tProjected");
|
||||
fragmentLinker.addProcedure(outputWithAdvancedFogProcedure);
|
||||
fragmentLinker.setInputParams(outputWithAdvancedFogProcedure,"outColor");
|
||||
}
|
||||
fragmentLinker.setOppositeLinker(vertexLinker);
|
||||
return new ShaderProgram(vertexLinker,fragmentLinker);
|
||||
}
|
||||
|
||||
private function formDirectionalProcedure(procedure:Procedure, light:Light3D, useShadow:Boolean) : void
|
||||
{
|
||||
var source:Array = ["#c0=c" + light.name_oG + "Direction","#c1=c" + light.name_oG + "Color","add t0.xyz, i1.xyz, c0.xyz","mov t0.w, c0.w","nrm t0.xyz,t0.xyz","dp3 t0.w, t0.xyz, i0.xyz","pow t0.w, t0.w, o1.w","dp3 t0.x, i0.xyz, c0.xyz","sat t0.x, t0.x"];
|
||||
if(useShadow)
|
||||
{
|
||||
source.push("mul t0.x, t0.x, i2.x");
|
||||
source.push("mul t0.xyz, c1.xyz, t0.xxx");
|
||||
source.push("mov o0.xyz, t0.xyz");
|
||||
source.push("add o0.xyz, o0.xyz, i3.xyz");
|
||||
source.push("mul t0.w, i2.x, t0.w");
|
||||
source.push("mul o1.xyz, c1.xyz, t0.www");
|
||||
}
|
||||
else
|
||||
{
|
||||
source.push("mul t0.xyz, c1.xyz, t0.xxxx");
|
||||
source.push("add o0, o0, t0.xyz");
|
||||
source.push("mul t0.xyz, c1.xyz, t0.w");
|
||||
source.push("add o1.xyz, o1.xyz, t0.xyz");
|
||||
}
|
||||
procedure.compileFromArray(source);
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, resourceType:Class) : void
|
||||
{
|
||||
super.alternativa3d::fillResources(resources,resourceType);
|
||||
if(this.normalMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.normalMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.normalMap] = true;
|
||||
}
|
||||
if(opacityMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(opacityMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[opacityMap] = true;
|
||||
}
|
||||
if(this.glossinessMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.glossinessMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.glossinessMap] = true;
|
||||
}
|
||||
if(this.specularMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.specularMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.specularMap] = true;
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
var program:ShaderProgram = null;
|
||||
var i:int = 0;
|
||||
var light:Light3D = null;
|
||||
var directional:DirectionalLight = null;
|
||||
var camTransform:Transform3D = null;
|
||||
var transform:Transform3D = null;
|
||||
var rScale:Number = NaN;
|
||||
var len:Number = NaN;
|
||||
var omni:OmniLight = null;
|
||||
var spot:SpotLight = null;
|
||||
var falloff:Number = NaN;
|
||||
var hotspot:Number = NaN;
|
||||
var lm:Transform3D = null;
|
||||
var dist:Number = NaN;
|
||||
var cLocal:Transform3D = null;
|
||||
var halfW:Number = NaN;
|
||||
var leftX:Number = NaN;
|
||||
var leftY:Number = NaN;
|
||||
var rightX:Number = NaN;
|
||||
var rightY:Number = NaN;
|
||||
var angle:Number = NaN;
|
||||
var dx:Number = NaN;
|
||||
var dy:Number = NaN;
|
||||
var lens:Number = NaN;
|
||||
var uScale:Number = NaN;
|
||||
var uRight:Number = NaN;
|
||||
var bmd:BitmapData = null;
|
||||
if(diffuseMap == null || this.normalMap == null || diffuseMap.alternativa3d::_texture == null || this.normalMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!name_L4 && opacityMap != null && opacityMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(this.glossinessMap != null && this.glossinessMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(this.specularMap != null && this.specularMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var object:Object3D = surface.alternativa3d::object;
|
||||
var positionBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.POSITION);
|
||||
var uvBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||
var normalsBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.NORMAL);
|
||||
var tangentsBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.TANGENT4);
|
||||
if(positionBuffer == null || uvBuffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var key:String = alternativa3d::fogMode.toString() + this.name_NH.toString() + (this.glossinessMap != null ? "G" : "g") + (opacityMap != null ? "O" : "o") + (this.specularMap != null ? "S" : "s") + (name_L4 ? "D" : "d");
|
||||
for(i = 0; i < lightsLength; i++)
|
||||
{
|
||||
light = lights[i];
|
||||
if(light is DirectionalLight && directional == null && DirectionalLight(light).shadow != null)
|
||||
{
|
||||
directional = DirectionalLight(light);
|
||||
key += "S";
|
||||
}
|
||||
key += light.name_oG;
|
||||
}
|
||||
var programs:Dictionary = _programs[object.alternativa3d::transformProcedure];
|
||||
if(programs == null)
|
||||
{
|
||||
programs = new Dictionary(false);
|
||||
_programs[object.alternativa3d::transformProcedure] = programs;
|
||||
program = this.final(object,lights,directional,lightsLength);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
programs[key] = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
program = programs[key];
|
||||
if(program == null)
|
||||
{
|
||||
program = this.final(object,lights,directional,lightsLength);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
programs[key] = program;
|
||||
}
|
||||
}
|
||||
var drawUnit:DrawUnit = camera.alternativa3d::renderer.alternativa3d::createDrawUnit(object,program.program,geometry.name_EM,surface.indexBegin,surface.numTriangles,program);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"),positionBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.POSITION],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.POSITION]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"),uvBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TEXCOORDS[0]],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||
object.alternativa3d::setTransformConstants(drawUnit,surface,program.vertexShader,camera);
|
||||
drawUnit.alternativa3d::setProjectionConstants(camera,program.vertexShader.getVariableIndex("cProjMatrix"),object.alternativa3d::localToCameraTransform);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromVector(program.fragmentShader.getVariableIndex("cAmbientColor"),camera.alternativa3d::ambient,1);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cSurface"),0,this.glossiness,this.name_kj,alpha);
|
||||
if(lightsLength > 0)
|
||||
{
|
||||
if(this.name_NH == NormalMapSpace.TANGENT_RIGHT_HANDED || this.name_NH == NormalMapSpace.TANGENT_LEFT_HANDED)
|
||||
{
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aNormal"),normalsBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.NORMAL],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.NORMAL]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aTangent"),tangentsBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TANGENT4],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TANGENT4]);
|
||||
}
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sBump"),this.normalMap.alternativa3d::_texture);
|
||||
camTransform = object.alternativa3d::cameraToLocalTransform;
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(program.vertexShader.getVariableIndex("cCameraPosition"),camTransform.d,camTransform.h,camTransform.l);
|
||||
for(i = 0; i < lightsLength; )
|
||||
{
|
||||
light = lights[i];
|
||||
if(light is DirectionalLight)
|
||||
{
|
||||
transform = light.name_cl;
|
||||
len = Number(Math.sqrt(transform.c * transform.c + transform.g * transform.g + transform.k * transform.k));
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Direction"),-transform.c / len,-transform.g / len,-transform.k / len,1);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Color"),light.alternativa3d::red,light.alternativa3d::green,light.alternativa3d::blue);
|
||||
}
|
||||
else if(light is OmniLight)
|
||||
{
|
||||
omni = light as OmniLight;
|
||||
transform = light.name_cl;
|
||||
rScale = Number(Math.sqrt(transform.a * transform.a + transform.e * transform.e + transform.i * transform.i));
|
||||
rScale += Math.sqrt(transform.b * transform.b + transform.f * transform.f + transform.j * transform.j);
|
||||
rScale += Math.sqrt(transform.c * transform.c + transform.g * transform.g + transform.k * transform.k);
|
||||
rScale /= 3;
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Position"),transform.d,transform.h,transform.l);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Radius"),1,omni.attenuationEnd * rScale - omni.attenuationBegin * rScale,omni.attenuationBegin * rScale);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Color"),light.alternativa3d::red,light.alternativa3d::green,light.alternativa3d::blue);
|
||||
}
|
||||
else if(light is SpotLight)
|
||||
{
|
||||
spot = light as SpotLight;
|
||||
transform = light.name_cl;
|
||||
rScale = Number(Math.sqrt(transform.a * transform.a + transform.e * transform.e + transform.i * transform.i));
|
||||
rScale += Math.sqrt(transform.b * transform.b + transform.f * transform.f + transform.j * transform.j);
|
||||
rScale += len = Number(Math.sqrt(transform.c * transform.c + transform.g * transform.g + transform.k * transform.k));
|
||||
rScale /= 3;
|
||||
falloff = Number(Math.cos(spot.falloff * 0.5));
|
||||
hotspot = Number(Math.cos(spot.hotspot * 0.5));
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Position"),transform.d,transform.h,transform.l);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Axis"),-transform.c / len,-transform.g / len,-transform.k / len);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Radius"),spot.attenuationEnd * rScale - spot.attenuationBegin * rScale,spot.attenuationBegin * rScale,hotspot == falloff ? 0.000001 : hotspot - falloff,falloff);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("c" + light.name_oG + "Color"),light.alternativa3d::red,light.alternativa3d::green,light.alternativa3d::blue);
|
||||
}
|
||||
if(directional != null)
|
||||
{
|
||||
directional.shadow.applyShader(drawUnit,program,object,camera);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sTexture"),diffuseMap.alternativa3d::_texture);
|
||||
if(!name_L4 && opacityMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"),opacityMap.alternativa3d::_texture);
|
||||
}
|
||||
if(this.glossinessMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sGlossiness"),this.glossinessMap.alternativa3d::_texture);
|
||||
}
|
||||
if(this.specularMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sSpecular"),this.specularMap.alternativa3d::_texture);
|
||||
}
|
||||
this.alternativa3d::setPassUVProcedureConstants(drawUnit,program.vertexShader);
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE || alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
lm = object.alternativa3d::localToCameraTransform;
|
||||
dist = alternativa3d::fogFar - alternativa3d::fogNear;
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(program.vertexShader.getVariableIndex("cFogSpace"),lm.i / dist,lm.j / dist,lm.k / dist,(lm.l - alternativa3d::fogNear) / dist);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogRange"),alternativa3d::fogMaxDensity,1,0,1 - alternativa3d::fogMaxDensity);
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::SIMPLE)
|
||||
{
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogColor"),alternativa3d::fogColorR,alternativa3d::fogColorG,alternativa3d::fogColorB);
|
||||
}
|
||||
if(alternativa3d::fogMode == alternativa3d::ADVANCED)
|
||||
{
|
||||
if(alternativa3d::fogTexture == null)
|
||||
{
|
||||
bmd = new BitmapData(32,1,false,16711680);
|
||||
for(i = 0; i < 32; i++)
|
||||
{
|
||||
bmd.setPixel(i,0,i / 32 * 255 << 16);
|
||||
}
|
||||
alternativa3d::fogTexture = new BitmapTextureResource(bmd);
|
||||
alternativa3d::fogTexture.upload(camera.alternativa3d::context3D);
|
||||
}
|
||||
cLocal = camera.alternativa3d::localToGlobalTransform;
|
||||
halfW = camera.view.width / 2;
|
||||
leftX = -halfW * cLocal.a + camera.alternativa3d::focalLength * cLocal.c;
|
||||
leftY = -halfW * cLocal.e + camera.alternativa3d::focalLength * cLocal.g;
|
||||
rightX = halfW * cLocal.a + camera.alternativa3d::focalLength * cLocal.c;
|
||||
rightY = halfW * cLocal.e + camera.alternativa3d::focalLength * cLocal.g;
|
||||
angle = Math.atan2(leftY,leftX) - Math.PI / 2;
|
||||
if(angle < 0)
|
||||
{
|
||||
angle += Math.PI * 2;
|
||||
}
|
||||
dx = rightX - leftX;
|
||||
dy = rightY - leftY;
|
||||
lens = Number(Math.sqrt(dx * dx + dy * dy));
|
||||
leftX /= lens;
|
||||
leftY /= lens;
|
||||
rightX /= lens;
|
||||
rightY /= lens;
|
||||
uScale = Math.acos(leftX * rightX + leftY * rightY) / Math.PI / 2;
|
||||
uRight = angle / Math.PI / 2;
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogConsts"),0.5 * uScale,0.5 - uRight,0);
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sFogTexture"),alternativa3d::fogTexture.alternativa3d::_texture);
|
||||
}
|
||||
if(this.name_ES)
|
||||
{
|
||||
if(drawUnit.alternativa3d::object == null)
|
||||
{
|
||||
throw new Error("");
|
||||
}
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.OPAQUE);
|
||||
}
|
||||
else if(name_L4 || opacityMap != null || alpha < 1)
|
||||
{
|
||||
drawUnit.alternativa3d::blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
||||
drawUnit.alternativa3d::blendDestination = Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA;
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.TRANSPARENT_SORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.OPAQUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
public class TextureFormat
|
||||
{
|
||||
public static const NONE:String = "atf_none";
|
||||
|
||||
public static const DXT1:String = "atf_dxt1";
|
||||
|
||||
public static const ETC1:String = "atf_etc1";
|
||||
|
||||
public static const PVRTC:String = "atf_pvrtc";
|
||||
|
||||
public function TextureFormat()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
package alternativa.engine3d.materials
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.objects.Surface;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.engine3d.resources.TextureResource;
|
||||
import avmplus.getQualifiedClassName;
|
||||
import flash.display3D.Context3DBlendFactor;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.display3D.VertexBuffer3D;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class TextureMaterial extends Material
|
||||
{
|
||||
alternativa3d static const _samplerSetProcedure:Procedure = new Procedure(["#v0=vUV","#s0=sTexture","#c0=cAlpha","tex t0, v0, s0 <2d, linear,repeat, miplinear>","mov t0.w, c0.w","mov o0, t0"],"samplerSetProcedure");
|
||||
|
||||
alternativa3d static const _samplerSetProcedureOpacity:Procedure = new Procedure(["#v0=vUV","#s0=sTexture","#s1=sOpacity","#c0=cAlpha","tex t0, v0, s0 <2d, linear,repeat, miplinear>","tex t1, v0, s1 <2d, linear,repeat, miplinear>","mov t0.w, t1.x","mul t0.w, t0.w, c0.w","mov o0, t0"],"samplerSetProcedureOpacity");
|
||||
|
||||
alternativa3d static const _samplerSetProcedureDiffuseAlpha:Procedure = new Procedure(["#v0=vUV","#s0=sTexture","#c0=cAlpha","tex t0, v0, s0 <2d, linear,repeat, miplinear>","mul t0.w, t0.w, c0.w","mov o0, t0"],"samplerSetProcedureDiffuseAlpha");
|
||||
|
||||
alternativa3d static const _passUVProcedure:Procedure = new Procedure(["#v0=vUV","#a0=aUV","mov v0, a0"],"passUVProcedure");
|
||||
|
||||
private static var _programs:Dictionary = new Dictionary();
|
||||
|
||||
public var diffuseMap:TextureResource;
|
||||
|
||||
public var opacityMap:TextureResource;
|
||||
|
||||
public var alpha:Number = 1;
|
||||
|
||||
public var name_L4:Boolean = false;
|
||||
|
||||
public function TextureMaterial(diffuseMap:TextureResource = null, opacityMap:TextureResource = null, alpha:Number = 1)
|
||||
{
|
||||
super();
|
||||
this.diffuseMap = diffuseMap;
|
||||
this.opacityMap = opacityMap;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
override alternativa3d function get canDrawInShadowMap() : Boolean
|
||||
{
|
||||
return !this.name_L4 && this.opacityMap == null;
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, resourceType:Class) : void
|
||||
{
|
||||
super.alternativa3d::fillResources(resources,resourceType);
|
||||
if(this.diffuseMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.diffuseMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.diffuseMap] = true;
|
||||
}
|
||||
if(this.opacityMap != null && Boolean(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.opacityMap)) as Class,resourceType)))
|
||||
{
|
||||
resources[this.opacityMap] = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function final(object:Object3D) : ShaderProgram
|
||||
{
|
||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||
var positionVar:String = "aPosition";
|
||||
vertexLinker.declareVariable(positionVar,VariableType.ATTRIBUTE);
|
||||
if(object.alternativa3d::transformProcedure != null)
|
||||
{
|
||||
positionVar = alternativa3d::appendPositionTransformProcedure(object.alternativa3d::transformProcedure,vertexLinker);
|
||||
}
|
||||
vertexLinker.addProcedure(alternativa3d::_projectProcedure);
|
||||
vertexLinker.setInputParams(alternativa3d::_projectProcedure,positionVar);
|
||||
vertexLinker.addProcedure(alternativa3d::_passUVProcedure);
|
||||
var outProcedure:Procedure = this.name_L4 ? alternativa3d::_samplerSetProcedureDiffuseAlpha : (this.opacityMap != null ? alternativa3d::_samplerSetProcedureOpacity : alternativa3d::_samplerSetProcedure);
|
||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||
fragmentLinker.addProcedure(outProcedure);
|
||||
fragmentLinker.setOppositeLinker(vertexLinker);
|
||||
return new ShaderProgram(vertexLinker,fragmentLinker);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector.<Light3D>, lightsLength:int, objectRenderPriority:int = -1) : void
|
||||
{
|
||||
var program:ShaderProgram = null;
|
||||
var object:Object3D = surface.alternativa3d::object;
|
||||
var positionBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.POSITION);
|
||||
var uvBuffer:VertexBuffer3D = geometry.alternativa3d::getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||
var key:int = this.name_L4 ? 2 : (this.opacityMap != null ? 1 : 0);
|
||||
var optionsPrograms:Vector.<ShaderProgram> = _programs[object.alternativa3d::transformProcedure];
|
||||
if(optionsPrograms == null)
|
||||
{
|
||||
optionsPrograms = new Vector.<ShaderProgram>(3,true);
|
||||
_programs[object.alternativa3d::transformProcedure] = optionsPrograms;
|
||||
program = this.final(object);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
optionsPrograms[key] = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
program = optionsPrograms[key];
|
||||
if(program == null)
|
||||
{
|
||||
program = this.final(object);
|
||||
program.upload(camera.alternativa3d::context3D);
|
||||
optionsPrograms[key] = program;
|
||||
}
|
||||
}
|
||||
if(positionBuffer == null || uvBuffer == null || this.diffuseMap == null || this.diffuseMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!this.name_L4 && this.opacityMap != null && this.opacityMap.alternativa3d::_texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var drawUnit:DrawUnit = camera.alternativa3d::renderer.alternativa3d::createDrawUnit(object,program.program,geometry.name_EM,surface.indexBegin,surface.numTriangles,program);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"),positionBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.POSITION],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.POSITION]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"),uvBuffer,geometry.alternativa3d::_attributesOffsets[VertexAttributes.TEXCOORDS[0]],VertexAttributes.alternativa3d::FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||
object.alternativa3d::setTransformConstants(drawUnit,surface,program.vertexShader,camera);
|
||||
drawUnit.alternativa3d::setProjectionConstants(camera,program.vertexShader.getVariableIndex("cProjMatrix"),object.alternativa3d::localToCameraTransform);
|
||||
drawUnit.alternativa3d::setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cAlpha"),0,0,0,this.alpha);
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sTexture"),this.diffuseMap.alternativa3d::_texture);
|
||||
if(!this.name_L4 && this.opacityMap != null)
|
||||
{
|
||||
drawUnit.alternativa3d::setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"),this.opacityMap.alternativa3d::_texture);
|
||||
}
|
||||
if(this.name_L4 || this.opacityMap != null || this.alpha < 1)
|
||||
{
|
||||
drawUnit.alternativa3d::blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
||||
drawUnit.alternativa3d::blendDestination = Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA;
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.TRANSPARENT_SORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.alternativa3d::renderer.alternativa3d::addDrawUnit(drawUnit,objectRenderPriority >= 0 ? objectRenderPriority : RenderPriority.OPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Material
|
||||
{
|
||||
var res:TextureMaterial = new TextureMaterial(null,null,this.alpha);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Material) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
var t:TextureMaterial = source as TextureMaterial;
|
||||
this.diffuseMap = t.diffuseMap;
|
||||
this.opacityMap = t.opacityMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
public class CommandType
|
||||
{
|
||||
public static const MOV:uint = 0;
|
||||
|
||||
public static const ADD:uint = 1;
|
||||
|
||||
public static const SUB:uint = 2;
|
||||
|
||||
public static const MUL:uint = 3;
|
||||
|
||||
public static const DIV:uint = 4;
|
||||
|
||||
public static const RCP:uint = 5;
|
||||
|
||||
public static const MIN:uint = 6;
|
||||
|
||||
public static const MAX:uint = 7;
|
||||
|
||||
public static const FRC:uint = 8;
|
||||
|
||||
public static const SQT:uint = 9;
|
||||
|
||||
public static const RSQ:uint = 10;
|
||||
|
||||
public static const POW:uint = 11;
|
||||
|
||||
public static const LOG:uint = 12;
|
||||
|
||||
public static const EXP:uint = 13;
|
||||
|
||||
public static const NRM:uint = 14;
|
||||
|
||||
public static const SIN:uint = 15;
|
||||
|
||||
public static const COS:uint = 16;
|
||||
|
||||
public static const CRS:uint = 17;
|
||||
|
||||
public static const DP3:uint = 18;
|
||||
|
||||
public static const DP4:uint = 19;
|
||||
|
||||
public static const ABS:uint = 20;
|
||||
|
||||
public static const NEG:uint = 21;
|
||||
|
||||
public static const SAT:uint = 22;
|
||||
|
||||
public static const M33:uint = 23;
|
||||
|
||||
public static const M44:uint = 24;
|
||||
|
||||
public static const M34:uint = 25;
|
||||
|
||||
public static const KIL:uint = 39;
|
||||
|
||||
public static const TEX:uint = 40;
|
||||
|
||||
public static const SGE:uint = 41;
|
||||
|
||||
public static const SLT:uint = 42;
|
||||
|
||||
public static const DEF:uint = 128;
|
||||
|
||||
public static const CAL:uint = 129;
|
||||
|
||||
public static const COMMAND_NAMES:Vector.<String> = Vector.<String>(["mov","add","sub","mul","div","rcp","min","max","frc","sqt","rsq","pow","log","exp","nrm","sin","cos","crs","dp3","dp4","abs","neg","sat","m33","m44","m34","1a","1b","1c","1d","1e","1f","20","21","22","23","24","25","26","kil","tex","sge","slt"]);
|
||||
|
||||
public function CommandType()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class DestinationVariable extends Variable
|
||||
{
|
||||
public function DestinationVariable(source:String)
|
||||
{
|
||||
var regmask:uint = 0;
|
||||
var cv:int = 0;
|
||||
var maskLength:uint = 0;
|
||||
var i:int = 0;
|
||||
super();
|
||||
var strType:String = source.match(/[tovi]/)[0];
|
||||
index = parseInt(source.match(/\d+/)[0],10);
|
||||
var swizzle:Array = source.match(/\.[xyzw]{1,4}/);
|
||||
var maskmatch:String = Boolean(swizzle) ? swizzle[0] : null;
|
||||
if(maskmatch != null)
|
||||
{
|
||||
regmask = 0;
|
||||
maskLength = uint(maskmatch.length);
|
||||
for(i = 1; i < maskLength; i++)
|
||||
{
|
||||
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
|
||||
if(cv == -1)
|
||||
{
|
||||
cv = 3;
|
||||
}
|
||||
regmask |= 1 << cv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
regmask = 15;
|
||||
}
|
||||
name_0J = regmask << 16 | index;
|
||||
switch(strType)
|
||||
{
|
||||
case "t":
|
||||
name_0J |= 33554432;
|
||||
type = 2;
|
||||
break;
|
||||
case "o":
|
||||
name_0J |= 50331648;
|
||||
type = 3;
|
||||
break;
|
||||
case "v":
|
||||
name_0J |= 67108864;
|
||||
type = 4;
|
||||
break;
|
||||
case "i":
|
||||
name_0J |= 100663296;
|
||||
type = 6;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentError("Wrong destination register type, must be \"t\" or \"o\" or \"v\", var = " + source);
|
||||
}
|
||||
}
|
||||
|
||||
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int) : void
|
||||
{
|
||||
byteCode.position = position;
|
||||
byteCode.writeUnsignedInt(name_0J & ~0x0F00FFFF | newIndex | newType << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Linker
|
||||
{
|
||||
public var name_RT:int = 0;
|
||||
|
||||
public var name_A:int = 0;
|
||||
|
||||
public var type:String;
|
||||
|
||||
private var name_2L:Vector.<Procedure> = new Vector.<Procedure>();
|
||||
|
||||
private var name_RU:ByteArray = new ByteArray();
|
||||
|
||||
private var name_8Z:Boolean;
|
||||
|
||||
alternativa3d var name_3r:Object;
|
||||
|
||||
private var name_c:Object = new Object();
|
||||
|
||||
private var name_T1:Linker;
|
||||
|
||||
private var name_W8:Dictionary = new Dictionary();
|
||||
|
||||
private var name_f:Dictionary = new Dictionary();
|
||||
|
||||
private var name_Jf:Vector.<uint> = new Vector.<uint>(6,true);
|
||||
|
||||
public function Linker(programType:String)
|
||||
{
|
||||
super();
|
||||
this.name_RU.endian = Endian.LITTLE_ENDIAN;
|
||||
this.type = programType;
|
||||
this.name_RU.writeByte(160);
|
||||
this.name_RU.writeUnsignedInt(1);
|
||||
this.name_RU.writeByte(161);
|
||||
this.name_RU.writeByte(programType == Context3DProgramType.FRAGMENT ? 1 : 0);
|
||||
}
|
||||
|
||||
public function clear() : void
|
||||
{
|
||||
this.name_RU.length = 7;
|
||||
this.name_Jf[0] = this.name_Jf[1] = this.name_Jf[2] = this.name_Jf[3] = this.name_Jf[4] = this.name_Jf[5] = 0;
|
||||
this.name_2L.length = 0;
|
||||
this.name_8Z = false;
|
||||
this.name_A = 0;
|
||||
this.name_RT = 0;
|
||||
this.name_3r = null;
|
||||
this.name_W8 = new Dictionary();
|
||||
this.name_f = new Dictionary();
|
||||
}
|
||||
|
||||
public function addProcedure(procedure:Procedure) : void
|
||||
{
|
||||
this.name_8Z = true;
|
||||
this.name_2L.push(procedure);
|
||||
}
|
||||
|
||||
public function declareVariable(name:String, type:uint = 2) : void
|
||||
{
|
||||
var v:Variable = null;
|
||||
v = new Variable();
|
||||
v.index = -1;
|
||||
v.type = type;
|
||||
v.name = name;
|
||||
this.name_c[name] = v;
|
||||
}
|
||||
|
||||
public function setInputParams(procedure:Procedure, ... args) : void
|
||||
{
|
||||
this.name_W8[procedure] = args;
|
||||
}
|
||||
|
||||
public function setOutputParams(procedure:Procedure, ... args) : void
|
||||
{
|
||||
this.name_f[procedure] = args;
|
||||
}
|
||||
|
||||
public function getVariableIndex(name:String) : int
|
||||
{
|
||||
if(this.name_8Z)
|
||||
{
|
||||
this.link();
|
||||
}
|
||||
var variable:Variable = this.name_3r[name];
|
||||
if(variable == null)
|
||||
{
|
||||
throw new Error("Variable \"" + name + "\" not found");
|
||||
}
|
||||
return variable.index;
|
||||
}
|
||||
|
||||
public function findVariable(name:String) : int
|
||||
{
|
||||
if(this.name_8Z)
|
||||
{
|
||||
this.link();
|
||||
}
|
||||
var variable:Variable = this.name_3r[name];
|
||||
if(variable == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return variable.index;
|
||||
}
|
||||
|
||||
public function containsVariable(name:String) : Boolean
|
||||
{
|
||||
if(this.name_8Z)
|
||||
{
|
||||
this.link();
|
||||
}
|
||||
return this.name_3r[name] != null;
|
||||
}
|
||||
|
||||
public function getByteCode() : ByteArray
|
||||
{
|
||||
if(this.name_8Z)
|
||||
{
|
||||
this.link();
|
||||
}
|
||||
return this.name_RU;
|
||||
}
|
||||
|
||||
public function setOppositeLinker(linker:Linker) : void
|
||||
{
|
||||
this.name_T1 = linker;
|
||||
this.name_8Z = true;
|
||||
}
|
||||
|
||||
public function link() : void
|
||||
{
|
||||
var v:Variable = null;
|
||||
var j:int = 0;
|
||||
var numParams:int = 0;
|
||||
var i:int = 0;
|
||||
var p:Procedure = null;
|
||||
var input:Array = null;
|
||||
var output:Array = null;
|
||||
var code:ByteArray = null;
|
||||
var param:String = null;
|
||||
var vars:Vector.<Variable> = null;
|
||||
var inParam:Variable = null;
|
||||
var outParam:Variable = null;
|
||||
if(this.name_8Z)
|
||||
{
|
||||
this.name_3r = new Object();
|
||||
this.name_RU.position = 7;
|
||||
this.name_Jf[0] = 0;
|
||||
this.name_Jf[1] = 0;
|
||||
this.name_Jf[3] = 0;
|
||||
this.name_Jf[4] = 0;
|
||||
this.name_Jf[5] = 0;
|
||||
this.name_A = 0;
|
||||
this.name_RT = 0;
|
||||
for each(v in this.name_c)
|
||||
{
|
||||
this.name_3r[v.name] = v;
|
||||
}
|
||||
for(i = 0; i < this.name_2L.length; i++)
|
||||
{
|
||||
p = this.name_2L[i];
|
||||
this.name_A += p.name_A;
|
||||
this.name_RT += p.name_RT;
|
||||
input = this.name_W8[p];
|
||||
output = this.name_f[p];
|
||||
code = new ByteArray();
|
||||
code.endian = Endian.LITTLE_ENDIAN;
|
||||
p.byteCode.position = 0;
|
||||
p.byteCode.readBytes(code,0,p.byteCode.length);
|
||||
if(input != null)
|
||||
{
|
||||
numParams = int(input.length);
|
||||
for(j = 0; j < numParams; )
|
||||
{
|
||||
param = input[j];
|
||||
v = this.name_3r[param];
|
||||
if(v == null)
|
||||
{
|
||||
throw new Error("Input parameter not set. paramName = " + param);
|
||||
}
|
||||
if(p.name_d2[6].length > j)
|
||||
{
|
||||
inParam = p.name_d2[6][j];
|
||||
if(inParam == null)
|
||||
{
|
||||
throw new Error("Input parameter set, but not exist in code. paramName = " + param + ", register = i" + j.toString());
|
||||
}
|
||||
if(this.name_c[v.name] != null && v.index < 0)
|
||||
{
|
||||
v.index = int(this.name_Jf[v.type]++);
|
||||
}
|
||||
while(inParam != null)
|
||||
{
|
||||
inParam.writeToByteArray(code,v.index,v.type);
|
||||
inParam = inParam.next;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if(output != null)
|
||||
{
|
||||
numParams = int(output.length);
|
||||
for(j = 0; j < numParams; j++)
|
||||
{
|
||||
param = output[j];
|
||||
v = this.name_3r[param];
|
||||
if(v == null)
|
||||
{
|
||||
if(!(j == 0 && i == this.name_2L.length - 1))
|
||||
{
|
||||
throw new Error("Output parameter have not declared. paramName = " + param);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.name_c[v.name] != null && v.index < 0)
|
||||
{
|
||||
if(v.type != 2)
|
||||
{
|
||||
throw new Error("Wrong output type:" + VariableType.TYPE_NAMES[v.type]);
|
||||
}
|
||||
v.index = int(this.name_Jf[v.type]++);
|
||||
}
|
||||
outParam = p.name_d2[3][j];
|
||||
if(outParam == null)
|
||||
{
|
||||
throw new Error("Output parameter set, but not exist in code. paramName = " + param + ", register = i" + j.toString());
|
||||
}
|
||||
while(outParam != null)
|
||||
{
|
||||
outParam.writeToByteArray(code,v.index,v.type);
|
||||
outParam = outParam.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vars = p.name_d2[2];
|
||||
for(j = 0; j < vars.length; j++)
|
||||
{
|
||||
v = vars[j];
|
||||
if(v != null)
|
||||
{
|
||||
while(v != null)
|
||||
{
|
||||
v.writeToByteArray(code,v.index + this.name_Jf[2],VariableType.TEMPORARY);
|
||||
v = v.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.name_Jf[VariableType.CONSTANT] += p.name_in;
|
||||
this.resolveVariablesUsages(code,p.name_d2[0],VariableType.ATTRIBUTE);
|
||||
this.resolveVariablesUsages(code,p.name_d2[1],VariableType.CONSTANT);
|
||||
this.resolveVaryings(code,p.name_d2[4]);
|
||||
this.resolveVariablesUsages(code,p.name_d2[5],VariableType.SAMPLER);
|
||||
this.name_RU.writeBytes(code,0,code.length);
|
||||
}
|
||||
this.name_8Z = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveVaryings(code:ByteArray, variableUsages:Vector.<Variable>) : void
|
||||
{
|
||||
var vUsage:Variable = null;
|
||||
var variable:Variable = null;
|
||||
var type:uint = VariableType.VARYING;
|
||||
if(this.name_T1 != null && this.name_T1.name_8Z)
|
||||
{
|
||||
this.name_T1.link();
|
||||
}
|
||||
var oppositeVariables:Object = this.name_T1 != null ? this.name_T1.name_3r : null;
|
||||
for(var j:uint = 0; j < variableUsages.length; j++)
|
||||
{
|
||||
vUsage = variableUsages[j];
|
||||
if(vUsage != null)
|
||||
{
|
||||
variable = this.name_3r[vUsage.name];
|
||||
if(variable == null)
|
||||
{
|
||||
variable = Variable.create();
|
||||
if(vUsage.name == null)
|
||||
{
|
||||
throw new Error("Varying is not assigned. Use \'assignVariableName\' method. register = " + vUsage.index);
|
||||
}
|
||||
this.name_3r[vUsage.name] = variable;
|
||||
variable.name = vUsage.name;
|
||||
if(oppositeVariables != null)
|
||||
{
|
||||
if(!(vUsage.name in oppositeVariables))
|
||||
{
|
||||
throw new Error("Varying with this name is not assigned to opposite linker. name = " + vUsage.name);
|
||||
}
|
||||
variable.index = Variable(oppositeVariables[vUsage.name]).index;
|
||||
}
|
||||
else
|
||||
{
|
||||
variable.index = this.name_Jf[type];
|
||||
this.name_Jf[type] += vUsage.size;
|
||||
}
|
||||
variable.type = type;
|
||||
}
|
||||
while(Boolean(vUsage))
|
||||
{
|
||||
vUsage.writeToByteArray(code,variable.index,variable.type);
|
||||
vUsage = vUsage.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveVariablesUsages(code:ByteArray, variableUsages:Vector.<Variable>, type:uint) : void
|
||||
{
|
||||
var vUsage:Variable = null;
|
||||
var variable:Variable = null;
|
||||
for(var j:int = 0; j < variableUsages.length; j++)
|
||||
{
|
||||
vUsage = variableUsages[j];
|
||||
if(vUsage != null)
|
||||
{
|
||||
variable = this.name_3r[vUsage.name];
|
||||
if(variable == null)
|
||||
{
|
||||
variable = Variable.create();
|
||||
if(vUsage.name != null)
|
||||
{
|
||||
this.name_3r[vUsage.name] = variable;
|
||||
}
|
||||
else if(!vUsage.isRelative)
|
||||
{
|
||||
throw new Error(VariableType.TYPE_NAMES[type] + " is not assigned. Use \"assignVariableName\" method. register = " + vUsage.index);
|
||||
}
|
||||
variable.name = vUsage.name;
|
||||
variable.index = this.name_Jf[type];
|
||||
this.name_Jf[type] += vUsage.size;
|
||||
variable.type = type;
|
||||
}
|
||||
else if(variable.index < 0)
|
||||
{
|
||||
variable.index = int(this.name_Jf[type]++);
|
||||
}
|
||||
while(vUsage != null)
|
||||
{
|
||||
vUsage.writeToByteArray(code,variable.index,variable.type);
|
||||
vUsage = vUsage.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function describeLinkageInfo() : String
|
||||
{
|
||||
var str:String = null;
|
||||
var p:Procedure = null;
|
||||
var args:* = undefined;
|
||||
var result:String = "LINKER:\n";
|
||||
var totalCodes:uint = 0;
|
||||
var totalCommands:uint = 0;
|
||||
for(var i:int = 0; i < this.name_2L.length; i++)
|
||||
{
|
||||
p = this.name_2L[i];
|
||||
if(p.name != null)
|
||||
{
|
||||
result += p.name + "(";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "#" + i.toString() + "(";
|
||||
}
|
||||
args = this.name_W8[p];
|
||||
if(args != null)
|
||||
{
|
||||
for each(str in args)
|
||||
{
|
||||
result += str + ",";
|
||||
}
|
||||
result = result.substr(0,result.length - 1);
|
||||
}
|
||||
result += ")";
|
||||
args = this.name_f[p];
|
||||
if(args != null)
|
||||
{
|
||||
result += "->(";
|
||||
for each(str in args)
|
||||
{
|
||||
result += str + ",";
|
||||
}
|
||||
result = result.substr(0,result.length - 1);
|
||||
result += ")";
|
||||
}
|
||||
result += " [IS:" + p.name_RT.toString() + ", CMDS:" + p.name_A.toString() + "]\n";
|
||||
totalCodes += p.name_RT;
|
||||
totalCommands += p.name_A;
|
||||
}
|
||||
return result + ("[IS:" + totalCodes.toString() + ", CMDS:" + totalCommands.toString() + "]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,370 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Procedure
|
||||
{
|
||||
public var name:String;
|
||||
|
||||
public var byteCode:ByteArray = new ByteArray();
|
||||
|
||||
public var name_d2:Vector.<Vector.<Variable>> = new Vector.<Vector.<Variable>>();
|
||||
|
||||
public var name_RT:int = 0;
|
||||
|
||||
public var name_A:int = 0;
|
||||
|
||||
alternativa3d var name_in:uint = 0;
|
||||
|
||||
public function Procedure(array:Array = null, name:String = null)
|
||||
{
|
||||
super();
|
||||
this.byteCode.endian = Endian.LITTLE_ENDIAN;
|
||||
this.name = name;
|
||||
if(array != null)
|
||||
{
|
||||
this.compileFromArray(array);
|
||||
}
|
||||
}
|
||||
|
||||
public static function compileFromArray(source:Array, name:String = null) : Procedure
|
||||
{
|
||||
return new Procedure(source,name);
|
||||
}
|
||||
|
||||
public static function compileFromString(source:String, name:String = null) : Procedure
|
||||
{
|
||||
var proc:Procedure = new Procedure(null,name);
|
||||
proc.compileFromString(source);
|
||||
return proc;
|
||||
}
|
||||
|
||||
private function addVariableUsage(v:Variable) : void
|
||||
{
|
||||
var vars:Vector.<Variable> = this.name_d2[v.type];
|
||||
var index:int = v.index;
|
||||
if(index >= vars.length)
|
||||
{
|
||||
vars.length = index + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.next = vars[index];
|
||||
}
|
||||
vars[index] = v;
|
||||
}
|
||||
|
||||
public function assignVariableName(type:uint, index:uint, name:String, size:uint = 1) : void
|
||||
{
|
||||
for(var v:Variable = this.name_d2[type][index]; v != null; )
|
||||
{
|
||||
v.size = size;
|
||||
v.name = name;
|
||||
v = v.next;
|
||||
}
|
||||
}
|
||||
|
||||
public function compileFromString(source:String) : void
|
||||
{
|
||||
var commands:Array = source.split("\n");
|
||||
this.compileFromArray(commands);
|
||||
}
|
||||
|
||||
public function compileFromArray(source:Array) : void
|
||||
{
|
||||
var cmd:String = null;
|
||||
var declaration:Array = null;
|
||||
var decArray:Array = null;
|
||||
var regType:String = null;
|
||||
var varIndex:int = 0;
|
||||
var varName:String = null;
|
||||
for(var i:int = 0; i < 7; i++)
|
||||
{
|
||||
this.name_d2[i] = new Vector.<Variable>();
|
||||
}
|
||||
this.byteCode.length = 0;
|
||||
this.name_A = 0;
|
||||
this.name_RT = 0;
|
||||
var declarationStrings:Vector.<String> = new Vector.<String>();
|
||||
var count:int = int(source.length);
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
cmd = source[i];
|
||||
declaration = cmd.match(/# *[acvs]\d{1,3} *= *[a-zA-Z0-9_]*/i);
|
||||
if(declaration != null && declaration.length > 0)
|
||||
{
|
||||
declarationStrings.push(declaration[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.writeCommand(cmd);
|
||||
}
|
||||
}
|
||||
for(i = 0,count = int(declarationStrings.length); i < count; )
|
||||
{
|
||||
decArray = declarationStrings[i].split("=");
|
||||
regType = decArray[0].match(/[acvs]/i);
|
||||
varIndex = int(int(decArray[0].match(/\d{1,3}/i)));
|
||||
varName = decArray[1].match(/[a-zA-Z0-9]*/i);
|
||||
switch(regType.toLowerCase())
|
||||
{
|
||||
case "a":
|
||||
this.assignVariableName(VariableType.ATTRIBUTE,varIndex,varName);
|
||||
break;
|
||||
case "c":
|
||||
this.assignVariableName(VariableType.CONSTANT,varIndex,varName);
|
||||
break;
|
||||
case "v":
|
||||
this.assignVariableName(VariableType.VARYING,varIndex,varName);
|
||||
break;
|
||||
case "s":
|
||||
this.assignVariableName(VariableType.SAMPLER,varIndex,varName);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public function assignConstantsArray(registersCount:uint = 1) : void
|
||||
{
|
||||
this.name_in = registersCount;
|
||||
}
|
||||
|
||||
private function writeCommand(source:String) : void
|
||||
{
|
||||
var destination:Variable = null;
|
||||
var source1:SourceVariable = null;
|
||||
var source2:Variable = null;
|
||||
var type:uint = 0;
|
||||
var s2v:SourceVariable = null;
|
||||
var commentIndex:int = int(source.indexOf("//"));
|
||||
if(commentIndex >= 0)
|
||||
{
|
||||
source = source.substr(0,commentIndex);
|
||||
}
|
||||
var operands:Array = source.match(/[A-Za-z]+(((\[.+\])|(\d+))(\.[xyzw]{1,4})?(\ *\<.*>)?)?/g);
|
||||
if(operands.length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var opCode:String = operands[0];
|
||||
if(opCode == "kil")
|
||||
{
|
||||
source1 = new SourceVariable(operands[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
destination = new DestinationVariable(operands[1]);
|
||||
source1 = new SourceVariable(operands[2]);
|
||||
this.addVariableUsage(destination);
|
||||
}
|
||||
this.addVariableUsage(source1);
|
||||
switch(opCode)
|
||||
{
|
||||
case "mov":
|
||||
type = CommandType.MOV;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "add":
|
||||
type = CommandType.ADD;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "sub":
|
||||
type = CommandType.SUB;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "mul":
|
||||
type = CommandType.MUL;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "div":
|
||||
type = CommandType.DIV;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "rcp":
|
||||
type = CommandType.RCP;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "min":
|
||||
type = CommandType.MIN;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "max":
|
||||
type = CommandType.MAX;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "frc":
|
||||
type = CommandType.FRC;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "sqt":
|
||||
type = CommandType.SQT;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "rsq":
|
||||
type = CommandType.RSQ;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "pow":
|
||||
type = CommandType.POW;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
this.name_RT += 3;
|
||||
break;
|
||||
case "log":
|
||||
type = CommandType.LOG;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "exp":
|
||||
type = CommandType.EXP;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "nrm":
|
||||
type = CommandType.NRM;
|
||||
this.name_RT += 3;
|
||||
break;
|
||||
case "sin":
|
||||
type = CommandType.SIN;
|
||||
this.name_RT += 8;
|
||||
break;
|
||||
case "cos":
|
||||
type = CommandType.COS;
|
||||
this.name_RT += 8;
|
||||
break;
|
||||
case "crs":
|
||||
type = CommandType.CRS;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
this.name_RT += 2;
|
||||
break;
|
||||
case "dp3":
|
||||
type = CommandType.DP3;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "dp4":
|
||||
type = CommandType.DP4;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "abs":
|
||||
type = CommandType.ABS;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "neg":
|
||||
type = CommandType.NEG;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "sat":
|
||||
type = CommandType.SAT;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "m33":
|
||||
type = CommandType.M33;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
this.name_RT += 3;
|
||||
break;
|
||||
case "m44":
|
||||
type = CommandType.M44;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
this.name_RT += 4;
|
||||
break;
|
||||
case "m34":
|
||||
type = CommandType.M34;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
this.name_RT += 3;
|
||||
break;
|
||||
case "kil":
|
||||
type = CommandType.KIL;
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "tex":
|
||||
type = CommandType.TEX;
|
||||
source2 = new SamplerVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "sge":
|
||||
type = CommandType.SGE;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
break;
|
||||
case "slt":
|
||||
type = CommandType.SLT;
|
||||
source2 = new SourceVariable(operands[3]);
|
||||
this.addVariableUsage(source2);
|
||||
++this.name_RT;
|
||||
}
|
||||
this.byteCode.writeUnsignedInt(type);
|
||||
if(destination != null)
|
||||
{
|
||||
destination.position = this.byteCode.position;
|
||||
this.byteCode.writeUnsignedInt(destination.name_0J);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.byteCode.writeUnsignedInt(0);
|
||||
}
|
||||
source1.position = this.byteCode.position;
|
||||
if(source1.relative != null)
|
||||
{
|
||||
this.addVariableUsage(source1.relative);
|
||||
source1.relative.position = this.byteCode.position;
|
||||
}
|
||||
this.byteCode.writeUnsignedInt(source1.name_0J);
|
||||
this.byteCode.writeUnsignedInt(source1.name_oc);
|
||||
if(source2 != null)
|
||||
{
|
||||
s2v = source2 as SourceVariable;
|
||||
source2.position = this.byteCode.position;
|
||||
if(s2v != null && s2v.relative != null)
|
||||
{
|
||||
this.addVariableUsage(s2v.relative);
|
||||
s2v.relative.position = s2v.position;
|
||||
}
|
||||
this.byteCode.writeUnsignedInt(source2.name_0J);
|
||||
this.byteCode.writeUnsignedInt(source2.name_oc);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.byteCode.position = this.byteCode.length = this.byteCode.length + 8;
|
||||
}
|
||||
++this.name_A;
|
||||
}
|
||||
|
||||
public function newInstance() : Procedure
|
||||
{
|
||||
var res:Procedure = new Procedure();
|
||||
res.byteCode = this.byteCode;
|
||||
res.name_d2 = this.name_d2;
|
||||
res.name_RT = this.name_RT;
|
||||
res.name_in = this.name_in;
|
||||
res.name_A = this.name_A;
|
||||
res.name = this.name;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class RelativeVariable extends Variable
|
||||
{
|
||||
public function RelativeVariable(source:String)
|
||||
{
|
||||
super();
|
||||
var relname:Array = source.match(/[A-Za-z]/g);
|
||||
index = parseInt(source.match(/\d+/g)[0],10);
|
||||
switch(relname[0])
|
||||
{
|
||||
case "a":
|
||||
type = VariableType.ATTRIBUTE;
|
||||
break;
|
||||
case "c":
|
||||
type = VariableType.CONSTANT;
|
||||
break;
|
||||
case "t":
|
||||
type = VariableType.TEMPORARY;
|
||||
break;
|
||||
case "i":
|
||||
type = VariableType.INPUT;
|
||||
}
|
||||
var selmatch:Array = source.match(/(\.[xyzw]{1,1})/);
|
||||
if(selmatch.length == 0)
|
||||
{
|
||||
throw new Error("error: bad index register select");
|
||||
}
|
||||
var relsel:int = selmatch[0].charCodeAt(1) - X_CHAR_CODE;
|
||||
if(relsel == -1)
|
||||
{
|
||||
relsel = 3;
|
||||
}
|
||||
var relofs:Array = source.match(/\+\d{1,3}/g);
|
||||
var reloffset:int = 0;
|
||||
if(relofs.length > 0)
|
||||
{
|
||||
reloffset = int(parseInt(relofs[0],10));
|
||||
}
|
||||
if(reloffset < 0 || reloffset > 255)
|
||||
{
|
||||
throw new Error("Error: index offset " + reloffset + " out of bounds. [0..255]");
|
||||
}
|
||||
name_0J = reloffset << 16 | index;
|
||||
name_oc |= type << 8;
|
||||
name_oc |= relsel << 16;
|
||||
name_oc |= 1 << 31;
|
||||
}
|
||||
|
||||
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int) : void
|
||||
{
|
||||
byteCode.position = position;
|
||||
byteCode.writeShort(newIndex);
|
||||
byteCode.position = position + 5;
|
||||
byteCode.writeByte(newType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class SamplerVariable extends Variable
|
||||
{
|
||||
public function SamplerVariable(source:String)
|
||||
{
|
||||
var opts:Array = null;
|
||||
var op:String = null;
|
||||
super();
|
||||
var strType:String = String(source.match(/[si]/g)[0]);
|
||||
switch(strType)
|
||||
{
|
||||
case "s":
|
||||
name_oc = VariableType.SAMPLER;
|
||||
break;
|
||||
case "i":
|
||||
name_oc = VariableType.INPUT;
|
||||
}
|
||||
index = parseInt(source.match(/\d+/g)[0],10);
|
||||
name_0J = index;
|
||||
var optsi:int = int(source.search(/<.*>/g));
|
||||
if(optsi != -1)
|
||||
{
|
||||
opts = source.substring(optsi).match(/(\w+)/g);
|
||||
}
|
||||
type = name_oc;
|
||||
var optsLength:uint = uint(opts.length);
|
||||
for(var i:int = 0; i < optsLength; )
|
||||
{
|
||||
op = opts[i];
|
||||
switch(op)
|
||||
{
|
||||
case "2d":
|
||||
name_oc &= ~0xF000;
|
||||
break;
|
||||
case "3d":
|
||||
name_oc &= ~0xF000;
|
||||
name_oc |= 8192;
|
||||
break;
|
||||
case "cube":
|
||||
name_oc &= ~0xF000;
|
||||
name_oc |= 4096;
|
||||
break;
|
||||
case "mipnearest":
|
||||
name_oc &= ~0x0F000000;
|
||||
name_oc |= 16777216;
|
||||
break;
|
||||
case "miplinear":
|
||||
name_oc &= ~0x0F000000;
|
||||
name_oc |= 33554432;
|
||||
break;
|
||||
case "mipnone":
|
||||
case "nomip":
|
||||
name_oc &= ~0x0F000000;
|
||||
break;
|
||||
case "nearest":
|
||||
name_oc &= ~4026531840;
|
||||
break;
|
||||
case "linear":
|
||||
name_oc &= ~4026531840;
|
||||
name_oc |= 268435456;
|
||||
break;
|
||||
case "centroid":
|
||||
name_oc |= 4294967296;
|
||||
break;
|
||||
case "single":
|
||||
name_oc |= 8589934592;
|
||||
break;
|
||||
case "depth":
|
||||
name_oc |= 17179869184;
|
||||
break;
|
||||
case "repeat":
|
||||
case "wrap":
|
||||
name_oc &= ~0xF00000;
|
||||
name_oc |= 1048576;
|
||||
break;
|
||||
case "clamp":
|
||||
name_oc &= ~0xF00000;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int) : void
|
||||
{
|
||||
super.writeToByteArray(byteCode,newIndex,newType);
|
||||
byteCode.position = position + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class SourceVariable extends Variable
|
||||
{
|
||||
public var relative:RelativeVariable;
|
||||
|
||||
public function SourceVariable(source:String)
|
||||
{
|
||||
var regmask:uint = 0;
|
||||
var isRel:Boolean = false;
|
||||
var cv:int = 0;
|
||||
var maskLength:uint = 0;
|
||||
var i:int = 0;
|
||||
super();
|
||||
var strType:String = String(source.match(/[catsoiv]/g)[0]);
|
||||
var relreg:Array = source.match(/\[.*\]/g);
|
||||
isRel = relreg.length > 0;
|
||||
if(isRel)
|
||||
{
|
||||
source = source.replace(relreg[0],"0");
|
||||
}
|
||||
else
|
||||
{
|
||||
index = parseInt(source.match(/\d+/g)[0],10);
|
||||
}
|
||||
var swizzle:Array = source.match(/\.[xyzw]{1,4}/);
|
||||
var maskmatch:String = Boolean(swizzle) ? swizzle[0] : null;
|
||||
if(Boolean(maskmatch))
|
||||
{
|
||||
regmask = 0;
|
||||
maskLength = uint(maskmatch.length);
|
||||
for(i = 1; i < maskLength; i++)
|
||||
{
|
||||
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
|
||||
if(cv == -1)
|
||||
{
|
||||
cv = 3;
|
||||
}
|
||||
regmask |= cv << (i - 1 << 1);
|
||||
}
|
||||
while(i <= 4)
|
||||
{
|
||||
regmask |= cv << (i - 1 << 1);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
regmask = 228;
|
||||
}
|
||||
name_0J = regmask << 24 | index;
|
||||
switch(strType)
|
||||
{
|
||||
case "a":
|
||||
type = VariableType.ATTRIBUTE;
|
||||
break;
|
||||
case "c":
|
||||
type = VariableType.CONSTANT;
|
||||
break;
|
||||
case "t":
|
||||
type = VariableType.TEMPORARY;
|
||||
break;
|
||||
case "o":
|
||||
type = VariableType.OUTPUT;
|
||||
break;
|
||||
case "v":
|
||||
type = VariableType.VARYING;
|
||||
break;
|
||||
case "i":
|
||||
type = VariableType.INPUT;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentError("Wrong source register type, must be \"a\" or \"c\" or \"t\" or \"o\" or \"v\" or \"i\", var = " + source);
|
||||
}
|
||||
name_oc = type;
|
||||
if(isRel)
|
||||
{
|
||||
this.relative = new RelativeVariable(relreg[0]);
|
||||
name_0J |= this.relative.name_0J;
|
||||
name_oc |= this.relative.name_oc;
|
||||
isRelative = true;
|
||||
}
|
||||
}
|
||||
|
||||
override public function get size() : uint
|
||||
{
|
||||
if(Boolean(this.relative))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return super.size;
|
||||
}
|
||||
|
||||
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int) : void
|
||||
{
|
||||
if(this.relative == null)
|
||||
{
|
||||
super.writeToByteArray(byteCode,newIndex,newType);
|
||||
}
|
||||
else
|
||||
{
|
||||
byteCode.position = position + 2;
|
||||
}
|
||||
byteCode.position = position + 4;
|
||||
byteCode.writeByte(newType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class Variable
|
||||
{
|
||||
private static var collector:Variable;
|
||||
|
||||
protected static const X_CHAR_CODE:Number = "x".charCodeAt(0);
|
||||
|
||||
public var name:String;
|
||||
|
||||
public var index:int;
|
||||
|
||||
public var type:uint;
|
||||
|
||||
public var position:uint = 0;
|
||||
|
||||
public var next:Variable;
|
||||
|
||||
public var name_0J:uint;
|
||||
|
||||
public var name_oc:uint;
|
||||
|
||||
public var isRelative:Boolean;
|
||||
|
||||
private var name_RS:uint = 1;
|
||||
|
||||
public function Variable()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static function create() : Variable
|
||||
{
|
||||
if(collector == null)
|
||||
{
|
||||
collector = new Variable();
|
||||
}
|
||||
var output:Variable = collector;
|
||||
collector = collector.next;
|
||||
output.next = null;
|
||||
return output;
|
||||
}
|
||||
|
||||
public function dispose() : void
|
||||
{
|
||||
this.next = collector;
|
||||
collector = this;
|
||||
}
|
||||
|
||||
public function get size() : uint
|
||||
{
|
||||
return this.name_RS;
|
||||
}
|
||||
|
||||
public function set size(value:uint) : void
|
||||
{
|
||||
this.name_RS = value;
|
||||
}
|
||||
|
||||
public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int) : void
|
||||
{
|
||||
byteCode.position = this.position;
|
||||
byteCode.writeShort(newIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package alternativa.engine3d.materials.compiler
|
||||
{
|
||||
public class VariableType
|
||||
{
|
||||
public static const ATTRIBUTE:uint = 0;
|
||||
|
||||
public static const CONSTANT:uint = 1;
|
||||
|
||||
public static const TEMPORARY:uint = 2;
|
||||
|
||||
public static const OUTPUT:uint = 3;
|
||||
|
||||
public static const VARYING:uint = 4;
|
||||
|
||||
public static const SAMPLER:uint = 5;
|
||||
|
||||
public static const INPUT:uint = 6;
|
||||
|
||||
public static const TYPE_NAMES:Vector.<String> = Vector.<String>(["attribute","constant","temporary","output","varying","sampler","input"]);
|
||||
|
||||
public function VariableType()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Decal extends Mesh
|
||||
{
|
||||
private static var transformProcedureStatic:Procedure = new Procedure(["sub t0.xyz, c0.xyz, i0.xyz","dp3 t0.w, t0.xyz, c1.xyz","mul t0.w, t0.w, c0.w","nrm t0.xyz, t0.xyz","mul t0.xyz, t0.xyz, t0.w","add o0.xyz, i0.xyz, t0.xyz","mov o0.w, c1.w","#c0=cPos","#c1=cDir"],"DecalTransformProcedure");
|
||||
|
||||
public var offset:Number;
|
||||
|
||||
public function Decal(offset:Number)
|
||||
{
|
||||
super();
|
||||
this.offset = offset;
|
||||
alternativa3d::transformProcedure = transformProcedureStatic;
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var surface:Surface = null;
|
||||
var debug:int = 0;
|
||||
for(var i:int = 0; i < name_Oy; )
|
||||
{
|
||||
surface = name_eW[i];
|
||||
if(surface.material != null)
|
||||
{
|
||||
surface.material.alternativa3d::collectDraws(camera,surface,geometry,lights,lightsLength,RenderPriority.DECALS);
|
||||
}
|
||||
if(alternativa3d::listening)
|
||||
{
|
||||
camera.view.alternativa3d::addSurfaceToMouseEvents(surface,geometry,alternativa3d::transformProcedure);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function setTransformConstants(drawUnit:DrawUnit, surface:Surface, vertexShader:Linker, camera:Camera3D) : void
|
||||
{
|
||||
var dx:Number = -alternativa3d::cameraToLocalTransform.c;
|
||||
var dy:Number = -alternativa3d::cameraToLocalTransform.g;
|
||||
var dz:Number = -alternativa3d::cameraToLocalTransform.k;
|
||||
var len:Number = this.offset / Math.sqrt(dx * dx + dy * dy + dz * dz) / camera.alternativa3d::focalLength;
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(vertexShader.getVariableIndex("cPos"),alternativa3d::cameraToLocalTransform.d,alternativa3d::cameraToLocalTransform.h,alternativa3d::cameraToLocalTransform.l,len);
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(vertexShader.getVariableIndex("cDir"),dx,dy,dz,1);
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Decal = new Decal(this.offset);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
this.offset = (source as Decal).offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Joint extends Object3D
|
||||
{
|
||||
alternativa3d var name_Dy:Transform3D = new Transform3D();
|
||||
|
||||
alternativa3d var bindPoseTransform:Transform3D = new Transform3D();
|
||||
|
||||
private var name_ar:Transform3D = new Transform3D();
|
||||
|
||||
public function Joint()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
alternativa3d function setBindPoseMatrix(matrix:Vector.<Number>) : void
|
||||
{
|
||||
this.alternativa3d::bindPoseTransform.initFromVector(matrix);
|
||||
}
|
||||
|
||||
alternativa3d function calculateTransform() : void
|
||||
{
|
||||
if(this.alternativa3d::bindPoseTransform != null)
|
||||
{
|
||||
this.name_Dy.combine(alternativa3d::localToGlobalTransform,this.alternativa3d::bindPoseTransform);
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Joint = new Joint();
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
var sourceJoint:Joint = null;
|
||||
super.clonePropertiesFrom(source);
|
||||
sourceJoint = source as Joint;
|
||||
this.alternativa3d::bindPoseTransform.a = sourceJoint.alternativa3d::bindPoseTransform.a;
|
||||
this.alternativa3d::bindPoseTransform.b = sourceJoint.alternativa3d::bindPoseTransform.b;
|
||||
this.alternativa3d::bindPoseTransform.c = sourceJoint.alternativa3d::bindPoseTransform.c;
|
||||
this.alternativa3d::bindPoseTransform.d = sourceJoint.alternativa3d::bindPoseTransform.d;
|
||||
this.alternativa3d::bindPoseTransform.e = sourceJoint.alternativa3d::bindPoseTransform.e;
|
||||
this.alternativa3d::bindPoseTransform.f = sourceJoint.alternativa3d::bindPoseTransform.f;
|
||||
this.alternativa3d::bindPoseTransform.g = sourceJoint.alternativa3d::bindPoseTransform.g;
|
||||
this.alternativa3d::bindPoseTransform.h = sourceJoint.alternativa3d::bindPoseTransform.h;
|
||||
this.alternativa3d::bindPoseTransform.i = sourceJoint.alternativa3d::bindPoseTransform.i;
|
||||
this.alternativa3d::bindPoseTransform.j = sourceJoint.alternativa3d::bindPoseTransform.j;
|
||||
this.alternativa3d::bindPoseTransform.k = sourceJoint.alternativa3d::bindPoseTransform.k;
|
||||
this.alternativa3d::bindPoseTransform.l = sourceJoint.alternativa3d::bindPoseTransform.l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.collisions.EllipsoidCollider;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RayIntersectionData;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Mesh extends Object3D
|
||||
{
|
||||
public var geometry:Geometry;
|
||||
|
||||
alternativa3d var name_eW:Vector.<Surface> = new Vector.<Surface>();
|
||||
|
||||
alternativa3d var name_Oy:int = 0;
|
||||
|
||||
public function Mesh()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
override public function intersectRay(origin:Vector3D, direction:Vector3D) : RayIntersectionData
|
||||
{
|
||||
var contentData:RayIntersectionData = null;
|
||||
var minTime:Number = NaN;
|
||||
var s:Surface = null;
|
||||
var data:RayIntersectionData = null;
|
||||
var childrenData:RayIntersectionData = super.intersectRay(origin,direction);
|
||||
if(boundBox != null && !boundBox.intersectRay(origin,direction))
|
||||
{
|
||||
contentData = null;
|
||||
}
|
||||
else if(this.geometry != null)
|
||||
{
|
||||
minTime = 1e+22;
|
||||
for each(s in this.name_eW)
|
||||
{
|
||||
data = this.geometry.alternativa3d::intersectRay(origin,direction,s.indexBegin,s.numTriangles);
|
||||
if(data != null && data.time < minTime)
|
||||
{
|
||||
contentData = data;
|
||||
contentData.object = this;
|
||||
contentData.surface = s;
|
||||
minTime = data.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(childrenData == null)
|
||||
{
|
||||
return contentData;
|
||||
}
|
||||
if(contentData == null)
|
||||
{
|
||||
return childrenData;
|
||||
}
|
||||
return childrenData.time < contentData.time ? childrenData : contentData;
|
||||
}
|
||||
|
||||
public function addSurface(material:Material, indexBegin:uint, numTriangles:uint) : Surface
|
||||
{
|
||||
var res:Surface = new Surface();
|
||||
res.alternativa3d::object = this;
|
||||
res.material = material;
|
||||
res.indexBegin = indexBegin;
|
||||
res.numTriangles = numTriangles;
|
||||
var _loc5_:* = this.name_Oy++;
|
||||
this.name_eW[_loc5_] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
public function getSurface(index:int) : Surface
|
||||
{
|
||||
return this.name_eW[index];
|
||||
}
|
||||
|
||||
public function get numSurfaces() : int
|
||||
{
|
||||
return this.name_Oy;
|
||||
}
|
||||
|
||||
public function setMaterialToAllSurfaces(material:Material) : void
|
||||
{
|
||||
for(var i:int = 0; i < this.name_eW.length; i++)
|
||||
{
|
||||
this.name_eW[i].material = material;
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function get useLights() : Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
override alternativa3d function updateBoundBox(boundBox:BoundBox, hierarchy:Boolean, transform:Transform3D = null) : void
|
||||
{
|
||||
super.alternativa3d::updateBoundBox(boundBox,hierarchy,transform);
|
||||
if(this.geometry != null)
|
||||
{
|
||||
this.geometry.alternativa3d::updateBoundBox(boundBox,transform);
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, hierarchy:Boolean = false, resourceType:Class = null) : void
|
||||
{
|
||||
var s:Surface = null;
|
||||
if(this.geometry != null && (resourceType == null || this.geometry is resourceType))
|
||||
{
|
||||
resources[this.geometry] = true;
|
||||
}
|
||||
for(var i:int = 0; i < this.name_Oy; )
|
||||
{
|
||||
s = this.name_eW[i];
|
||||
if(s.material != null)
|
||||
{
|
||||
s.material.alternativa3d::fillResources(resources,resourceType);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
super.alternativa3d::fillResources(resources,hierarchy,resourceType);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var surface:Surface = null;
|
||||
var debug:int = 0;
|
||||
for(var i:int = 0; i < this.name_Oy; )
|
||||
{
|
||||
surface = this.name_eW[i];
|
||||
if(surface.material != null)
|
||||
{
|
||||
surface.material.alternativa3d::collectDraws(camera,surface,this.geometry,lights,lightsLength);
|
||||
}
|
||||
if(alternativa3d::listening)
|
||||
{
|
||||
camera.view.alternativa3d::addSurfaceToMouseEvents(surface,this.geometry,alternativa3d::transformProcedure);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectGeometry(collider:EllipsoidCollider, excludedObjects:Dictionary) : void
|
||||
{
|
||||
collider.alternativa3d::geometries.push(this.geometry);
|
||||
collider.name_QK.push(alternativa3d::localToGlobalTransform);
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Mesh = new Mesh();
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
var s:Surface = null;
|
||||
super.clonePropertiesFrom(source);
|
||||
var mesh:Mesh = source as Mesh;
|
||||
this.geometry = mesh.geometry;
|
||||
this.name_Oy = 0;
|
||||
this.name_eW.length = 0;
|
||||
for each(s in mesh.name_eW)
|
||||
{
|
||||
this.addSurface(s.material,s.indexBegin,s.numTriangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,671 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Skin extends Mesh
|
||||
{
|
||||
private static var _transformProcedures:Dictionary = new Dictionary();
|
||||
|
||||
private static var _deltaTransformProcedures:Dictionary = new Dictionary();
|
||||
|
||||
public var name_WA:Vector.<Joint>;
|
||||
|
||||
alternativa3d var name_Cq:Vector.<Vector.<Joint>>;
|
||||
|
||||
alternativa3d var name_fB:Vector.<Procedure>;
|
||||
|
||||
alternativa3d var name_do:Vector.<Procedure>;
|
||||
|
||||
private var numJoints:int = 0;
|
||||
|
||||
private var maxInfluences:int = 0;
|
||||
|
||||
public function Skin(maxInfluences:int, numJoints:int)
|
||||
{
|
||||
super();
|
||||
this.numJoints = numJoints;
|
||||
this.maxInfluences = maxInfluences;
|
||||
this.name_WA = new Vector.<Joint>();
|
||||
this.name_Cq = new Vector.<Vector.<Joint>>();
|
||||
this.name_fB = new Vector.<Procedure>();
|
||||
this.name_do = new Vector.<Procedure>();
|
||||
alternativa3d::transformProcedure = this.calculateTransformProcedure(maxInfluences,numJoints);
|
||||
alternativa3d::deltaTransformProcedure = this.calculateDeltaTransformProcedure(maxInfluences,numJoints);
|
||||
}
|
||||
|
||||
override public function addSurface(material:Material, indexBegin:uint, numTriangles:uint) : Surface
|
||||
{
|
||||
this.name_fB[name_Oy] = alternativa3d::transformProcedure;
|
||||
this.name_do[name_Oy] = alternativa3d::deltaTransformProcedure;
|
||||
this.name_Cq[name_Oy] = this.name_WA;
|
||||
return super.addSurface(material,indexBegin,numTriangles);
|
||||
}
|
||||
|
||||
private function divideSurface(limit:uint, iterations:uint, surface:Surface, jointsOffsets:Vector.<uint>, jointBufferVertexSize:uint, inVertices:ByteArray, outVertices:ByteArray, outIndices:Vector.<uint>, outSurfaces:Vector.<Surface>, outJointsMaps:Vector.<Dictionary>) : uint
|
||||
{
|
||||
var i:int = 0;
|
||||
var j:int = 0;
|
||||
var count:int = 0;
|
||||
var jointsLength:int = 0;
|
||||
var index:uint = 0;
|
||||
var group:Dictionary = null;
|
||||
var key:* = undefined;
|
||||
var key2:* = undefined;
|
||||
var jointIndex:uint = 0;
|
||||
var weight:Number = NaN;
|
||||
var localNumJoints:uint = 0;
|
||||
var newIndexBegin:uint = 0;
|
||||
var jointsGroupLength:uint = 0;
|
||||
var n:int = 0;
|
||||
var faces:Dictionary = null;
|
||||
var locatedIndices:Dictionary = null;
|
||||
var resSurface:Surface = null;
|
||||
var origin:uint = 0;
|
||||
var sumWeight:Number = NaN;
|
||||
var indexBegin:uint = uint(surface.indexBegin);
|
||||
var indexCount:uint = uint(surface.numTriangles * 3);
|
||||
var indices:Vector.<uint> = geometry.alternativa3d::_indices;
|
||||
var groups:Dictionary = new Dictionary();
|
||||
for(i = int(indexBegin),count = int(indexBegin + indexCount); i < count; )
|
||||
{
|
||||
group = groups[i] = new Dictionary();
|
||||
jointsGroupLength = 0;
|
||||
for(n = 0; n < 3; n++)
|
||||
{
|
||||
index = indices[int(i + n)];
|
||||
for(j = 0,jointsLength = int(jointsOffsets.length); j < jointsLength; )
|
||||
{
|
||||
inVertices.position = jointBufferVertexSize * index + jointsOffsets[j];
|
||||
jointIndex = uint(uint(inVertices.readFloat()));
|
||||
weight = Number(inVertices.readFloat());
|
||||
if(weight > 0)
|
||||
{
|
||||
group[jointIndex] = true;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for(key in group)
|
||||
{
|
||||
jointsGroupLength++;
|
||||
}
|
||||
if(jointsGroupLength > limit)
|
||||
{
|
||||
throw new Error("Unable to divide Skin.");
|
||||
}
|
||||
i += 3;
|
||||
}
|
||||
var facesGroups:Dictionary = this.optimizeGroups(groups,limit,iterations);
|
||||
var newIndex:uint = 0;
|
||||
for(key in facesGroups)
|
||||
{
|
||||
faces = facesGroups[key];
|
||||
localNumJoints = 0;
|
||||
group = groups[key];
|
||||
for(key2 in group)
|
||||
{
|
||||
if(group[key2] is Boolean)
|
||||
{
|
||||
group[key2] = 3 * localNumJoints++;
|
||||
}
|
||||
}
|
||||
locatedIndices = new Dictionary();
|
||||
for(key2 in faces)
|
||||
{
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
index = indices[int(key2 + i)];
|
||||
if(locatedIndices[index] != null)
|
||||
{
|
||||
outIndices.push(locatedIndices[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
locatedIndices[index] = newIndex;
|
||||
outIndices.push(newIndex++);
|
||||
outVertices.writeBytes(inVertices,index * jointBufferVertexSize,jointBufferVertexSize);
|
||||
outVertices.position -= jointBufferVertexSize;
|
||||
origin = uint(outVertices.position);
|
||||
sumWeight = 0;
|
||||
for(j = 0; j < jointsLength; )
|
||||
{
|
||||
outVertices.position = origin + jointsOffsets[j];
|
||||
jointIndex = uint(uint(outVertices.readFloat()));
|
||||
weight = Number(outVertices.readFloat());
|
||||
outVertices.position -= 8;
|
||||
if(weight > 0)
|
||||
{
|
||||
outVertices.writeFloat(group[jointIndex]);
|
||||
outVertices.writeFloat(weight);
|
||||
sumWeight += weight;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if(sumWeight != 1)
|
||||
{
|
||||
for(j = 0; j < jointsLength; )
|
||||
{
|
||||
outVertices.position = origin + jointsOffsets[j] + 4;
|
||||
weight = Number(outVertices.readFloat());
|
||||
if(weight > 0)
|
||||
{
|
||||
outVertices.position -= 4;
|
||||
outVertices.writeFloat(weight / sumWeight);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
outVertices.position = origin + jointBufferVertexSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
resSurface = new Surface();
|
||||
resSurface.alternativa3d::object = this;
|
||||
resSurface.material = surface.material;
|
||||
resSurface.indexBegin = newIndexBegin;
|
||||
resSurface.numTriangles = (outIndices.length - newIndexBegin) / 3;
|
||||
outSurfaces.push(resSurface);
|
||||
outJointsMaps.push(group);
|
||||
newIndexBegin = uint(outIndices.length);
|
||||
}
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
private function optimizeGroups(groups:Dictionary, limit:uint, iterations:uint = 1) : Dictionary
|
||||
{
|
||||
var key:* = undefined;
|
||||
var inKey:* = undefined;
|
||||
var minLike:Number = NaN;
|
||||
var group1:Dictionary = null;
|
||||
var group2:Dictionary = null;
|
||||
var like:Number = NaN;
|
||||
var copyKey:* = undefined;
|
||||
var indices:Dictionary = null;
|
||||
var indices2:Dictionary = null;
|
||||
var facesGroups:Dictionary = new Dictionary();
|
||||
for(var i:int = 1; i < iterations + 1; i++)
|
||||
{
|
||||
minLike = 1 - i / iterations;
|
||||
for(key in groups)
|
||||
{
|
||||
group1 = groups[key];
|
||||
for(inKey in groups)
|
||||
{
|
||||
if(key != inKey)
|
||||
{
|
||||
group2 = groups[inKey];
|
||||
like = this.calculateLikeFactor(group1,group2,limit);
|
||||
if(like >= minLike)
|
||||
{
|
||||
delete groups[inKey];
|
||||
for(copyKey in group2)
|
||||
{
|
||||
group1[copyKey] = true;
|
||||
}
|
||||
indices = facesGroups[key];
|
||||
if(indices == null)
|
||||
{
|
||||
indices = facesGroups[key] = new Dictionary();
|
||||
indices[key] = true;
|
||||
}
|
||||
indices2 = facesGroups[inKey];
|
||||
if(indices2 != null)
|
||||
{
|
||||
delete facesGroups[inKey];
|
||||
for(copyKey in indices2)
|
||||
{
|
||||
indices[copyKey] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
indices[inKey] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return facesGroups;
|
||||
}
|
||||
|
||||
private function calculateLikeFactor(group1:Dictionary, group2:Dictionary, limit:uint) : Number
|
||||
{
|
||||
var key:* = undefined;
|
||||
var unionCount:uint = 0;
|
||||
var intersectCount:uint = 0;
|
||||
var group1Count:uint = 0;
|
||||
var group2Count:uint = 0;
|
||||
for(key in group1)
|
||||
{
|
||||
unionCount++;
|
||||
if(group2[key] != null)
|
||||
{
|
||||
intersectCount++;
|
||||
}
|
||||
group1Count++;
|
||||
}
|
||||
for(key in group2)
|
||||
{
|
||||
if(group1[key] == null)
|
||||
{
|
||||
unionCount++;
|
||||
}
|
||||
group2Count++;
|
||||
}
|
||||
if(unionCount > limit)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return intersectCount / unionCount;
|
||||
}
|
||||
|
||||
public function divide(limit:uint, iterations:uint = 1) : void
|
||||
{
|
||||
var key:* = undefined;
|
||||
var outIndices:Vector.<uint> = null;
|
||||
var outVertices:ByteArray = null;
|
||||
var outJointsMaps:Vector.<Dictionary> = null;
|
||||
var maxIndex:uint = 0;
|
||||
var j:int = 0;
|
||||
var count:int = 0;
|
||||
var maxJoints:uint = 0;
|
||||
var vec:Vector.<Joint> = null;
|
||||
var joints:Dictionary = null;
|
||||
var index:uint = 0;
|
||||
var attributes:Array = null;
|
||||
var _loc30_:ByteArray = null;
|
||||
var jointsBuffer:int = geometry.findVertexStreamByAttribute(VertexAttributes.JOINTS[0]);
|
||||
var jointsOffsets:Vector.<uint> = new Vector.<uint>();
|
||||
var jointOffset:int = 0;
|
||||
if(jointsBuffer >= 0)
|
||||
{
|
||||
jointOffset = geometry.getAttributeOffset(VertexAttributes.JOINTS[0]) * 4;
|
||||
jointsOffsets.push(jointOffset);
|
||||
jointsOffsets.push(jointOffset + 8);
|
||||
var jbTest:int = geometry.findVertexStreamByAttribute(VertexAttributes.JOINTS[1]);
|
||||
if(jbTest >= 0)
|
||||
{
|
||||
jointOffset = geometry.getAttributeOffset(VertexAttributes.JOINTS[1]) * 4;
|
||||
jointsOffsets.push(jointOffset);
|
||||
jointsOffsets.push(jointOffset + 8);
|
||||
if(jointsBuffer != jbTest)
|
||||
{
|
||||
throw new Error("Cannot divide skin, all joinst must be in the same buffer");
|
||||
}
|
||||
}
|
||||
jbTest = geometry.findVertexStreamByAttribute(VertexAttributes.JOINTS[2]);
|
||||
if(jbTest >= 0)
|
||||
{
|
||||
jointOffset = geometry.getAttributeOffset(VertexAttributes.JOINTS[2]) * 4;
|
||||
jointsOffsets.push(jointOffset);
|
||||
jointsOffsets.push(jointOffset + 8);
|
||||
if(jointsBuffer != jbTest)
|
||||
{
|
||||
throw new Error("Cannot divide skin, all joinst must be in the same buffer");
|
||||
}
|
||||
}
|
||||
jbTest = geometry.findVertexStreamByAttribute(VertexAttributes.JOINTS[3]);
|
||||
if(jbTest >= 0)
|
||||
{
|
||||
jointOffset = geometry.getAttributeOffset(VertexAttributes.JOINTS[3]) * 4;
|
||||
jointsOffsets.push(jointOffset);
|
||||
jointsOffsets.push(jointOffset + 8);
|
||||
if(jointsBuffer != jbTest)
|
||||
{
|
||||
throw new Error("Cannot divide skin, all joinst must be in the same buffer");
|
||||
}
|
||||
}
|
||||
var outSurfaces:Vector.<Surface> = new Vector.<Surface>();
|
||||
var totalVertices:ByteArray = new ByteArray();
|
||||
totalVertices.endian = Endian.LITTLE_ENDIAN;
|
||||
var totalIndices:Vector.<uint> = new Vector.<uint>();
|
||||
var totalIndicesLength:uint = 0;
|
||||
var lastMaxIndex:uint = 0;
|
||||
var lastSurfaceIndex:uint = 0;
|
||||
var lastIndicesCount:uint = 0;
|
||||
this.name_Cq.length = 0;
|
||||
var jointsBufferNumMappings:int = int(geometry.alternativa3d::_vertexStreams[jointsBuffer].attributes.length);
|
||||
var jointsBufferData:ByteArray = geometry.alternativa3d::_vertexStreams[jointsBuffer].data;
|
||||
for(var i:int = 0; i < name_Oy; i++)
|
||||
{
|
||||
outIndices = new Vector.<uint>();
|
||||
outVertices = new ByteArray();
|
||||
outJointsMaps = new Vector.<Dictionary>();
|
||||
outVertices.endian = Endian.LITTLE_ENDIAN;
|
||||
maxIndex = this.divideSurface(limit,iterations,name_eW[i],jointsOffsets,jointsBufferNumMappings * 4,jointsBufferData,outVertices,outIndices,outSurfaces,outJointsMaps);
|
||||
for(j = 0,count = int(outIndices.length); j < count; j++)
|
||||
{
|
||||
var _loc31_:* = totalIndicesLength++;
|
||||
totalIndices[_loc31_] = lastMaxIndex + outIndices[j];
|
||||
}
|
||||
for(j = 0,count = int(outJointsMaps.length); j < count; j++)
|
||||
{
|
||||
maxJoints = 0;
|
||||
vec = this.name_Cq[j + lastSurfaceIndex] = new Vector.<Joint>();
|
||||
joints = outJointsMaps[j];
|
||||
for(key in joints)
|
||||
{
|
||||
index = uint(uint(joints[key] / 3));
|
||||
if(vec.length < index)
|
||||
{
|
||||
vec.length = index + 1;
|
||||
}
|
||||
vec[index] = this.name_WA[uint(key / 3)];
|
||||
maxJoints++;
|
||||
}
|
||||
}
|
||||
for(j = int(lastSurfaceIndex); j < outSurfaces.length; j++)
|
||||
{
|
||||
outSurfaces[j].indexBegin += lastIndicesCount;
|
||||
}
|
||||
lastSurfaceIndex += outJointsMaps.length;
|
||||
lastIndicesCount += outIndices.length;
|
||||
totalVertices.writeBytes(outVertices,0,outVertices.length);
|
||||
lastMaxIndex += maxIndex;
|
||||
}
|
||||
name_eW = outSurfaces;
|
||||
name_Oy = outSurfaces.length;
|
||||
this.name_fB.length = name_Oy;
|
||||
this.name_do.length = name_Oy;
|
||||
for(i = 0; i < name_Oy; i++)
|
||||
{
|
||||
this.name_fB[i] = this.calculateTransformProcedure(this.maxInfluences,this.name_Cq[i].length);
|
||||
this.name_do[i] = this.calculateDeltaTransformProcedure(this.maxInfluences,this.name_Cq[i].length);
|
||||
}
|
||||
var newGeometry:Geometry = new Geometry();
|
||||
newGeometry.alternativa3d::_indices = totalIndices;
|
||||
for(i = 0; i < geometry.alternativa3d::_vertexStreams.length; i++)
|
||||
{
|
||||
attributes = geometry.alternativa3d::_vertexStreams[i].attributes;
|
||||
newGeometry.addVertexStream(attributes);
|
||||
if(i == jointsBuffer)
|
||||
{
|
||||
newGeometry.alternativa3d::_vertexStreams[i].data = totalVertices;
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc30_ = new ByteArray();
|
||||
_loc30_.endian = Endian.LITTLE_ENDIAN;
|
||||
_loc30_.writeBytes(geometry.alternativa3d::_vertexStreams[i].data);
|
||||
newGeometry.alternativa3d::_vertexStreams[i].data = _loc30_;
|
||||
}
|
||||
}
|
||||
newGeometry.alternativa3d::_numVertices = totalVertices.length / (newGeometry.alternativa3d::_vertexStreams[0].attributes.length << 2);
|
||||
geometry = newGeometry;
|
||||
return;
|
||||
}
|
||||
throw new Error("Cannot divide skin, joints[0] must be binded");
|
||||
}
|
||||
|
||||
private function calculateJointsTransforms(root:Object3D) : void
|
||||
{
|
||||
for(var child:Object3D = root.alternativa3d::childrenList; child != null; child = child.alternativa3d::next)
|
||||
{
|
||||
if(child.alternativa3d::transformChanged)
|
||||
{
|
||||
child.alternativa3d::composeTransforms();
|
||||
}
|
||||
child.alternativa3d::localToGlobalTransform.combine(root.alternativa3d::localToGlobalTransform,child.alternativa3d::transform);
|
||||
if(child is Joint)
|
||||
{
|
||||
Joint(child).alternativa3d::calculateTransform();
|
||||
}
|
||||
this.calculateJointsTransforms(child);
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var surface:Surface = null;
|
||||
var debug:int = 0;
|
||||
if(geometry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(var child:Object3D = alternativa3d::childrenList; child != null; )
|
||||
{
|
||||
if(child.alternativa3d::transformChanged)
|
||||
{
|
||||
child.alternativa3d::composeTransforms();
|
||||
}
|
||||
child.alternativa3d::localToGlobalTransform.copy(child.alternativa3d::transform);
|
||||
if(child is Joint)
|
||||
{
|
||||
Joint(child).alternativa3d::calculateTransform();
|
||||
}
|
||||
this.calculateJointsTransforms(child);
|
||||
child = child.alternativa3d::next;
|
||||
}
|
||||
for(var i:int = 0; i < name_Oy; )
|
||||
{
|
||||
surface = name_eW[i];
|
||||
alternativa3d::transformProcedure = this.name_fB[i];
|
||||
alternativa3d::deltaTransformProcedure = this.name_do[i];
|
||||
if(surface.material != null)
|
||||
{
|
||||
surface.material.alternativa3d::collectDraws(camera,surface,geometry,lights,lightsLength);
|
||||
}
|
||||
if(alternativa3d::listening)
|
||||
{
|
||||
camera.view.alternativa3d::addSurfaceToMouseEvents(surface,geometry,alternativa3d::transformProcedure);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function setTransformConstants(drawUnit:DrawUnit, surface:Surface, vertexShader:Linker, camera:Camera3D) : void
|
||||
{
|
||||
var i:int = 0;
|
||||
var count:int = 0;
|
||||
var attribute:int = 0;
|
||||
var joint:Joint = null;
|
||||
for(i = 0; i < this.maxInfluences; i += 2)
|
||||
{
|
||||
attribute = int(VertexAttributes.JOINTS[i >> 1]);
|
||||
drawUnit.alternativa3d::setVertexBufferAt(vertexShader.getVariableIndex("joint" + i.toString()),geometry.alternativa3d::getVertexBuffer(attribute),geometry.alternativa3d::_attributesOffsets[attribute],VertexAttributes.alternativa3d::FORMATS[attribute]);
|
||||
}
|
||||
var surfaceIndex:int = int(name_eW.indexOf(surface));
|
||||
var joints:Vector.<Joint> = this.name_Cq[surfaceIndex];
|
||||
for(i = 0,count = int(joints.length); i < count; i++)
|
||||
{
|
||||
joint = joints[i];
|
||||
drawUnit.alternativa3d::setVertexConstantsFromTransform(i * 3,joint.name_Dy);
|
||||
}
|
||||
}
|
||||
|
||||
private function calculateTransformProcedure(maxInfluences:int, numJoints:int) : Procedure
|
||||
{
|
||||
var joint:int = 0;
|
||||
var res:Procedure = _transformProcedures[maxInfluences | numJoints << 16];
|
||||
if(res != null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res = _transformProcedures[maxInfluences | numJoints << 16] = new Procedure(null,"SkinTransformProcedure");
|
||||
var array:Array = [];
|
||||
var j:int = 0;
|
||||
for(var i:int = 0; i < maxInfluences; i++)
|
||||
{
|
||||
joint = int(int(i / 2));
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
var _loc8_:* = j++;
|
||||
array[_loc8_] = "m34 t0.xyz, i0, c[a" + joint + ".x]";
|
||||
var _loc9_:* = j++;
|
||||
array[_loc9_] = "mul o0, t0.xyz, a" + joint + ".y";
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "m34 t0.xyz, i0, c[a" + joint + ".x]";
|
||||
_loc9_ = j++;
|
||||
array[_loc9_] = "mul t0.xyz, t0.xyz, a" + joint + ".y";
|
||||
var _loc10_:* = j++;
|
||||
array[_loc10_] = "add o0, o0, t0.xyz";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "m34 t0.xyz, i0, c[a" + joint + ".z]";
|
||||
_loc9_ = j++;
|
||||
array[_loc9_] = "mul t0.xyz, t0.xyz, a" + joint + ".w";
|
||||
_loc10_ = j++;
|
||||
array[_loc10_] = "add o0, o0, t0.xyz";
|
||||
}
|
||||
}
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "mov o0.w, i0.w";
|
||||
res.compileFromArray(array);
|
||||
res.assignConstantsArray(numJoints * 3);
|
||||
for(i = 0; i < maxInfluences; i += 2)
|
||||
{
|
||||
res.assignVariableName(VariableType.ATTRIBUTE,int(i / 2),"joint" + i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private function calculateDeltaTransformProcedure(maxInfluences:int, numJoints:int) : Procedure
|
||||
{
|
||||
var joint:int = 0;
|
||||
var res:Procedure = _deltaTransformProcedures[maxInfluences | numJoints << 16];
|
||||
if(res != null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
res = _deltaTransformProcedures[maxInfluences | numJoints << 16] = new Procedure(null,"SkinDeltaTransformProcedure");
|
||||
var array:Array = [];
|
||||
var j:int = 0;
|
||||
for(var i:int = 0; i < maxInfluences; i++)
|
||||
{
|
||||
joint = int(int(i / 2));
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
var _loc8_:* = j++;
|
||||
array[_loc8_] = "m33 t0.xyz, i0, c[a" + joint + ".x]";
|
||||
var _loc9_:* = j++;
|
||||
array[_loc9_] = "mul o0, t0.xyz, a" + joint + ".y";
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "m33 t0.xyz, i0, c[a" + joint + ".x]";
|
||||
_loc9_ = j++;
|
||||
array[_loc9_] = "mul t0.xyz, t0.xyz, a" + joint + ".y";
|
||||
var _loc10_:* = j++;
|
||||
array[_loc10_] = "add o0, o0, t0.xyz";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "m33 t0.xyz, i0, c[a" + joint + ".z]";
|
||||
_loc9_ = j++;
|
||||
array[_loc9_] = "mul t0.xyz, t0.xyz, a" + joint + ".w";
|
||||
_loc10_ = j++;
|
||||
array[_loc10_] = "add o0, o0, t0.xyz";
|
||||
}
|
||||
}
|
||||
_loc8_ = j++;
|
||||
array[_loc8_] = "mov o0.w, i0.w";
|
||||
_loc9_ = j++;
|
||||
array[_loc9_] = "nrm o0.xyz, o0.xyz";
|
||||
res.compileFromArray(array);
|
||||
for(i = 0; i < maxInfluences; i += 2)
|
||||
{
|
||||
res.assignVariableName(VariableType.ATTRIBUTE,int(i / 2),"joint" + i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Skin = new Skin(this.maxInfluences,this.numJoints);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
var skin:Skin = Skin(source);
|
||||
if(skin.name_WA != null)
|
||||
{
|
||||
this.name_WA = this.cloneJointsVector(skin.name_WA,skin);
|
||||
}
|
||||
for(var i:int = 0; i < name_Oy; )
|
||||
{
|
||||
this.name_Cq[i] = this.cloneJointsVector(skin.name_Cq[i],skin);
|
||||
this.name_fB[i] = this.calculateTransformProcedure(this.maxInfluences,this.name_Cq[i].length);
|
||||
this.name_do[i] = this.calculateDeltaTransformProcedure(this.maxInfluences,this.name_Cq[i].length);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function cloneJointsVector(joints:Vector.<Joint>, skin:Skin) : Vector.<Joint>
|
||||
{
|
||||
var joint:Joint = null;
|
||||
var count:int = int(joints.length);
|
||||
var result:Vector.<Joint> = new Vector.<Joint>();
|
||||
for(var i:int = 0; i < count; i++)
|
||||
{
|
||||
joint = joints[i];
|
||||
result[i] = Joint(this.findClonedJoint(joint,skin,this));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private function findClonedJoint(joint:Joint, parentSource:Object3D, parentDest:Object3D) : Object3D
|
||||
{
|
||||
var j:Object3D = null;
|
||||
for(var srcChild:Object3D = parentSource.alternativa3d::childrenList, dstChild:Object3D = parentDest.alternativa3d::childrenList; srcChild != null; )
|
||||
{
|
||||
if(srcChild == joint)
|
||||
{
|
||||
return dstChild;
|
||||
}
|
||||
if(srcChild.alternativa3d::childrenList != null)
|
||||
{
|
||||
j = this.findClonedJoint(joint,srcChild,dstChild);
|
||||
if(j != null)
|
||||
{
|
||||
return j;
|
||||
}
|
||||
}
|
||||
srcChild = srcChild.alternativa3d::next;
|
||||
dstChild = dstChild.alternativa3d::next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class SkyBox extends Mesh
|
||||
{
|
||||
public static const LEFT:String = "left";
|
||||
|
||||
public static const RIGHT:String = "right";
|
||||
|
||||
public static const BACK:String = "back";
|
||||
|
||||
public static const FRONT:String = "front";
|
||||
|
||||
public static const BOTTOM:String = "bottom";
|
||||
|
||||
public static const TOP:String = "top";
|
||||
|
||||
private static var transformProcedureStatic:Procedure = new Procedure(["sub t0.xyz, i0.xyz, c0.xyz","mul t0.x, t0.x, c0.w","mul t0.y, t0.y, c0.w","mul t0.z, t0.z, c0.w","add o0.xyz, t0.xyz, c0.xyz","mov o0.w, i0.w","#c0=cTrans"]);
|
||||
|
||||
private var name_gj:Surface;
|
||||
|
||||
private var name_69:Surface;
|
||||
|
||||
private var name_EB:Surface;
|
||||
|
||||
private var name_iw:Surface;
|
||||
|
||||
private var name_1V:Surface;
|
||||
|
||||
private var name_Oz:Surface;
|
||||
|
||||
private var size:Number;
|
||||
|
||||
public function SkyBox(size:Number, left:Material = null, right:Material = null, back:Material = null, front:Material = null, bottom:Material = null, top:Material = null, uvPadding:Number = 0)
|
||||
{
|
||||
super();
|
||||
size *= 0.5;
|
||||
this.size = size;
|
||||
geometry = new Geometry(24);
|
||||
var attributes:Array = new Array();
|
||||
attributes[0] = VertexAttributes.POSITION;
|
||||
attributes[1] = VertexAttributes.POSITION;
|
||||
attributes[2] = VertexAttributes.POSITION;
|
||||
attributes[6] = VertexAttributes.TEXCOORDS[0];
|
||||
attributes[7] = VertexAttributes.TEXCOORDS[0];
|
||||
geometry.addVertexStream(attributes);
|
||||
geometry.setAttributeValues(VertexAttributes.POSITION,Vector.<Number>([-size,-size,size,-size,-size,-size,-size,size,-size,-size,size,size,size,size,size,size,size,-size,size,-size,-size,size,-size,size,size,-size,size,size,-size,-size,-size,-size,-size,-size,-size,size,-size,size,size,-size,size,-size,size,size,-size,size,size,size,-size,size,-size,-size,-size,-size,size,-size,-size,size,size,-size,-size,-size,size,-size,size,size,size,size,size,size,-size,size]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[0],Vector.<Number>([uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding,uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding,uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding,uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding,uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding,uvPadding,uvPadding,uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,1 - uvPadding,uvPadding]));
|
||||
geometry.indices = Vector.<uint>([0,1,3,2,3,1,4,5,7,6,7,5,8,9,11,10,11,9,12,13,15,14,15,13,16,17,19,18,19,17,20,21,23,22,23,21]);
|
||||
this.name_gj = addSurface(left,0,2);
|
||||
this.name_69 = addSurface(right,6,2);
|
||||
this.name_EB = addSurface(back,12,2);
|
||||
this.name_iw = addSurface(front,18,2);
|
||||
this.name_1V = addSurface(bottom,24,2);
|
||||
this.name_Oz = addSurface(top,30,2);
|
||||
alternativa3d::transformProcedure = transformProcedureStatic;
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var surface:Surface = null;
|
||||
for(var i:int = 0; i < name_Oy; )
|
||||
{
|
||||
surface = name_eW[i];
|
||||
if(surface.material != null)
|
||||
{
|
||||
surface.material.alternativa3d::collectDraws(camera,surface,geometry,lights,lightsLength,RenderPriority.SKY);
|
||||
}
|
||||
if(alternativa3d::listening)
|
||||
{
|
||||
camera.view.alternativa3d::addSurfaceToMouseEvents(surface,geometry,alternativa3d::transformProcedure);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function setTransformConstants(drawUnit:DrawUnit, surface:Surface, vertexShader:Linker, camera:Camera3D) : void
|
||||
{
|
||||
var dx:Number = NaN;
|
||||
var dy:Number = NaN;
|
||||
var dz:Number = NaN;
|
||||
var len:Number = NaN;
|
||||
var max:Number = 0;
|
||||
dx = -this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = -this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = -this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = -this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = -this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = -this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = -this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = -this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = -this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = -this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = -this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
dx = -this.size - alternativa3d::cameraToLocalTransform.d;
|
||||
dy = this.size - alternativa3d::cameraToLocalTransform.h;
|
||||
dz = this.size - alternativa3d::cameraToLocalTransform.l;
|
||||
len = dx * dx + dy * dy + dz * dz;
|
||||
if(len > max)
|
||||
{
|
||||
max = len;
|
||||
}
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(0,alternativa3d::cameraToLocalTransform.d,alternativa3d::cameraToLocalTransform.h,alternativa3d::cameraToLocalTransform.l,camera.farClipping / Math.sqrt(max));
|
||||
}
|
||||
|
||||
public function getSide(side:String) : Surface
|
||||
{
|
||||
switch(side)
|
||||
{
|
||||
case LEFT:
|
||||
return this.name_gj;
|
||||
case RIGHT:
|
||||
return this.name_69;
|
||||
case BACK:
|
||||
return this.name_EB;
|
||||
case FRONT:
|
||||
return this.name_iw;
|
||||
case BOTTOM:
|
||||
return this.name_1V;
|
||||
case TOP:
|
||||
return this.name_Oz;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:SkyBox = new SkyBox(0);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
var surface:Surface = null;
|
||||
var newSurface:Surface = null;
|
||||
super.clonePropertiesFrom(source);
|
||||
var src:SkyBox = source as SkyBox;
|
||||
for(var i:int = 0; i < src.name_Oy; )
|
||||
{
|
||||
surface = src.name_eW[i];
|
||||
newSurface = name_eW[i];
|
||||
if(surface == src.name_gj)
|
||||
{
|
||||
this.name_gj = newSurface;
|
||||
}
|
||||
else if(surface == src.name_69)
|
||||
{
|
||||
this.name_69 = newSurface;
|
||||
}
|
||||
else if(surface == src.name_EB)
|
||||
{
|
||||
this.name_EB = newSurface;
|
||||
}
|
||||
else if(surface == src.name_iw)
|
||||
{
|
||||
this.name_iw = newSurface;
|
||||
}
|
||||
else if(surface == src.name_1V)
|
||||
{
|
||||
this.name_1V = newSurface;
|
||||
}
|
||||
else if(surface == src.name_Oz)
|
||||
{
|
||||
this.name_Oz = newSurface;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Debug;
|
||||
import alternativa.engine3d.core.DrawUnit;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.RenderPriority;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Sprite3D extends Object3D
|
||||
{
|
||||
private static const geometries:Dictionary = new Dictionary();
|
||||
|
||||
private static var transformProcedureStatic:Procedure = new Procedure(["sub t0.z, i0.x, c3.x","sub t0.w, i0.y, c3.y","mul t0.z, t0.z, c3.z","mul t0.w, t0.w, c3.w","mov t1.z, c4.w","sin t1.x, t1.z","cos t1.y, t1.z","mul t1.z, t0.z, t1.y","mul t1.w, t0.w, t1.x","sub t0.x, t1.z, t1.w","mul t1.z, t0.z, t1.x","mul t1.w, t0.w, t1.y","add t0.y, t1.z, t1.w","add t0.x, t0.x, c4.x","add t0.y, t0.y, c4.y","add t0.z, i0.z, c4.z","mov t0.w, i0.w","dp4 o0.x, t0, c0","dp4 o0.y, t0, c1","dp4 o0.z, t0, c2","mov o0.w, t0.w","#c0=trans1","#c1=trans2","#c2=trans3","#c3=size","#c4=coords"]);
|
||||
|
||||
private static var deltaTransformProcedureStatic:Procedure = new Procedure(["mov t1.z, c4.w","sin t1.x, t1.z","cos t1.y, t1.z","mul t1.z, i0.x, t1.y","mul t1.w, i0.y, t1.x","sub t0.x, t1.z, t1.w","mul t1.z, i0.x, t1.x","mul t1.w, i0.y, t1.y","add t0.y, t1.z, t1.w","mov t0.z, i0.z","mov t0.w, i0.w","dp3 o0.x, t0, c0","dp3 o0.y, t0, c1","dp3 o0.z, t0, c2","#c0=trans1","#c1=trans2","#c2=trans3","#c3=size","#c4=coords"]);
|
||||
|
||||
public var originX:Number = 0.5;
|
||||
|
||||
public var originY:Number = 0.5;
|
||||
|
||||
public var rotation:Number = 0;
|
||||
|
||||
public var width:Number;
|
||||
|
||||
public var height:Number;
|
||||
|
||||
public var perspectiveScale:Boolean = true;
|
||||
|
||||
public var alwaysOnTop:Boolean = false;
|
||||
|
||||
alternativa3d var surface:Surface;
|
||||
|
||||
public function Sprite3D(width:Number, height:Number, material:Material = null)
|
||||
{
|
||||
super();
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.alternativa3d::surface = new Surface();
|
||||
this.alternativa3d::surface.alternativa3d::object = this;
|
||||
this.material = material;
|
||||
this.alternativa3d::surface.indexBegin = 0;
|
||||
this.alternativa3d::surface.numTriangles = 2;
|
||||
alternativa3d::transformProcedure = transformProcedureStatic;
|
||||
alternativa3d::deltaTransformProcedure = deltaTransformProcedureStatic;
|
||||
}
|
||||
|
||||
public function get material() : Material
|
||||
{
|
||||
return this.alternativa3d::surface.material;
|
||||
}
|
||||
|
||||
public function set material(value:Material) : void
|
||||
{
|
||||
this.alternativa3d::surface.material = value;
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, hierarchy:Boolean = false, resourceType:Class = null) : void
|
||||
{
|
||||
if(this.alternativa3d::surface.material != null)
|
||||
{
|
||||
this.alternativa3d::surface.material.alternativa3d::fillResources(resources,resourceType);
|
||||
}
|
||||
super.alternativa3d::fillResources(resources,hierarchy,resourceType);
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
var debug:int = 0;
|
||||
var geometry:Geometry = this.alternativa3d::getGeometry(camera.alternativa3d::context3D);
|
||||
if(this.alternativa3d::surface.material != null)
|
||||
{
|
||||
this.alternativa3d::surface.material.alternativa3d::collectDraws(camera,this.alternativa3d::surface,geometry,lights,lightsLength,this.alwaysOnTop ? RenderPriority.NEXT_LAYER : -1);
|
||||
}
|
||||
if(alternativa3d::listening)
|
||||
{
|
||||
camera.view.alternativa3d::addSurfaceToMouseEvents(this.alternativa3d::surface,geometry,alternativa3d::transformProcedure);
|
||||
}
|
||||
if(camera.debug)
|
||||
{
|
||||
debug = camera.alternativa3d::checkInDebug(this);
|
||||
if(Boolean(debug & Debug.BOUNDS) && boundBox != null)
|
||||
{
|
||||
Debug.alternativa3d::drawBoundBox(camera,boundBox,alternativa3d::localToCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function setTransformConstants(drawUnit:DrawUnit, surface:Surface, vertexShader:Linker, camera:Camera3D) : void
|
||||
{
|
||||
var scale:Number = Number(Math.sqrt(alternativa3d::localToCameraTransform.a * alternativa3d::localToCameraTransform.a + alternativa3d::localToCameraTransform.e * alternativa3d::localToCameraTransform.e + alternativa3d::localToCameraTransform.i * alternativa3d::localToCameraTransform.i));
|
||||
scale += Math.sqrt(alternativa3d::localToCameraTransform.b * alternativa3d::localToCameraTransform.b + alternativa3d::localToCameraTransform.f * alternativa3d::localToCameraTransform.f + alternativa3d::localToCameraTransform.j * alternativa3d::localToCameraTransform.j);
|
||||
scale += Math.sqrt(alternativa3d::localToCameraTransform.c * alternativa3d::localToCameraTransform.c + alternativa3d::localToCameraTransform.g * alternativa3d::localToCameraTransform.g + alternativa3d::localToCameraTransform.k * alternativa3d::localToCameraTransform.k);
|
||||
scale /= 3;
|
||||
if(!this.perspectiveScale && !camera.orthographic)
|
||||
{
|
||||
scale *= alternativa3d::localToCameraTransform.l / camera.alternativa3d::focalLength;
|
||||
}
|
||||
drawUnit.alternativa3d::setVertexConstantsFromTransform(0,alternativa3d::cameraToLocalTransform);
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(3,this.originX,this.originY,this.width * scale,this.height * scale);
|
||||
drawUnit.alternativa3d::setVertexConstantsFromNumbers(4,alternativa3d::localToCameraTransform.d,alternativa3d::localToCameraTransform.h,alternativa3d::localToCameraTransform.l,this.rotation);
|
||||
}
|
||||
|
||||
alternativa3d function getGeometry(context:Context3D) : Geometry
|
||||
{
|
||||
var attributes:Array = null;
|
||||
var geometry:Geometry = geometries[context];
|
||||
if(geometry == null)
|
||||
{
|
||||
geometry = new Geometry(4);
|
||||
attributes = new Array();
|
||||
attributes[0] = VertexAttributes.POSITION;
|
||||
attributes[1] = VertexAttributes.POSITION;
|
||||
attributes[2] = VertexAttributes.POSITION;
|
||||
attributes[3] = VertexAttributes.NORMAL;
|
||||
attributes[4] = VertexAttributes.NORMAL;
|
||||
attributes[5] = VertexAttributes.NORMAL;
|
||||
attributes[6] = VertexAttributes.TEXCOORDS[0];
|
||||
attributes[7] = VertexAttributes.TEXCOORDS[0];
|
||||
attributes[8] = VertexAttributes.TEXCOORDS[1];
|
||||
attributes[9] = VertexAttributes.TEXCOORDS[1];
|
||||
attributes[10] = VertexAttributes.TEXCOORDS[2];
|
||||
attributes[11] = VertexAttributes.TEXCOORDS[2];
|
||||
attributes[12] = VertexAttributes.TEXCOORDS[3];
|
||||
attributes[13] = VertexAttributes.TEXCOORDS[3];
|
||||
attributes[14] = VertexAttributes.TEXCOORDS[4];
|
||||
attributes[15] = VertexAttributes.TEXCOORDS[4];
|
||||
attributes[16] = VertexAttributes.TEXCOORDS[5];
|
||||
attributes[17] = VertexAttributes.TEXCOORDS[5];
|
||||
attributes[18] = VertexAttributes.TEXCOORDS[6];
|
||||
attributes[19] = VertexAttributes.TEXCOORDS[6];
|
||||
attributes[20] = VertexAttributes.TEXCOORDS[7];
|
||||
attributes[21] = VertexAttributes.TEXCOORDS[7];
|
||||
attributes[22] = VertexAttributes.TANGENT4;
|
||||
attributes[23] = VertexAttributes.TANGENT4;
|
||||
attributes[24] = VertexAttributes.TANGENT4;
|
||||
attributes[25] = VertexAttributes.TANGENT4;
|
||||
geometry.addVertexStream(attributes);
|
||||
geometry.setAttributeValues(VertexAttributes.POSITION,Vector.<Number>([0,0,0,0,1,0,1,1,0,1,0,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.NORMAL,Vector.<Number>([0,0,-1,0,0,-1,0,0,-1,0,0,-1]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[0],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[1],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[2],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[3],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[4],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[5],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[6],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.setAttributeValues(VertexAttributes.TEXCOORDS[7],Vector.<Number>([0,0,0,1,1,1,1,0]));
|
||||
geometry.indices = Vector.<uint>([0,1,3,2,3,1]);
|
||||
geometry.upload(context);
|
||||
geometries[context] = geometry;
|
||||
}
|
||||
return geometry;
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Sprite3D = new Sprite3D(this.width,this.height);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
override protected function clonePropertiesFrom(source:Object3D) : void
|
||||
{
|
||||
super.clonePropertiesFrom(source);
|
||||
var src:Sprite3D = source as Sprite3D;
|
||||
this.width = src.width;
|
||||
this.height = src.height;
|
||||
this.material = src.material;
|
||||
this.originX = src.originX;
|
||||
this.originY = src.originY;
|
||||
this.rotation = src.rotation;
|
||||
this.perspectiveScale = src.perspectiveScale;
|
||||
this.alwaysOnTop = src.alwaysOnTop;
|
||||
}
|
||||
|
||||
override alternativa3d function updateBoundBox(boundBox:BoundBox, hierarchy:Boolean, transform:Transform3D = null) : void
|
||||
{
|
||||
var ax:Number = NaN;
|
||||
var ay:Number = NaN;
|
||||
var az:Number = NaN;
|
||||
var size:Number = NaN;
|
||||
var ww:Number = this.width;
|
||||
var hh:Number = this.height;
|
||||
var w:Number = (this.originX >= 0.5 ? this.originX : 1 - this.originX) * ww;
|
||||
var h:Number = (this.originY >= 0.5 ? this.originY : 1 - this.originY) * hh;
|
||||
var radius:Number = Number(Math.sqrt(w * w + h * h));
|
||||
var cx:Number = 0;
|
||||
var cy:Number = 0;
|
||||
var cz:Number = 0;
|
||||
if(transform != null)
|
||||
{
|
||||
ax = transform.a;
|
||||
ay = transform.e;
|
||||
az = transform.i;
|
||||
size = Number(Math.sqrt(ax * ax + ay * ay + az * az));
|
||||
ax = transform.b;
|
||||
ay = transform.f;
|
||||
az = transform.j;
|
||||
size += Math.sqrt(ax * ax + ay * ay + az * az);
|
||||
ax = transform.c;
|
||||
ay = transform.g;
|
||||
az = transform.k;
|
||||
size += Math.sqrt(ax * ax + ay * ay + az * az);
|
||||
radius *= size / 3;
|
||||
cx = transform.d;
|
||||
cy = transform.h;
|
||||
cz = transform.l;
|
||||
}
|
||||
if(cx - radius < boundBox.minX)
|
||||
{
|
||||
boundBox.minX = cx - radius;
|
||||
}
|
||||
if(cx + radius > boundBox.maxX)
|
||||
{
|
||||
boundBox.maxX = cx + radius;
|
||||
}
|
||||
if(cy - radius < boundBox.minY)
|
||||
{
|
||||
boundBox.minY = cy - radius;
|
||||
}
|
||||
if(cy + radius > boundBox.maxY)
|
||||
{
|
||||
boundBox.maxY = cy + radius;
|
||||
}
|
||||
if(cz - radius < boundBox.minZ)
|
||||
{
|
||||
boundBox.minZ = cz - radius;
|
||||
}
|
||||
if(cz + radius > boundBox.maxZ)
|
||||
{
|
||||
boundBox.maxZ = cz + radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Surface
|
||||
{
|
||||
public var material:Material;
|
||||
|
||||
public var indexBegin:int = 0;
|
||||
|
||||
public var numTriangles:int = 0;
|
||||
|
||||
alternativa3d var object:Object3D;
|
||||
|
||||
public function Surface()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public function clone() : Surface
|
||||
{
|
||||
var res:Surface = new Surface();
|
||||
res.alternativa3d::object = this.alternativa3d::object;
|
||||
res.material = this.material;
|
||||
res.indexBegin = this.indexBegin;
|
||||
res.numTriangles = this.numTriangles;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
package alternativa.engine3d.objects
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Camera3D;
|
||||
import alternativa.engine3d.core.Light3D;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.Transform3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.A3DUtils;
|
||||
import alternativa.engine3d.materials.ShaderProgram;
|
||||
import alternativa.engine3d.materials.compiler.Linker;
|
||||
import alternativa.engine3d.materials.compiler.Procedure;
|
||||
import alternativa.engine3d.materials.compiler.VariableType;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import alternativa.engine3d.resources.WireGeometry;
|
||||
import flash.display3D.Context3DProgramType;
|
||||
import flash.geom.Vector3D;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.getDefinitionByName;
|
||||
import flash.utils.getQualifiedClassName;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class WireFrame extends Object3D
|
||||
{
|
||||
alternativa3d static const shaderProgram:ShaderProgram = initProgram();
|
||||
|
||||
public var thickness:Number = 1;
|
||||
|
||||
alternativa3d var name_lc:Vector.<Number> = new Vector.<Number>(4,true);
|
||||
|
||||
alternativa3d var geometry:WireGeometry;
|
||||
|
||||
public function WireFrame(color:uint = 0, alpha:Number = 1, thickness:Number = 0.5)
|
||||
{
|
||||
super();
|
||||
this.color = color;
|
||||
this.alpha = alpha;
|
||||
this.thickness = thickness;
|
||||
this.alternativa3d::geometry = new WireGeometry();
|
||||
}
|
||||
|
||||
private static function initProgram() : ShaderProgram
|
||||
{
|
||||
var vertexShader:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||
var transform:Procedure = new Procedure();
|
||||
transform.compileFromArray(["mov t0, a0","mov t0.w, c0.y","m34 t0.xyz, t0, c2","m34 t1.xyz, a1, c2","sub t2, t1.xyz, t0.xyz","slt t5.x, t0.z, c1.z","sub t5.y, c0.y, t5.x","add t4.x, t0.z, c0.z","sub t4.y, t0.z, t1.z","add t4.y, t4.y, c0.w","div t4.z, t4.x, t4.y","mul t4.xyz, t4.zzz, t2.xyz","add t3.xyz, t0.xyz, t4.xyz","mul t0, t0, t5.y","mul t3.xyz, t3.xyz, t5.x","add t0, t0, t3.xyz","sub t2, t1.xyz, t0.xyz","crs t3.xyz, t2, t0","nrm t3.xyz, t3.xyz","mul t3.xyz, t3.xyz, a0.w","mul t3.xyz, t3.xyz, c1.w","mul t4.x, t0.z, c1.x","mul t3.xyz, t3.xyz, t4.xxx","add t0.xyz, t0.xyz, t3.xyz","m44 o0, t0, c5"]);
|
||||
transform.assignVariableName(VariableType.ATTRIBUTE,0,"pos1");
|
||||
transform.assignVariableName(VariableType.ATTRIBUTE,1,"pos2");
|
||||
transform.assignVariableName(VariableType.CONSTANT,0,"ZERO");
|
||||
transform.assignVariableName(VariableType.CONSTANT,1,"consts");
|
||||
transform.assignVariableName(VariableType.CONSTANT,2,"worldView",3);
|
||||
transform.assignVariableName(VariableType.CONSTANT,5,"proj",4);
|
||||
vertexShader.addProcedure(transform);
|
||||
vertexShader.link();
|
||||
var fragmentShader:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||
var fp:Procedure = new Procedure();
|
||||
fp.compileFromArray(["mov o0, c0"]);
|
||||
fp.assignVariableName(VariableType.CONSTANT,0,"color");
|
||||
fragmentShader.addProcedure(fp);
|
||||
fragmentShader.link();
|
||||
return new ShaderProgram(vertexShader,fragmentShader);
|
||||
}
|
||||
|
||||
public static function createLinesList(points:Vector.<Vector3D>, color:uint = 0, alpha:Number = 1, thickness:Number = 1) : WireFrame
|
||||
{
|
||||
var p0:Vector3D = null;
|
||||
var p1:Vector3D = null;
|
||||
var result:WireFrame = new WireFrame(color,alpha,thickness);
|
||||
var geometry:WireGeometry = result.alternativa3d::geometry;
|
||||
for(var i:uint = 0, count:uint = points.length - 1; i < count; i += 2)
|
||||
{
|
||||
p0 = points[i];
|
||||
p1 = points[i + 1];
|
||||
geometry.alternativa3d::addLine(p0.x,p0.y,p0.z,p1.x,p1.y,p1.z);
|
||||
}
|
||||
result.calculateBoundBox();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function createLineStrip(points:Vector.<Vector3D>, color:uint = 0, alpha:Number = 1, thickness:Number = 1) : WireFrame
|
||||
{
|
||||
var p0:Vector3D = null;
|
||||
var p1:Vector3D = null;
|
||||
var result:WireFrame = new WireFrame(color,alpha,thickness);
|
||||
var geometry:WireGeometry = result.alternativa3d::geometry;
|
||||
for(var i:uint = 0, count:uint = points.length - 1; i < count; i++)
|
||||
{
|
||||
p0 = points[i];
|
||||
p1 = points[i + 1];
|
||||
geometry.alternativa3d::addLine(p0.x,p0.y,p0.z,p1.x,p1.y,p1.z);
|
||||
}
|
||||
result.calculateBoundBox();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function createEdges(mesh:Mesh, color:uint = 0, alpha:Number = 1, thickness:Number = 1) : WireFrame
|
||||
{
|
||||
var index:uint = 0;
|
||||
var v1x:Number = NaN;
|
||||
var v1y:Number = NaN;
|
||||
var v1z:Number = NaN;
|
||||
var v2x:Number = NaN;
|
||||
var v2y:Number = NaN;
|
||||
var v2z:Number = NaN;
|
||||
var v3x:Number = NaN;
|
||||
var v3y:Number = NaN;
|
||||
var v3z:Number = NaN;
|
||||
var result:WireFrame = new WireFrame(color,alpha,thickness);
|
||||
var geometry:Geometry = mesh.geometry;
|
||||
var resultGeometry:WireGeometry = result.alternativa3d::geometry;
|
||||
var edges:Dictionary = new Dictionary();
|
||||
var indices:Vector.<uint> = geometry.indices;
|
||||
var vertices:Vector.<Number> = geometry.getAttributeValues(VertexAttributes.POSITION);
|
||||
for(var i:int = 0, count:int = int(indices.length); i < count; )
|
||||
{
|
||||
index = indices[i] * 3;
|
||||
v1x = vertices[index];
|
||||
index++;
|
||||
v1y = vertices[index];
|
||||
index++;
|
||||
v1z = vertices[index];
|
||||
index = indices[int(i + 1)] * 3;
|
||||
v2x = vertices[index];
|
||||
index++;
|
||||
v2y = vertices[index];
|
||||
index++;
|
||||
v2z = vertices[index];
|
||||
index = indices[int(i + 2)] * 3;
|
||||
v3x = vertices[index];
|
||||
index++;
|
||||
v3y = vertices[index];
|
||||
index++;
|
||||
v3z = vertices[index];
|
||||
if(checkEdge(edges,v1x,v1y,v1z,v2x,v2y,v2z))
|
||||
{
|
||||
resultGeometry.alternativa3d::addLine(v1x,v1y,v1z,v2x,v2y,v2z);
|
||||
}
|
||||
if(checkEdge(edges,v2x,v2y,v2z,v3x,v3y,v3z))
|
||||
{
|
||||
resultGeometry.alternativa3d::addLine(v2x,v2y,v2z,v3x,v3y,v3z);
|
||||
}
|
||||
if(checkEdge(edges,v1x,v1y,v1z,v3x,v3y,v3z))
|
||||
{
|
||||
resultGeometry.alternativa3d::addLine(v1x,v1y,v1z,v3x,v3y,v3z);
|
||||
}
|
||||
i += 3;
|
||||
}
|
||||
result.calculateBoundBox();
|
||||
result.alternativa3d::_x = mesh.alternativa3d::_x;
|
||||
result.alternativa3d::_y = mesh.alternativa3d::_y;
|
||||
result.alternativa3d::_z = mesh.alternativa3d::_z;
|
||||
result.alternativa3d::_rotationX = mesh.alternativa3d::_rotationX;
|
||||
result.alternativa3d::_rotationY = mesh.alternativa3d::_rotationY;
|
||||
result.alternativa3d::_rotationZ = mesh.alternativa3d::_rotationZ;
|
||||
result.alternativa3d::_scaleX = mesh.alternativa3d::_scaleX;
|
||||
result.alternativa3d::_scaleY = mesh.alternativa3d::_scaleY;
|
||||
result.alternativa3d::_scaleZ = mesh.alternativa3d::_scaleZ;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static function checkEdge(edges:Dictionary, v1x:Number, v1y:Number, v1z:Number, v2x:Number, v2y:Number, v2z:Number) : Boolean
|
||||
{
|
||||
var str:String = null;
|
||||
if(v1x * v1x + v1y * v1y + v1z * v1z < v2x * v2x + v2y * v2y + v2z * v2z)
|
||||
{
|
||||
str = v1x.toString() + v1y.toString() + v1z.toString() + v2x.toString() + v2y.toString() + v2z.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
str = v2x.toString() + v2y.toString() + v2z.toString() + v1x.toString() + v1y.toString() + v1z.toString();
|
||||
}
|
||||
if(Boolean(edges[str]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
edges[str] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get alpha() : Number
|
||||
{
|
||||
return this.name_lc[3];
|
||||
}
|
||||
|
||||
public function set alpha(value:Number) : void
|
||||
{
|
||||
this.name_lc[3] = value;
|
||||
}
|
||||
|
||||
public function get color() : uint
|
||||
{
|
||||
return this.name_lc[0] * 255 << 16 | this.name_lc[1] * 255 << 8 | this.name_lc[2] * 255;
|
||||
}
|
||||
|
||||
public function set color(value:uint) : void
|
||||
{
|
||||
this.name_lc[0] = (value >> 16 & 0xFF) / 255;
|
||||
this.name_lc[1] = (value >> 8 & 0xFF) / 255;
|
||||
this.name_lc[2] = (value & 0xFF) / 255;
|
||||
}
|
||||
|
||||
override alternativa3d function updateBoundBox(boundBox:BoundBox, hierarchy:Boolean, transform:Transform3D = null) : void
|
||||
{
|
||||
super.alternativa3d::updateBoundBox(boundBox,hierarchy,transform);
|
||||
if(this.alternativa3d::geometry != null)
|
||||
{
|
||||
this.alternativa3d::geometry.alternativa3d::updateBoundBox(boundBox,transform);
|
||||
}
|
||||
}
|
||||
|
||||
override alternativa3d function collectDraws(camera:Camera3D, lights:Vector.<Light3D>, lightsLength:int) : void
|
||||
{
|
||||
this.alternativa3d::geometry.alternativa3d::getDrawUnits(camera,this.name_lc,this.thickness,this,alternativa3d::shaderProgram);
|
||||
}
|
||||
|
||||
override alternativa3d function fillResources(resources:Dictionary, hierarchy:Boolean = false, resourceType:Class = null) : void
|
||||
{
|
||||
super.alternativa3d::fillResources(resources,hierarchy,resourceType);
|
||||
if(A3DUtils.alternativa3d::checkParent(getDefinitionByName(getQualifiedClassName(this.alternativa3d::geometry)) as Class,resourceType))
|
||||
{
|
||||
resources[this.alternativa3d::geometry] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
package alternativa.engine3d.primitives
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import alternativa.engine3d.core.BoundBox;
|
||||
import alternativa.engine3d.core.Object3D;
|
||||
import alternativa.engine3d.core.VertexAttributes;
|
||||
import alternativa.engine3d.materials.Material;
|
||||
import alternativa.engine3d.objects.Mesh;
|
||||
import alternativa.engine3d.resources.Geometry;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class Box extends Mesh
|
||||
{
|
||||
public function Box(width:Number = 100, length:Number = 100, height:Number = 100, widthSegments:uint = 1, lengthSegments:uint = 1, heightSegments:uint = 1, reverse:Boolean = false, material:Material = null)
|
||||
{
|
||||
var x:int = 0;
|
||||
var y:int = 0;
|
||||
var z:int = 0;
|
||||
var halfHeight:Number = NaN;
|
||||
super();
|
||||
if(widthSegments <= 0 || lengthSegments <= 0 || heightSegments <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var indices:Vector.<uint> = new Vector.<uint>();
|
||||
var wp:int = widthSegments + 1;
|
||||
var lp:int = lengthSegments + 1;
|
||||
var hp:int = heightSegments + 1;
|
||||
var halfWidth:Number = width * 0.5;
|
||||
var halfLength:Number = length * 0.5;
|
||||
halfHeight = height * 0.5;
|
||||
var wd:Number = 1 / widthSegments;
|
||||
var ld:Number = 1 / lengthSegments;
|
||||
var hd:Number = 1 / heightSegments;
|
||||
var ws:Number = width / widthSegments;
|
||||
var ls:Number = length / lengthSegments;
|
||||
var hs:Number = height / heightSegments;
|
||||
var vertices:ByteArray = new ByteArray();
|
||||
vertices.endian = Endian.LITTLE_ENDIAN;
|
||||
var offset:uint = 0;
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
vertices.writeFloat(x * ws - halfWidth);
|
||||
vertices.writeFloat(y * ls - halfLength);
|
||||
vertices.writeFloat(-halfHeight);
|
||||
vertices.writeFloat((widthSegments - x) * wd);
|
||||
vertices.writeFloat((lengthSegments - y) * ld);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
offset = uint(vertices.position);
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(y = 0; y < lp; )
|
||||
{
|
||||
if(x < widthSegments && y < lengthSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,(x + 1) * lp + y + 1,(x + 1) * lp + y,x * lp + y,x * lp + y + 1,0,0,-1,halfHeight,0,-1,0,0,reverse);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
vertices.position = offset;
|
||||
var o:uint = uint(wp * lp);
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
vertices.writeFloat(x * ws - halfWidth);
|
||||
vertices.writeFloat(y * ls - halfLength);
|
||||
vertices.writeFloat(halfHeight);
|
||||
vertices.writeFloat(x * wd);
|
||||
vertices.writeFloat((lengthSegments - y) * ld);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
offset = uint(vertices.position);
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(y = 0; y < lp; )
|
||||
{
|
||||
if(x < widthSegments && y < lengthSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,o + x * lp + y,o + (x + 1) * lp + y,o + (x + 1) * lp + y + 1,o + x * lp + y + 1,0,0,1,halfHeight,0,-1,0,0,reverse);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
vertices.position = offset;
|
||||
o += wp * lp;
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(z = 0; z < hp; z++)
|
||||
{
|
||||
vertices.writeFloat(x * ws - halfWidth);
|
||||
vertices.writeFloat(-halfLength);
|
||||
vertices.writeFloat(z * hs - halfHeight);
|
||||
vertices.writeFloat(x * wd);
|
||||
vertices.writeFloat((heightSegments - z) * hd);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
offset = uint(vertices.position);
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(z = 0; z < hp; )
|
||||
{
|
||||
if(x < widthSegments && z < heightSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,o + x * hp + z,o + (x + 1) * hp + z,o + (x + 1) * hp + z + 1,o + x * hp + z + 1,0,-1,0,halfLength,0,0,-1,0,reverse);
|
||||
}
|
||||
z++;
|
||||
}
|
||||
}
|
||||
vertices.position = offset;
|
||||
o += wp * hp;
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(z = 0; z < hp; z++)
|
||||
{
|
||||
vertices.writeFloat(x * ws - halfWidth);
|
||||
vertices.writeFloat(halfLength);
|
||||
vertices.writeFloat(z * hs - halfHeight);
|
||||
vertices.writeFloat((widthSegments - x) * wd);
|
||||
vertices.writeFloat((heightSegments - z) * hd);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
offset = uint(vertices.position);
|
||||
for(x = 0; x < wp; x++)
|
||||
{
|
||||
for(z = 0; z < hp; )
|
||||
{
|
||||
if(x < widthSegments && z < heightSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,o + x * hp + z,o + x * hp + z + 1,o + (x + 1) * hp + z + 1,o + (x + 1) * hp + z,0,1,0,halfLength,0,0,-1,0,reverse);
|
||||
}
|
||||
z++;
|
||||
}
|
||||
}
|
||||
vertices.position = offset;
|
||||
o += wp * hp;
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
for(z = 0; z < hp; z++)
|
||||
{
|
||||
vertices.writeFloat(-halfWidth);
|
||||
vertices.writeFloat(y * ls - halfLength);
|
||||
vertices.writeFloat(z * hs - halfHeight);
|
||||
vertices.writeFloat((lengthSegments - y) * ld);
|
||||
vertices.writeFloat((heightSegments - z) * hd);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
offset = uint(vertices.position);
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
for(z = 0; z < hp; )
|
||||
{
|
||||
if(y < lengthSegments && z < heightSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,o + y * hp + z,o + y * hp + z + 1,o + (y + 1) * hp + z + 1,o + (y + 1) * hp + z,-1,0,0,halfWidth,0,0,-1,0,reverse);
|
||||
}
|
||||
z++;
|
||||
}
|
||||
}
|
||||
vertices.position = offset;
|
||||
o += lp * hp;
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
for(z = 0; z < hp; z++)
|
||||
{
|
||||
vertices.writeFloat(halfWidth);
|
||||
vertices.writeFloat(y * ls - halfLength);
|
||||
vertices.writeFloat(z * hs - halfHeight);
|
||||
vertices.writeFloat(y * ld);
|
||||
vertices.writeFloat((heightSegments - z) * hd);
|
||||
vertices.length = vertices.position = vertices.position + 28;
|
||||
}
|
||||
}
|
||||
for(y = 0; y < lp; y++)
|
||||
{
|
||||
for(z = 0; z < hp; )
|
||||
{
|
||||
if(y < lengthSegments && z < heightSegments)
|
||||
{
|
||||
this.createFace(indices,vertices,o + y * hp + z,o + (y + 1) * hp + z,o + (y + 1) * hp + z + 1,o + y * hp + z + 1,1,0,0,halfWidth,0,0,-1,0,reverse);
|
||||
}
|
||||
z++;
|
||||
}
|
||||
}
|
||||
geometry = new Geometry();
|
||||
geometry.alternativa3d::_indices = indices;
|
||||
var attributes:Array = new Array();
|
||||
attributes[0] = VertexAttributes.POSITION;
|
||||
attributes[1] = VertexAttributes.POSITION;
|
||||
attributes[2] = VertexAttributes.POSITION;
|
||||
attributes[3] = VertexAttributes.TEXCOORDS[0];
|
||||
attributes[4] = VertexAttributes.TEXCOORDS[0];
|
||||
attributes[5] = VertexAttributes.NORMAL;
|
||||
attributes[6] = VertexAttributes.NORMAL;
|
||||
attributes[7] = VertexAttributes.NORMAL;
|
||||
attributes[8] = VertexAttributes.TANGENT4;
|
||||
attributes[9] = VertexAttributes.TANGENT4;
|
||||
attributes[10] = VertexAttributes.TANGENT4;
|
||||
attributes[11] = VertexAttributes.TANGENT4;
|
||||
geometry.addVertexStream(attributes);
|
||||
geometry.alternativa3d::_vertexStreams[0].data = vertices;
|
||||
geometry.alternativa3d::_numVertices = vertices.length / 48;
|
||||
addSurface(material,0,indices.length / 3);
|
||||
boundBox = new BoundBox();
|
||||
boundBox.minX = -halfWidth;
|
||||
boundBox.minY = -halfLength;
|
||||
boundBox.minZ = -halfHeight;
|
||||
boundBox.maxX = halfWidth;
|
||||
boundBox.maxY = halfLength;
|
||||
boundBox.maxZ = halfHeight;
|
||||
}
|
||||
|
||||
private function createFace(indices:Vector.<uint>, vertices:ByteArray, a:int, b:int, c:int, d:int, nx:Number, ny:Number, nz:Number, no:Number, tx:Number, ty:Number, tz:Number, tw:Number, reverse:Boolean) : void
|
||||
{
|
||||
var v:int = 0;
|
||||
if(reverse)
|
||||
{
|
||||
nx = -nx;
|
||||
ny = -ny;
|
||||
nz = -nz;
|
||||
no = -no;
|
||||
v = a;
|
||||
a = d;
|
||||
d = v;
|
||||
v = b;
|
||||
b = c;
|
||||
c = v;
|
||||
}
|
||||
indices.push(a);
|
||||
indices.push(b);
|
||||
indices.push(c);
|
||||
indices.push(a);
|
||||
indices.push(c);
|
||||
indices.push(d);
|
||||
vertices.position = a * 48 + 20;
|
||||
vertices.writeFloat(nx);
|
||||
vertices.writeFloat(ny);
|
||||
vertices.writeFloat(nz);
|
||||
vertices.writeFloat(tx);
|
||||
vertices.writeFloat(ty);
|
||||
vertices.writeFloat(tz);
|
||||
vertices.writeFloat(tw);
|
||||
vertices.position = b * 48 + 20;
|
||||
vertices.writeFloat(nx);
|
||||
vertices.writeFloat(ny);
|
||||
vertices.writeFloat(nz);
|
||||
vertices.writeFloat(tx);
|
||||
vertices.writeFloat(ty);
|
||||
vertices.writeFloat(tz);
|
||||
vertices.writeFloat(tw);
|
||||
vertices.position = c * 48 + 20;
|
||||
vertices.writeFloat(nx);
|
||||
vertices.writeFloat(ny);
|
||||
vertices.writeFloat(nz);
|
||||
vertices.writeFloat(tx);
|
||||
vertices.writeFloat(ty);
|
||||
vertices.writeFloat(tz);
|
||||
vertices.writeFloat(tw);
|
||||
vertices.position = d * 48 + 20;
|
||||
vertices.writeFloat(nx);
|
||||
vertices.writeFloat(ny);
|
||||
vertices.writeFloat(nz);
|
||||
vertices.writeFloat(tx);
|
||||
vertices.writeFloat(ty);
|
||||
vertices.writeFloat(tz);
|
||||
vertices.writeFloat(tw);
|
||||
}
|
||||
|
||||
override public function clone() : Object3D
|
||||
{
|
||||
var res:Box = new Box(0,0,0,0,0,0);
|
||||
res.clonePropertiesFrom(this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package alternativa.engine3d.resources
|
||||
{
|
||||
import alternativa.engine3d.alternativa3d;
|
||||
import flash.display3D.Context3D;
|
||||
import flash.display3D.Context3DTextureFormat;
|
||||
import flash.display3D.textures.CubeTexture;
|
||||
import flash.display3D.textures.Texture;
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
use namespace alternativa3d;
|
||||
|
||||
public class ATFTextureResource extends TextureResource
|
||||
{
|
||||
public var data:ByteArray;
|
||||
|
||||
public function ATFTextureResource(data:ByteArray)
|
||||
{
|
||||
super();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
override public function upload(context3D:Context3D) : void
|
||||
{
|
||||
var type:uint = 0;
|
||||
var format:String = null;
|
||||
if(alternativa3d::_texture != null)
|
||||
{
|
||||
alternativa3d::_texture.dispose();
|
||||
}
|
||||
if(this.data != null)
|
||||
{
|
||||
this.data.position = 6;
|
||||
type = uint(this.data.readByte());
|
||||
switch(type & 0x7F)
|
||||
{
|
||||
case 0:
|
||||
format = Context3DTextureFormat.BGRA;
|
||||
break;
|
||||
case 1:
|
||||
format = Context3DTextureFormat.BGRA;
|
||||
break;
|
||||
case 2:
|
||||
format = Context3DTextureFormat.COMPRESSED;
|
||||
}
|
||||
if((type & ~0x7F) == 0)
|
||||
{
|
||||
alternativa3d::_texture = context3D.createTexture(1 << this.data.readByte(),1 << this.data.readByte(),format,false);
|
||||
Texture(alternativa3d::_texture).uploadCompressedTextureFromByteArray(this.data,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
alternativa3d::_texture = context3D.createCubeTexture(1 << this.data.readByte(),format,false);
|
||||
CubeTexture(alternativa3d::_texture).uploadCompressedTextureFromByteArray(this.data,0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
alternativa3d::_texture = null;
|
||||
throw new Error("Cannot upload without data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user