Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
ActionScript
// forked from yonatan's MCE on SiGL // forked from keim_at_Si's wonderflで3D 【Phong shading】 // forked from keim_at_Si's wonderflで3D 【Flat shading】 高速化 // forked from keim_at_Si's wonderflで3D 【Flat shading】 // 高速化,マウスで光源移動,クリックで材質変更 //-------------------------------------------------- package { import flash.display.*; import flash.text.*; import flash.geom.*; import flash.events.*; import flash.utils.*; import flash.filters.*; import flash.ui.*; // import net.hires.debug.Stats; [SWF(width="465", height="465", backgroundColor="0xE0E0E0", frameRate="30")] public class main extends Sprite { private const _sides:int = 4; private const _sections:int = 72; private var _matrix:Matrix3D = new Matrix3D(); private var _rotMatrix:Matrix3D = new Matrix3D(); private var _engine:EngineFaceBasedRender = new EngineFaceBasedRender(800, _sections*_sides*8); private var _material:Material = new Material; private var _light:Light = new Light(); private var _models:Array = []; private var _model:Knot; private var _transformedSideNormals:Vector.
= new Vector.
(); private var _mousePoint:Point; private var _timeSum:int, _timeCount:int; private var _textField:TextField = new TextField(); function main() { var i:int; for (i=0; i<60; i++) _models.push(new Knot(2, 3, _sections, _sides, 2/3, i/60)); stage.quality = "medium"; _engine.x = 232; _engine.y = 232; // GlowFilter(color:uint = 0xFF0000, alpha:Number = 1.0, blurX:Number = 6.0, blurY:Number = 6.0, // strength:Number = 2, quality:int = 1, inner:Boolean = false, knockout:Boolean = false) _engine.filters = [new GlowFilter(0, 1, 4, 4, 2, 2)]; addChild(_engine); addEventListener("enterFrame", _onEnterFrame); Mouse.cursor = MouseCursor.BUTTON; stage.addEventListener("mouseDown", function(e:Event):void { _mousePoint = new Point(mouseX, mouseY); Mouse.cursor = MouseCursor.HAND; }); stage.addEventListener("mouseUp", function(e:Event):void { _mousePoint = null; Mouse.cursor = MouseCursor.BUTTON; }); // initialize parameters // _timeSum = 0; // _timeCount = 0; // _textField.autoSize = "left"; // _textField.background = true; // _textField.backgroundColor = 0x80f080; // addChild(_textField); // var status:Stats = new Stats(); // status.x = 400; // addChild(status); } private function _onEnterFrame(e:Event) : void { var i:int, t:int; _model = _models[int(getTimer()/10) % _models.length]; // update paremters if(_mousePoint) { var p:Point = new Point(mouseX, mouseY).subtract(_mousePoint); var axis:Vector3D = new Vector3D(p.y, -p.x, 0); axis.normalize(); _rotMatrix.appendRotation(p.length/2, axis) _mousePoint.x = mouseX; _mousePoint.y = mouseY; } // light position var lx:Number = (Math.max(0, Math.min(2, mouseX / (465 / 2))) - 1) / Math.SQRT2; var ly:Number = (Math.max(0, Math.min(2, mouseY / (465 / 2))) - 1) / Math.SQRT2; var lz:Number = -Math.sqrt(1 - (lx*lx+ly*ly)); _light.setPosition(lx, ly, lz); t = getTimer(); _engine.pushMatrix(); _matrix.identity(); _matrix.append(_rotMatrix); _matrix.appendScale(10, 10, 10); _matrix.appendTranslation(0, 0, 150); _engine.matrix.append(_matrix); _engine.project(_model); _calculateVertexNormal(); _engine.render(_model, _light, _material); _engine.popMatrix(); _timeSum += getTimer() - t; // if (++_timeCount == 30) { // _textField.text = "Redering time: " + String(_timeSum) + "[ms/30frames]"; // _timeSum = 0; // _timeCount = 0; // } } private function _calculateVertexNormal() : void { var len:int = _transformedSideNormals.length; var ni:int = 0; var ti:int = 0; _rotMatrix.transformVectors(_model.sideNormals, _transformedSideNormals); while (ni
0) intensity = -intensity; // front/back material var u:Number = 0.5 + intensity/2; _model.texCoord[ti] = u; ti+=3; _model.texCoord[ti] = u; ti+=3; _model.texCoord[ti] = u; ti+=3; _model.texCoord[ti] = u; ti+=3; } } } } import flash.display.*; import flash.filters.*; import flash.geom.*; class EngineFaceBasedRender extends Shape { public var matrix:Matrix3D; private var _vertexOnWorld:Vector.
; private var _vout:Vector.
; private var _projector:PerspectiveProjection; private var _projectionMatrix:Matrix3D; private var _matrixStac:Vector.
; function EngineFaceBasedRender(focus:Number=400, numVerts:int = 0) { _vertexOnWorld = new Vector.
(numVerts*3, numVerts != 0); _vout = new Vector.
; _projector = new PerspectiveProjection(); _matrixStac = new Vector.
(); initialize(focus); } public function initialize(focus:Number) : EngineFaceBasedRender { _projector.focalLength = focus; _projectionMatrix = _projector.toMatrix3D(); matrix = new Matrix3D(); _matrixStac.length = 1; _matrixStac[0] = matrix; return this; } public function clearMatrix() : EngineFaceBasedRender { matrix = _matrixStac[0]; _matrixStac.length = 1; return this; } public function pushMatrix() : EngineFaceBasedRender { _matrixStac.push(matrix.clone()); return this; } public function popMatrix() : EngineFaceBasedRender { if (_matrixStac.length == 1) return this; matrix = _matrixStac.pop(); return this; } public function project(model:Model) : EngineFaceBasedRender { matrix.transformVectors(model.vertices, _vertexOnWorld); var vertices:Vector.
= _vertexOnWorld; for each (var face:Face in model.faces) { var z:Number; z = vertices[int(int((face.i0<<1) + face.i0) + 2)]; z += vertices[int(int((face.i1<<1) + face.i1) + 2)]; z += vertices[int(int((face.i2<<1) + face.i2) + 2)]; face.z = z; } model.faces.sort(function(f1:Face, f2:Face) : Number { return f2.z - f1.z; }); return this; } public function render(model:Model, light:Light, material:Material) : EngineFaceBasedRender { Utils3D.projectVectors(_projectionMatrix, _vertexOnWorld, _vout, model.texCoord); graphics.clear(); graphics.beginBitmapFill(material.texture, null, false, true); graphics.drawTriangles(_vout, model.indices, model.texCoord); graphics.endFill(); return this; } } class Face { public var i0:int, i1:int, i2:int, z:Number; // Factory static private var _freeList:Vector.
= new Vector.
(); static public function alloc() : Face { return _freeList.pop() || new Face(); } static public function free(face:Face) : void { _freeList.push(face); } } class Model { public var vertices:Vector.
; public var texCoord:Vector.
; public var faces:Vector.
; private var _indices:Vector.
= new Vector.
(); private var _faceIdx:int = 0; function Model(vertices:Vector.
=null, texCoord:Vector.
=null, faces:Vector.
=null) { this.vertices = vertices || new Vector.
(); this.texCoord = texCoord || new Vector.
(); this.faces = faces || new Vector.
(); if(faces) { _indices = new Vector.
(faces.length*3, true); } } public function clear() : Model { for each (var face:Face in faces) Face.free(face); faces = new Vector.
(); _faceIdx = 0; return this; } public function face(i0:int, i1:int, i2:int) : Model { var face:Face = Face.alloc(); face.i0 = i0; face.i1 = i1; face.i2 = i2; faces[_faceIdx++] = face; return this; } public function get indices() : Vector.
{ var i:int = 0; for each (var face:Face in faces) { _indices[i++] = face.i0; _indices[i++] = face.i1; _indices[i++] = face.i2; } return _indices; } } class Light { private var _direction:Vector3D = new Vector3D(); private var _halfVector:Vector3D = new Vector3D(); public function get direction() : Vector3D { return _direction; } public function get halfVector() : Vector3D { return _halfVector; } function Light(x:Number=1, y:Number=1, z:Number=1) { setPosition(x, y, z); } public function setPosition(x:Number, y:Number, z:Number) : void { _direction.x = -x; _direction.y = -y; _direction.z = -z; _direction.normalize(); _halfVector.x = _direction.x; _halfVector.y = _direction.y; _halfVector.z = _direction.z + 1; _halfVector.normalize(); } } class Material { private static const LINES:int = 13; private static const W:int = 0x800; private static const H:int = 0x100; public var texture:BitmapData = new BitmapData(W,H,false); private var _shape:Shape = new Shape; function Material() { setColor(0xdb9438, 0xb2a64a); } protected function _drawLines(color:uint, start:Number, end:Number):void { for(var line:int = 0; line
; public function Knot(p:int = 2, q:int = 3, sections:int = 72, sides:int = 4, thickness:Number = 2/3, offset:Number = 0) { var numVerts:int = sections*sides*8; _p = p; _q = q; _sections = sections; _slices = sections * 2; _sides = sides; _thickness = thickness; _offset = offset; super( new Vector.
(numVerts*3, true), new Vector.
(numVerts*3, true), new Vector.
(sections*sides*8, true) ); sideNormals = new Vector.
(_slices*_sides*3, true) _createVertices(); _createFaces(); _createNormals(); } protected function _createNormals():void { var i:int = 0; for(var section:int=0; section<_sections; section++) { for(var side:int=0; side<_sides; side++) { for(var slice:int=0; slice<2; slice++) { var u:Number = Math.PI*2 * (section*2+slice)/_slices; var v:Number = Math.PI*2 * side/_sides - u*(_sides-1)/_sides; var n:Vector3D = _extrudedPoint(u, v, 1); n.decrementBy(_curvePoint(u)); n.normalize(); sideNormals[i++] = n.x; sideNormals[i++] = n.y; sideNormals[i++] = n.z; } } } } protected function _createFaces():void { for(var section:int=0; section<_sections; section++) { for(var side:int=0; side<_sides; side++) { var i:int = section*_sides*8 + side*8; // section face(i+1, i+0, i+4).face(i+4, i+5, i+1) i++; face(i+1, i+0, i+4).face(i+4, i+5, i+1) i++; face(i+1, i+0, i+4).face(i+4, i+5, i+1) i--; i--; // connector var i0:int, i1:int, i2:int, i3:int; i0=i+5; i1=i+6; i += _sides*8; if(section+1 == _sections) { i+=8; // compensate for twist if(side+1 == _sides) i = 0; } i %= vertices.length/3; i2=i+1; i3=i+2; face(i0, i2, i1); face(i2, i3, i1); } } } protected function _createVertices():void { var i:int = 0; function _vertex(v:Vector3D, texv:Number):void { vertices[i] = v.x; texCoord[i++] = 0; vertices[i] = v.y; texCoord[i++] = texv; vertices[i] = v.z; texCoord[i++] = 0; } for(var section:int=0; section<_sections; section++) { for(var side:int=0; side<_sides; side++) { var p:Number; for each(p in [0, 0.4, 0.6, 1]) _vertex(_edgePoint(section*2, side, p), p); for each(p in [0, 0.4, 0.6, 1]) _vertex(_edgePoint(section*2+1, side, p), p); } } } // 0 <= p <= 1 is the offset along the edge protected function _edgePoint(slice:int, side:int, p:Number):Vector3D { var u:Number = Math.PI*2 * slice/_slices; var v:Number = Math.PI*2 * side/_sides - u*(_sides-1)/_sides; v -= Math.PI / _sides; // make side 0 parallel to Z axis var v0:Vector3D = _extrudedPoint(u, v, _thickness); var v1:Vector3D = _extrudedPoint(u, v + Math.PI*2/_sides, _thickness); return _vlerp(v0, v1, p); } protected function _extrudedPoint(u:Number, v:Number, length:Number):Vector3D { v -= Math.PI*2*_offset/_sections*(_sides-1)/_sides; // calculate curve point and normal vectors from u var cp:Vector3D = _curvePoint(u); var ncp:Vector3D = _curvePoint(u+0.0001); var t:Vector3D = ncp.subtract(cp); var n:Vector3D = ncp.add(cp); var b:Vector3D = t.crossProduct(n); n = b.crossProduct(t); n.normalize(); b.normalize(); // extrude in direction v var cx:Number = length * Math.sin(v); var cy:Number = length * -Math.cos(v); return new Vector3D( cp.x + cx*n.x + cy*b.x, cp.y + cx*n.y + cy*b.y, cp.z + cx*n.z + cy*b.z ); } protected function _curvePoint(t:Number):Vector3D { t += Math.PI*2*_offset/_sections; return new Vector3D( 2 * Math.sin(t*_p) - Math.sin(t), -(2 * Math.cos(t*_p) + Math.cos(t)), Math.sin(t*_q) ); } protected function _vlerp(v0:Vector3D, v1:Vector3D, p:Number):Vector3D { return new Vector3D( v0.x*(1-p) + v1.x*p, v0.y*(1-p) + v1.y*p, v0.z*(1-p) + v1.z*p, v0.w*(1-p) + v1.w*p ); } }
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email