Double-sided mesh
geometry example and some MeshUtils (incomplete package)
to make meshes doublesided.
/**
* Copyright Glidias ( http://wonderfl.net/user/Glidias )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wHml
*/
package {
//geometryexample
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.Vertex;
import alternativ7.engine3d.core.View;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.objects.Mesh;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import alternativ7.engine3d.alternativa3d;
use namespace alternativa3d;
/**
* Geometry example and some MeshUtil methods
(scroll to bottom)
*/
public class GeometryExample extends Sprite {
private var rootContainer:Object3DContainer = new Object3DContainer();
private var camera:Camera3D;
private var controller:SimpleObjectController;
public function GeometryExample() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// Camera and view
// Создание камеры и вьюпорта
camera = new Camera3D();
camera.view = new View(stage.stageWidth, stage.stageHeight);
addChild(camera.view);
addChild(camera.diagram);
// Initial position
// Установка начального положения камеры
camera.rotationX = -120*Math.PI/180;
camera.y = -400;
camera.z = 200;
controller = new SimpleObjectController(stage, camera, 500);
rootContainer.addChild(camera);
// Adding of geometry
// Создание геометрии
var mesh:Mesh = new Mesh();
var v1:Vertex = mesh.addVertex(-100, 100, 0, 0, 0, "v1");
var v2:Vertex = mesh.addVertex(-100, -100, 0, 0, 1, "v2");
var v3:Vertex = mesh.addVertex(100, -100, 0, 1, 1, "v3");
var v4:Vertex = mesh.addVertex(100, 100, 0, 1, 0, "v4");
mesh.addFace(Vector.<Vertex>([v1, v2, v3, v4]), new FillMaterial(0x22AA11, 1, 1));
var material:FillMaterial = new FillMaterial(0xBB3300, 1, 1);
mesh.addVertex(-200, 0, 50, 0, 0, "left");
mesh.addFaceByIds(["v1", "left", "v2"], material);
mesh.addVertex(0, -200, 50, 0, 0, "back");
mesh.addFaceByIds(["v2", "back", "v3"], material);
mesh.addVertex(200, 0, 50, 0, 0, "right");
mesh.addFaceByIds(["v3", "right", "v4"], material);
mesh.addVertex(0, 200, 50, 0, 0, "front");
mesh.addFaceByIds(["v4", "front", "v1"], material);
// Make double-sided!
MeshUtils.makeDoubleSided(mesh);
// Calculating of normals
// Расчёт нормалей
mesh.calculateNormals(true);
// Calculating of bounds
// Расчёт границ
mesh.calculateBounds();
mesh.rotationZ = -0.3;
rootContainer.addChild(mesh);
// Listeners
// Подписка на события
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(Event.RESIZE, onResize);
}
private function onEnterFrame(e:Event):void {
controller.update();
camera.render();
}
private function onResize(e:Event = null):void {
// Width and height of view
// Установка ширины и высоты вьюпорта
camera.view.width = stage.stageWidth;
camera.view.height = stage.stageHeight;
}
}
}
import alternativ7.engine3d.core.Face;
import alternativ7.engine3d.core.Wrapper;
import alternativ7.engine3d.objects.Mesh;
import alternativ7.engine3d.alternativa3d;
use namespace alternativa3d;
internal class MeshUtils {
public static function makeDoubleSided(mesh:Mesh):void {
// Create new list of faces and combine them together
var tailNewFace:Face;
var newFace:Face;
var headNewFace:Face;
var lastFace:Face;
for (var face:Face = mesh.faceList; face!=null; face= face.next) {
newFace = cloneFace(face);
flipFaces(newFace);
if (tailNewFace != null) tailNewFace.next = newFace
else headNewFace = newFace
tailNewFace = newFace;
lastFace = face;
}
// combine lists with new
lastFace.next = headNewFace;
}
public static function cloneFace(face:Face):Face
{
// Prepare cloned face
var clipFace:Face = face.create();
clipFace.material = face.material;
clipFace.offset = face.offset;
clipFace.normalX = face.normalX;
clipFace.normalY = face.normalY;
clipFace.normalZ = face.normalZ;
// deepCloneWrapper() inline
var wrapper:Wrapper = face.wrapper;
var wrapperClone:Wrapper = wrapper.create();
wrapperClone.vertex = wrapper.vertex;
var w:Wrapper = wrapper.next;
var tailWrapper:Wrapper = wrapperClone;
var wClone:Wrapper;
while (w != null) {
wClone = w.create();
wClone.vertex = w.vertex;
tailWrapper.next = wClone;
tailWrapper = wClone;
w = w.next;
}
clipFace.wrapper = wrapperClone;
return clipFace;
}
public static function flipFaces(list:Face):void {
for (var f:Face = list; f != null; f = f.next) {
// Flip normal/offset values
f.normalX = -f.normalX;
f.normalY = -f.normalY;
f.normalZ = -f.normalZ;
f.offset = -f.offset;
// Reverse vertex order
var nextWrapper:Wrapper;
var headerWrapper:Wrapper = null;
for (var w:Wrapper = f.wrapper; w != null; w = nextWrapper) {
nextWrapper = w.next;
w.next = headerWrapper;
headerWrapper = w;
}
f.wrapper = headerWrapper;
}
}
}