// FN 3D Engine // disease332000@yahoo.com FN_MATRIX = new Array(new Array(), new Array()); // Matrices FN_STACK = 0; // Stack position fnGetStack = function() // Small function, returns stack position { return FN_STACK; } FN_PROJECT = 0; FN_VIEW = FN_MATRIX_MODE = 1; // Matrix Modes FN_MATRIX[fnGetStack()][FN_PROJECT] = FN_MATRIX[fnGetStack()][FN_VIEW] // Matrices = FN_MATRIX_IDENTITY = new Array( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // Identity Matrix (default) FN_LINE_WIDTH = 1; FN_LINE_ALPHA = 100; FN_DEPTH_BUFFER = new Array(); // Currently only used with spriting FN_LINE_COLOR = 0x000000; FN_CONST_FOCAL_LENGTH = 300; FN_CONST_DEPTH = FN_CONST_CONTEXT = 0; // Movie clip depth, Rendering context FN_DRAW_MODE = -1; // Drawing mode FN_TRIANGLES = 0; // Draws triangles FN_BLANK = 1; // Draws nothing FN_CURVE = 2; // Draws a beizer curve FN_QUAD = 4; // Draws a quad FN_LINE = 3; FN_DRAW_FUNC = new Array(); // Open ended drawing functions allows for alot of tweaking FN_DRAW_FUNC[FN_TRIANGLES] = function(Obj, X, Y) { Obj.lineTo(X, Y); } FN_DRAW_FUNC[FN_QUAD] = function(Obj, X, Y) { Obj.lineTo(X, Y); } FN_DRAW_FUNC[FN_BLANK] = function() { } FN_DRAW_FUNC[FN_CURVE] = function(Obj, X, Y, A, B) { Obj.curveTo(X, Y, A, B); } FN_DRAW_FUNC[FN_LINE] = function(Obj, X, Y) { Obj.lineTo(X, Y); } FN_DRAW_CLOSE = new Array(true, false, false, false, true); // A boolean array -- close the shape or not FN_VERTEX_COUNT = 0; FN_VERTEX_ARRAY = new Array(); // Keeps a constant count of vertices FN_VERTEX_BUFFER = new Array(0, 0, 0); // Keeps the latest vector from a vertex call FN_CONTROL_BUFFER = new Array(0, 0, 0); // Keeps the latest vector from a control call FN_VERTEX_CLOSE = new Array(0, 0, 0); // Return vertex (closes unclosed polygons) FN_VERTEX_ARRAY[FN_TRIANGLES] = 3; // Number of vertices for triangles drawing mode FN_VERTEX_ARRAY[FN_BLANK] = 0; FN_VERTEX_ARRAY[FN_CURVE] = 2; FN_VERTEX_ARRAY[FN_LINE] = 2; FN_VERTEX_ARRAY[FN_QUAD] = 4; FN_CACHE_BEGIN = 0; FN_CACHE_END = 1; FN_CACHE_ADD = 2; FN_CACHE_CLEAR = 3; FN_CACHE_DRAW = 4; FN_CACHE_ACTIVE = false; FN_CACHE_ARRAY = new Array(); FN_CACHE_INDEX = 0; _global.fnCache = function(Mode) { // Under Construction if(Mode==FN_CACHE_BEGIN) { FN_CACHE_INDEX = 0; FN_CACHE_ACTIVE = true; } if(Mode==FN_CACHE_END) { FN_CACHE_ACTIVE = false; } if(Mode==FN_CACHE_ADD) { FN_CACHE_ACTIVE = true; } if(Mode==FN_CACHE_CLEAR) { FN_CACHE_INDEX = 0; } if(Mode==FN_CACHE_DRAW) { } } _global.fnGetDepth = function() { return FN_CONST_DEPTH; } _global.fnAddDepth = function() { FN_CONST_DEPTH++; } // Increments depth _global.fnCreateContext = function() { // Creates a context FN_CONST_CONTEXT = _root.createEmptyMovieClip( "FN_CONTEXT_MOVIE", FN_CONST_DEPTH); fnAddDepth(); } _global.fnAttachGraphic = function(Linkage) { var o = _root.attachMovie(Linkage, FN_CONST_DEPTH.toString(), FN_CONST_DEPTH); fnAddDepth(); return o; } _global.fnAttachEmpty = function() { var o = _root.createEmptyMovieClip(FN_CONST_DEPTH.toString(), FN_CONST_DEPTH); fnAddDepth(); return o; } _global.fnGetContext = function() // Returns a pointer to the rendering context { return FN_CONST_CONTEXT; } _global.fnSetContext = function(Context) // Sets the context to an arbitrary movieclip { FN_CONST_CONTEXT = Context; } _global.fnMatrixMode = function(Mode) // Sets the matrix mode { FN_MATRIX_MODE = Mode; } fnConcatMatrix = function(MatrixA, MatrixB) { // Multiplies two matrices return [MatrixA[0]*MatrixB[0] + MatrixA[1]*MatrixB[4] + MatrixA[2]*MatrixB[8] + MatrixA[3]*MatrixB[12], MatrixA[0]*MatrixB[1] + MatrixA[1]*MatrixB[5] + MatrixA[2]*MatrixB[9] + MatrixA[3]*MatrixB[13], MatrixA[0]*MatrixB[2] + MatrixA[1]*MatrixB[6] + MatrixA[2]*MatrixB[10] + MatrixA[3]*MatrixB[14], MatrixA[0]*MatrixB[3] + MatrixA[1]*MatrixB[7] + MatrixA[2]*MatrixB[11] + MatrixA[3]*MatrixB[15], MatrixA[4]*MatrixB[0] + MatrixA[5]*MatrixB[4] + MatrixA[6]*MatrixB[8] + MatrixA[7]*MatrixB[12], MatrixA[4]*MatrixB[1] + MatrixA[5]*MatrixB[5] + MatrixA[6]*MatrixB[9] + MatrixA[7]*MatrixB[13], MatrixA[4]*MatrixB[2] + MatrixA[5]*MatrixB[6] + MatrixA[6]*MatrixB[10] + MatrixA[7]*MatrixB[14], MatrixA[4]*MatrixB[3] + MatrixA[5]*MatrixB[7] + MatrixA[6]*MatrixB[11] + MatrixA[7]*MatrixB[15], MatrixA[8]*MatrixB[0] + MatrixA[9]*MatrixB[4] + MatrixA[10]*MatrixB[8] + MatrixA[11]*MatrixB[12], MatrixA[8]*MatrixB[1] + MatrixA[9]*MatrixB[5] + MatrixA[10]*MatrixB[9] + MatrixA[11]*MatrixB[13], MatrixA[8]*MatrixB[2] + MatrixA[9]*MatrixB[6] + MatrixA[10]*MatrixB[10] + MatrixA[11]*MatrixB[14], MatrixA[8]*MatrixB[3] + MatrixA[9]*MatrixB[7] + MatrixA[10]*MatrixB[11] + MatrixA[11]*MatrixB[15], MatrixA[12]*MatrixB[0] + MatrixA[13]*MatrixB[4] + MatrixA[14]*MatrixB[8] + MatrixA[15]*MatrixB[12], MatrixA[12]*MatrixB[1] + MatrixA[13]*MatrixB[5] + MatrixA[14]*MatrixB[9] + MatrixA[15]*MatrixB[13], MatrixA[12]*MatrixB[2] + MatrixA[13]*MatrixB[6] + MatrixA[14]*MatrixB[10] + MatrixA[15]*MatrixB[14], MatrixA[12]*MatrixB[3] + MatrixA[13]*MatrixB[7] + MatrixA[14]*MatrixB[11] + MatrixA[15]*MatrixB[15]]; } fnConcatVector = function(MatrixA, VectorA) { // Multiplies a vector an a matrix //if(MatrixA == FN_MATRIX_IDENTITY) { return VectorA; } return [MatrixA[0]*VectorA[0] + MatrixA[1]*VectorA[1] + MatrixA[2]*VectorA[2] + MatrixA[3], MatrixA[4]*VectorA[0] + MatrixA[5]*VectorA[1] + MatrixA[6]*VectorA[2] + MatrixA[7], MatrixA[8]*VectorA[0] + MatrixA[9]*VectorA[1] + MatrixA[10]*VectorA[2] + MatrixA[11]]; } _global.fnMultMatrix = function(MatrixA) { // Multiplies the current matrix by an arbitrary matrix var MatrixB = new Array(); MatrixB = fnConcatMatrix(FN_MATRIX[fnGetStack()][FN_MATRIX_MODE], MatrixA); FN_MATRIX[fnGetStack()][FN_MATRIX_MODE] = MatrixB; } _global.fnTranslate = function(X, Y, Z) { // Translates the current matrix through a vector var Matrix = new Array( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); Matrix[3] = X; Matrix[7] = Y; Matrix[11] = Z; fnMultMatrix(Matrix); } _global.fnRotate = function(X, Y, Z) { // Rotates the current matrix through three euler angles var cx = Math.cos(X); var sx = Math.sin(X); var cy = Math.cos(Y); var sy = Math.sin(Y); var cz = Math.cos(Z); var sz = Math.sin(Z); var Matrix = new Array( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); Matrix[0] = (cy * cz); Matrix[1] = (cy * sz); Matrix[2] = (-sy); Matrix[4] = (sx * sy * cz - cx * sz); Matrix[5] = (sx * sy * sz + cx * cz); Matrix[6] = (sx * cy); Matrix[8] = (cx * sy * cz + sx * sz); Matrix[9] = (cx * sy * sz - sx * cz); Matrix[10] = (cx * cy); Matrix[15] = 1.0; fnMultMatrix(Matrix); } _global.fnWidth = function(Num) { if(!Num) { return FN_LINE_WIDTH; } FN_LINE_WIDTH = Num; } _global.fnAlpha = function(Num) { if(!Num) { return FN_LINE_ALPHA; } FN_LINE_ALPHA = Num; } _global.fnColor = function(Num) { FN_LINE_COLOR = Num; return FN_LINE_COLOR; } _global.fnBegin = function(Mode) { // Begins drawing FN_DRAW_MODE = Mode; var Obj = fnGetContext(); Obj.beginFill(0x000000, 0); Obj.lineStyle(FN_LINE_WIDTH, FN_LINE_COLOR, FN_LINE_ALPHA); FN_VERTEX_COUNT = 0; } _global.fnEnd = function() { // Ends drawing var Obj = fnGetContext(); Obj.lineStyle(FN_LINE_WIDTH, 0x000000, 0); Obj.endFill(); } _global.fnControl3 = function(X, Y, Z) { var Vector = new Array(X, Y, Z); Vector = fnConcatVector(FN_MATRIX[fnGetStack()][FN_VIEW], Vector); var Scale = FN_CONST_FOCAL_LENGTH/(FN_CONST_FOCAL_LENGTH+Vector[2]); Vector[0] *= Scale; Vector[1] *= Scale; FN_CONTROL_BUFFER = [Vector[0], Vector[1], Vector[2]]; } _global.fnVertex3 = function(X, Y, Z) { // Draws a vertex var Vector = new Array(X, Y, Z); Vector = fnConcatVector(FN_MATRIX[fnGetStack()][FN_VIEW], Vector); var Scale = FN_CONST_FOCAL_LENGTH/(FN_CONST_FOCAL_LENGTH+Vector[2]); Vector[0] *= Scale; Vector[1] *= Scale; FN_VERTEX_BUFFER = [Vector[0], Vector[1], Vector[2]]; if(FN_VERTEX_ARRAY[FN_DRAW_MODE]>0) { var Obj = fnGetContext(); FN_VERTEX_COUNT++; if(FN_VERTEX_COUNT == 1) { Obj.moveTo(Vector[0], Vector[1]); FN_VERTEX_CLOSE = [Vector[0], Vector[1]]; } else { FN_DRAW_FUNC[FN_DRAW_MODE](Obj, Vector[0], Vector[1], FN_CONTROL_BUFFER[0], FN_CONTROL_BUFFER[1]); } if(FN_VERTEX_COUNT >= FN_VERTEX_ARRAY[FN_DRAW_MODE] && FN_DRAW_CLOSE[FN_DRAW_MODE]) { FN_DRAW_FUNC[FN_DRAW_MODE](Obj, FN_VERTEX_CLOSE[0], FN_VERTEX_CLOSE[1]); FN_VERTEX_COUNT = 0; } } if(FN_CACHE_ACTIVE) { FN_CACHE_ARRAY[FN_CACHE_INDEX*3] = FN_VERTEX_BUFFER; } } _global.fnSprite = function(Obj, ScaleX, ScaleY, ScaleA) { Obj._x = FN_VERTEX_BUFFER[0]+fnGetContext()._x; Obj._y = FN_VERTEX_BUFFER[1]+fnGetContext()._y; if(ScaleX) { Obj._xscale = (100-FN_VERTEX_BUFFER[2]); } if(ScaleY) { Obj._yscale = (100-FN_VERTEX_BUFFER[2]); } if(ScaleA) { Obj._alpha = (100-FN_VERTEX_BUFFER[2]); } FN_DEPTH_BUFFER.push(new Array(Obj, FN_VERTEX_BUFFER[2])); } _global.fnBuffer = function() { return FN_VERTEX_BUFFER; } _global.fnClear = function() { // Clears the screen fnGetContext().clear(); FN_DEPTH_BUFFER = new Array(); } _global.fnSort = function() { // Sorts out the sprite depth buffer for(var i = 0; i < FN_DEPTH_BUFFER.length; i++) { for(var j = 0; j < FN_DEPTH_BUFFER.length; j++) { if(FN_DEPTH_BUFFER[i][1] > FN_DEPTH_BUFFER[j][1] && FN_DEPTH_BUFFER[i][0].getDepth() < FN_DEPTH_BUFFER[j][0].getDepth()) { FN_DEPTH_BUFFER[i][0].swapDepths(FN_DEPTH_BUFFER[j][0]); } } } } _global.fnPush = function() { // Pushes a matrix off the stack FN_STACK++; if(!FN_MATRIX[fnGetStack()][FN_VIEW]) { FN_MATRIX[fnGetStack()] = new Array(new Array(), new Array()); FN_MATRIX[fnGetStack()][FN_VIEW] = FN_MATRIX[FN_STACK-1][FN_VIEW]; } else { FN_MATRIX[fnGetStack()][FN_VIEW] = FN_MATRIX[FN_STACK-1][FN_VIEW]; } if(!FN_MATRIX[fnGetStack()][FN_PROJECT]) { FN_MATRIX[fnGetStack()] = new Array(new Array(), new Array()); FN_MATRIX[fnGetStack()][FN_PROJECT] = FN_MATRIX[FN_STACK-1][FN_PROJECT]; } else { FN_MATRIX[fnGetStack()][FN_PROJECT] = FN_MATRIX[FN_STACK-1][FN_PROJECT]; } } _global.fnPop = function() // Pops a matrix off the stack { FN_STACK--; }