package alternativa.engine3d.primitives { import alternativa.engine3d.*; import alternativa.engine3d.core.Mesh; import alternativa.engine3d.core.Object3D; import alternativa.engine3d.core.Surface; import flash.geom.Point; use namespace alternativa3d; /** * Плоскость. */ public class Plane extends Mesh { /** * Создает плоскость. *
Примитив после создания содержит в cебе одну или две поверхности, в зависимости от значения параметров.
* При значении reverse установленном в true примитив будет содержать грань - "back".
* При значении reverse установленном в false примитив будет содержать грань - "front".
* Параметр twoSided указывает методу создать обе поверхности.
true, то формируется двусторонняя плоскость
* @param reverse инвертирование нормалей
* @param triangulate флаг триангуляции. Если указано значение true, четырехугольники в плоскости будут триангулированы.
*/
public function Plane(width:Number = 100, length:Number = 100, widthSegments:uint = 1, lengthSegments:uint = 1, twoSided:Boolean = true, reverse:Boolean = false, triangulate:Boolean = false) {
super();
if ((widthSegments == 0) || (lengthSegments == 0)) {
return;
}
width = (width < 0)? 0 : width;
length = (length < 0)? 0 : length;
// Середина
var wh:Number = width/2;
var lh:Number = length/2;
// Размеры сегмента
var ws:Number = width/widthSegments;
var ls:Number = length/lengthSegments;
// Размеры UV-сегмента
var wd:Number = 1/widthSegments;
var ld:Number = 1/lengthSegments;
// Создание точек и UV
var x:int;
var y:int;
var uv:Array = new Array();
for (y = 0; y <= lengthSegments; y++) {
uv[y] = new Array();
for (x = 0; x <= widthSegments; x++) {
uv[y][x] = new Point(x*wd, y*ld);
createVertex(x*ws - wh, y*ls - lh, 0, x+"_"+y);
}
}
// Создание поверхностей
var front:Surface;
var back:Surface;
if (twoSided || !reverse) {
front = createSurface(null, "front");
}
if (twoSided || reverse) {
back = createSurface(null, "back");
}
// Создание полигонов
for (y = 0; y < lengthSegments; y++) {
for (x = 0; x < widthSegments; x++) {
if (twoSided || !reverse) {
if (triangulate) {
createFace([x + "_" + y, (x + 1) + "_" + y, (x + 1) + "_" + (y + 1)], "front" + x + "_" + y + ":0");
setUVsToFace(uv[y][x], uv[y][x + 1], uv[y + 1][x + 1], "front" + x + "_" + y + ":0");
createFace([(x + 1) + "_" + (y + 1), x + "_" + (y + 1), x + "_" + y], "front" + x + "_" + y + ":1");
setUVsToFace(uv[y + 1][x + 1], uv[y + 1][x], uv[y][x], "front" + x + "_" + y + ":1");
front.addFace("front" + x + "_" + y + ":0");
front.addFace("front" + x + "_" + y + ":1");
} else {
createFace([x + "_" + y, (x + 1) + "_" + y, (x + 1) + "_" + (y + 1), x + "_" + (y + 1)], "front" + x + "_" + y);
setUVsToFace(uv[y][x], uv[y][x + 1], uv[y + 1][x + 1], "front" + x + "_" + y);
front.addFace("front" + x + "_" + y);
}
}
if (twoSided || reverse) {
if (triangulate) {
createFace([x + "_" + y, x + "_" + (y + 1), (x + 1) + "_" + (y + 1)], "back" + x + "_" + y + ":0");
setUVsToFace(uv[lengthSegments - y][x], uv[lengthSegments - y - 1][x], uv[lengthSegments - y - 1][x + 1], "back" + x + "_" + y + ":0");
createFace([(x + 1) + "_" + (y + 1), (x + 1) + "_" + y, x + "_" + y], "back" + x + "_" + y + ":1");
setUVsToFace(uv[lengthSegments - y - 1][x + 1], uv[lengthSegments - y][x + 1], uv[lengthSegments - y][x], "back" + x + "_" + y + ":1");
back.addFace("back" + x + "_" + y + ":0");
back.addFace("back"+x+"_"+y + ":1");
} else {
createFace([x + "_" + y, x + "_" + (y + 1), (x + 1) + "_" + (y + 1), (x + 1) + "_" + y], "back" + x + "_" + y);
setUVsToFace(uv[lengthSegments - y][x], uv[lengthSegments - y - 1][x], uv[lengthSegments - y - 1][x + 1], "back" + x + "_" + y);
back.addFace("back" + x + "_" + y);
}
}
}
}
}
/**
* @inheritDoc
*/
protected override function createEmptyObject():Object3D {
return new Plane(0, 0, 0);
}
}
}