// FN Utility Toolset // disease332000@yahoo.com #include "FN.as" function fnuVertex3(X, Y, Z) { this.X = X?X:0; this.Y = Y?Y:0; this.Z = Z?Z:0; return this; } fnuVertex3.prototype.fnuAdd = function(Target) { New = new fnuVertex3(this.X, this.Y, this.Z); New.X += Target.X; New.Y += Target.Y; New.Z += Target.Z; return New; } fnuVertex3.prototype.fnuNegate = function() { New = new fnuVertex3(-this.X, -this.Y, -this.Z); return New; } fnuVertex3.prototype.fnuScalar = function(Target) { New = new fnuVertex3(this.X, this.Y, this.Z); New.X *= Target; New.Y *= Target; New.Z *= Target; return New; } fnuVertex3.prototype.fnuSet = function(X, Y, Z) { this.X = X; this.Y = Y; this.Z = Z; } function fnuQuat(X, Y, Z, W) { this.X = X?X:0; this.Y = Y?Y:0; this.Z = Z?Z:0; this.W = W?W:0; return this; } fnuQuat.prototype.fnuNormalize = function() { var Len = Math.sqrt(this.X*this.X + this.Y*this.Y + this.Z*this.Z + this.W*this.W); this.X /= Len; this.Y /= Len; this.Z /= Len; this.W /= Len; } fnuQuat.prototype.fnuFromAxisAngle = function(Theta, X, Y, Z) { var Len = Math.sqrt(X*X + Y*Y + Z*Z); X /= Len; Y /= Len; Z /= Len; var Temp = Math.sin(Theta/2); this.W = Math.cos(Theta/2); this.X = X * Temp; this.Y = Y * Temp; this.Z = Z * Temp; this.fnuNormalize(); } fnuQuat.prototype.fnuToMatrix = function() { return Array(1 - 2*(this.Y*this.Y) - 2*(this.Z*this.Z), 2*(this.X*this.Y) - 2*(this.W*this.Z), 2*(this.X*this.Z) + 2*(this.W*this.Y), 0, 2*(this.X*this.Y) + 2*(this.W*this.Z), 1 - 2*(this.X*this.X) - 2*(this.Z*this.Z), 2*(this.Y*this.Z) - 2*(this.W*this.X), 0, 2*(this.X*this.Z) - 2*(this.W*this.Y), 2*(this.Y*this.Z) - 2*(this.W*this.X), 1 - 2*(this.X*this.X) - 2*(this.Y*this.Y), 0, 0, 0, 0, 1); } fnuQuat.prototype.fnuToArr = function() { return Array(this.X, this.Y, this.Z, this.W); } function fnuWorld() { this.Gravity = new fnuVertex3(0, 0.02, 0); this.Friction = 0.98; this.Wind = new fnuVertex3(0, 0, 0); } function fnuParticle3(X, Y, Z, Param) { this.Pos = new fnuVertex3(X, Y, Z); // Position this.Vel = new fnuVertex3(0, 0, 0); // Velocity this.Life = 100; // Life of the Particle this.Decay = 5; // Decay rate of the particle this.Loop = true; // Re-initialize the particle after it is dead? this.Dead = false; // Is the particle dead yet? this.Init = Param[0]; // The external initialization function this.Kill = Param[1]; // The external death function this.Time = Param[2]; // The iteration function -- called every update this.World = Param[3]; // The world (general set of rules) where the particle exists this.Visible = true; this.Child = new Array(); // The particles children this.Parent = null; // The particles parent this.Relative = false; this.Model = null; // And external instance of fnuModel this.Init(); // Call the initialization function last! return this; } fnuParticle3.prototype.fnuAddChild = function(New) { this.Child[this.Child.length] = new fnuParticle3(New.X, New.Y, New.Z, Array(New.Init, New.Kill, New.Time, New.World)); this.Child[this.Child.length-1].Parent = this; return this.Child[this.Child.length-1]; } fnuParticle3.prototype.fnuUpdate = function() { if(this.Life < 0) { if(this.Loop) { this.Init(); this.Life = 100; this.Kill(); this.Dead = false; } else { if(!this.Dead) { if(this.Parent) { for(var i = 0; i < this.Parent.Child.length; i++) { if(this == this.Parent.Child[i]) { this.Parent.splice(i, 1); delete this; } } } this.Kill(); this.Dead = true; } } } else { this.Vel = this.Vel.fnuAdd(this.World.Gravity); this.Vel = this.Vel.fnuAdd(this.World.Wind); this.Vel = this.Vel.fnuScalar(this.World.Friction); this.Pos = this.Pos.fnuAdd(this.Vel); this.Life -= this.Decay; this.Time(); } for(var i = 0; i < this.Child.length; i++) { this.Child[i].Parent = this; this.Child[i].fnuUpdate(); } } fnuParticle3.prototype.fnuDraw = function() { if(this.Life>0) { if(this.Visible) { if(this.Model) { fnPush(); fnTranslate(this.Pos.X, this.Pos.Y, this.Pos.Z); this.Model.fnuDraw(); fnPop(); } else { fnAlpha(this.Life+50); fnColor(0x000000); fnBegin(FN_LINE); if(this.Parent&&this.Relative) { fnVertex3(this.Pos.X+this.Parent.Pos.X, this.Pos.Y+this.Parent.Pos.Y, this.Pos.Z+this.Parent.Pos.Z); fnVertex3(this.Pos.X+this.Parent.Pos.X+this.Vel.X, this.Pos.Y+this.Parent.Pos.Y+this.Vel.Y, this.Pos.Z+this.Parent.Pos.Z+this.Vel.Z); } else { fnVertex3(this.Pos.X, this.Pos.Y, this.Pos.Z); fnVertex3(this.Pos.X+this.Vel.X, this.Pos.Y+this.Vel.Y, this.Pos.Z+this.Vel.Z); } fnEnd(); } } } for(var i = 0; i < this.Child.length; i++) { this.Child[i].Parent = this; this.Child[i].fnuDraw(); } } function fnuModel() { this.Vert = new Array(); this.Face = new Array(); this.Line = new Array(); this.Col = 0x000000; } fnuModel.prototype.fnuAddVert = function(X, Y, Z) { this.Vert[this.Vert.length] = new fnuVertex3(X, Y, Z); return this.Vert.length-1; } fnuModel.prototype.fnuAddFace = function(A, B, C) { this.Face[this.Face.length] = new Array(A, B, C); return this.Face.length-1; } fnuModel.prototype.fnuAddLine = function(A, B) { this.Line[this.Line.length] = new Array(A, B); return this.Line.length-1; } fnuModel.prototype.fnuReset = function() { this.Life = 100; this.Init(); for(var i = 0; i < this.Child.length; i++) { this.Child[i].fnuReset(); } } fnuModel.prototype.fnuDraw = function() { fnColor(this.Col); fnBegin(FN_TRIANGLES); for(var i = 0; i < this.Face.length; i++) { fnVertex3(this.Vert[this.Face[i][0]].X, this.Vert[this.Face[i][0]].Y, this.Vert[this.Face[i][0]].Z); fnVertex3(this.Vert[this.Face[i][1]].X, this.Vert[this.Face[i][1]].Y, this.Vert[this.Face[i][1]].Z); fnVertex3(this.Vert[this.Face[i][2]].X, this.Vert[this.Face[i][2]].Y, this.Vert[this.Face[i][2]].Z); } fnEnd(); fnBegin(FN_LINE); for(var i = 0; i < this.Line.length; i++) { fnVertex3(this.Vert[this.Line[i][0]].X, this.Vert[this.Line[i][0]].Y, this.Vert[this.Line[i][0]].Z); fnVertex3(this.Vert[this.Line[i][1]].X, this.Vert[this.Line[i][1]].Y, this.Vert[this.Line[i][1]].Z); } fnEnd(); }