📄 mesh.as
字号:
} private function forgetFaceNeighbours(face:Face):void { if (_neighboursDirty) return; _n01 = _neighbour01[face]; if (_n01 != null) { delete _neighbour01[face]; if (_neighbour01[_n01] == face) delete _neighbour01[_n01]; if (_neighbour12[_n01] == face) delete _neighbour12[_n01]; if (_neighbour20[_n01] == face) delete _neighbour20[_n01]; } _n12 = _neighbour12[face]; if (_n12 != null) { delete _neighbour12[face]; if (_neighbour01[_n12] == face) delete _neighbour01[_n12]; if (_neighbour12[_n12] == face) delete _neighbour12[_n12]; if (_neighbour20[_n12] == face) delete _neighbour20[_n12]; } _n20 = _neighbour20[face]; if (_n20 != null) { delete _neighbour20[face]; if (_neighbour01[_n20] == face) delete _neighbour01[_n20]; if (_neighbour12[_n20] == face) delete _neighbour12[_n20]; if (_neighbour20[_n20] == face) delete _neighbour20[_n20]; } } private function onFaceVertexChange(event:MeshElementEvent):void { if (!_neighboursDirty) { var face:Face = event.element as Face; forgetFaceNeighbours(face); rememberFaceNeighbours(face); } _vertfacesDirty = true; } //TODO: create effective dispose mechanism for meshs /* private function clear():void { for each (var face:Face in _faces.concat([])) removeFace(face); } */ /** * Defines a segment material to be used for outlining the 3d object. */ public var outline:ISegmentMaterial; /** * Defines a triangle material to be used for the backface of all faces in the 3d object. */ public var back:ITriangleMaterial; /** * Indicates whether both the front and reverse sides of a face should be rendered. */ public var bothsides:Boolean; /** * Indicates whether a debug bounding box should be rendered around the 3d object. */ public var debugbb:Boolean; /** * Returns an array of the faces contained in the mesh object. */ public function get faces():Array { return _faces; } /** * Returns an array of the elements contained in the mesh object. */ public override function get elements():Array { return _faces; } /** * Defines the material used to render the faces in the mesh object. * Individual material settings on faces will override this setting. * * @see away3d.core.base.Face#material */ public function get material():ITriangleMaterial { return _material; } public function set material(val:ITriangleMaterial):void { if (_material == val) return; if (_material != null && _material is IUVMaterial) (_material as IUVMaterial).removeOnResize(onMaterialResize); _material = val; if (_material != null && _material is IUVMaterial) (_material as IUVMaterial).addOnResize(onMaterialResize); //reset texturemapping (if applicable) if (_material is IUVMaterial || _material is ILayerMaterial) for each (var face:Face in _faces) if (face._material == null) face._dt.texturemapping = null; } /** * Creates a new <code>BaseMesh</code> object. * * @param init [optional] An initialisation object for specifying default instance properties. */ public function Mesh(init:Object = null) { super(init); material = ini.getMaterial("material"); outline = ini.getSegmentMaterial("outline"); back = ini.getMaterial("back"); bothsides = ini.getBoolean("bothsides", false); debugbb = ini.getBoolean("debugbb", false); if ((material == null) && (outline == null)) material = new WireColorMaterial(); } /** * Adds a face object to the mesh object. * * @param face The face object to be added. */ public function addFace(face:Face):void { addElement(face); _faces.push(face); face._dt.source = face.parent = this; face._dt.create = createDrawTriangle; face.addOnVertexChange(onFaceVertexChange); rememberFaceNeighbours(face); _vertfacesDirty = true; } /** * Removes a face object from the mesh object. * * @param face The face object to be removed. */ public function removeFace(face:Face):void { var index:int = _faces.indexOf(face); if (index == -1) return; removeElement(face); _vertfacesDirty = true; forgetFaceNeighbours(face); face.removeOnVertexChange(onFaceVertexChange); _faces.splice(index, 1); } /** * Inverts the geometry of all face objects. * * @see away3d.code.base.Face#invert() */ public function invertFaces():void { for each (var face:Face in _faces) face.invert(); } /** * Divides a face object into 4 equal sized face objects. * Used to segment a mesh in order to reduce affine persepective distortion. * * @see away3d.primitives.SkyBox */ public function quarterFaces():void { var medians:Dictionary = new Dictionary(); for each (var face:Face in _faces.concat([])) { var v0:Vertex = face.v0; var v1:Vertex = face.v1; var v2:Vertex = face.v2; if (medians[v0] == null) medians[v0] = new Dictionary(); if (medians[v1] == null) medians[v1] = new Dictionary(); if (medians[v2] == null) medians[v2] = new Dictionary(); var v01:Vertex = medians[v0][v1]; if (v01 == null) { v01 = Vertex.median(v0, v1); medians[v0][v1] = v01; medians[v1][v0] = v01; } var v12:Vertex = medians[v1][v2]; if (v12 == null) { v12 = Vertex.median(v1, v2); medians[v1][v2] = v12; medians[v2][v1] = v12; } var v20:Vertex = medians[v2][v0]; if (v20 == null) { v20 = Vertex.median(v2, v0); medians[v2][v0] = v20; medians[v0][v2] = v20; } var uv0:UV = face.uv0; var uv1:UV = face.uv1; var uv2:UV = face.uv2; var uv01:UV = UV.median(uv0, uv1); var uv12:UV = UV.median(uv1, uv2); var uv20:UV = UV.median(uv2, uv0); var material:ITriangleMaterial = face.material; removeFace(face); addFace(new Face(v0, v01, v20, material, uv0, uv01, uv20)); addFace(new Face(v01, v1, v12, material, uv01, uv1, uv12)); addFace(new Face(v20, v12, v2, material, uv20, uv12, uv2)); addFace(new Face(v12, v20, v01, material, uv12, uv20, uv01)); } } /** * Moves the origin point of the mesh without moving the contents. * * @param dx The amount of movement along the local x axis. * @param dy The amount of movement along the local y axis. * @param dz The amount of movement along the local z axis. */ public function movePivot(dx:Number, dy:Number, dz:Number):void { //if (_transformDirty) // updateTransform(); var nd:Boolean = _neighboursDirty; _neighboursDirty = true; for each (var vertex:Vertex in vertices) { vertex.x -= dx; vertex.y -= dy; vertex.z -= dz; } var dV:Number3D = new Number3D(dx, dy, dz); dV.rotate(dV.clone(), _transform); dV.add(dV, position); moveTo(dV); _neighboursDirty = nd; } /** * @inheritDoc * * @see away3d.core.traverse.PrimitiveTraverser * @see away3d.core.draw.DrawTriangle * @see away3d.core.draw.DrawSegment */ override public function primitives(consumer:IPrimitiveConsumer, session:AbstractRenderSession):void { super.primitives(consumer, session); _dtStore = _dtStore.concat(_dtActive); _dtActive = new Array(); if (outline != null) if (_neighboursDirty) findNeighbours(); if (debugbb) { if (_debugboundingbox == null) _debugboundingbox = new WireCube({material:"#white"}); _debugboundingbox.v000.x = minX; _debugboundingbox.v001.x = minX; _debugboundingbox.v010.x = minX; _debugboundingbox.v011.x = minX; _debugboundingbox.v100.x = maxX; _debugboundingbox.v101.x = maxX; _debugboundingbox.v110.x = maxX; _debugboundingbox.v111.x = maxX; _debugboundingbox.v000.y = minY; _debugboundingbox.v001.y = minY; _debugboundingbox.v010.y = maxY; _debugboundingbox.v011.y = maxY; _debugboundingbox.v100.y = minY; _debugboundingbox.v101.y = minY; _debugboundingbox.v110.y = maxY; _debugboundingbox.v111.y = maxY; _debugboundingbox.v000.z = minZ; _debugboundingbox.v001.z = maxZ; _debugboundingbox.v010.z = minZ; _debugboundingbox.v011.z = maxZ; _debugboundingbox.v100.z = minZ; _debugboundingbox.v101.z = maxZ; _debugboundingbox.v110.z = minZ; _debugboundingbox.v111.z = maxZ; if (_faces.length > 0) _debugboundingbox.primitives(consumer, session); } _backmat = back || material; for each (var face:Face in _faces) { if (!face._visible) continue; //project each Vertex to a ScreenVertex _tri = face._dt; _tri.v0 = face._v0.project(projection); _tri.v1 = face._v1.project(projection); _tri.v2 = face._v2.project(projection); //check each ScreenVertex is visible if (!_tri.v0.visible) continue; if (!_tri.v1.visible) continue; if (!_tri.v2.visible) continue; //calculate Draw_triangle properties _tri.calc(); //check _triangle is not behind the camera if (_tri.maxZ < 0) continue; //determine if _triangle is facing towards or away from camera _backface = _tri.area < 0; //if _triangle facing away, check for backface material if (_backface) { if (!bothsides) continue; _tri.material = face._back; } else _tri.material = face._material; //determine the material of the _triangle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -