import Class from '../core/Class';
import Geometry from './Geometry';
import GeometryData from './GeometryData';
import constants from '../constants';
const {
FRONT,
BACK
} = constants;
const normalData = [0, 0, 1];
/**
* 平面几何体
* @class
* @extends Geometry
*/
const PlaneGeometry = Class.create(/** @lends PlaneGeometry.prototype */ {
Extends: Geometry,
/**
* @default true
* @type {boolean}
*/
isPlaneGeometry: true,
/**
* @default PlaneGeometry
* @type {string}
*/
className: 'PlaneGeometry',
/**
* 宽度
* @default 1
* @type {number}
*/
width: 1,
/**
* 高度
* @default 1
* @type {number}
*/
height: 1,
/**
* 水平分割面的数量
* @default 1
* @type {number}
*/
widthSegments: 1,
/**
* 垂直分割面的数量
* @default 1
* @type {number}
*/
heightSegments: 1,
/**
* @constructs
* @param {object} [params] 创建对象的属性参数。可包含此类的所有属性。
* @param {number} [params.width=1] 宽度
* @param {number} [params.height=1] 高度
* @param {number} [params.widthSegments=1] 水平分割面的数量
* @param {number} [params.heightSegments=1] 垂直分割面的数量
* @param {any} [params.[value:string]] 其它属性
*/
constructor(params) {
PlaneGeometry.superclass.constructor.call(this, params);
this.build();
},
build() {
const {
widthSegments,
heightSegments
} = this;
const count = (widthSegments + 1) * (heightSegments + 1);
const diffW = this.width / widthSegments;
const diffH = this.height / heightSegments;
const vertices = new Float32Array(count * 3);
const normals = new Float32Array(count * 3);
const uvs = new Float32Array(count * 2);
const indices = new Uint16Array(widthSegments * heightSegments * 6);
let indicesIdx = 0;
for (let h = 0; h <= heightSegments; h++) {
for (let w = 0; w <= widthSegments; w++) {
let idx = h * (widthSegments + 1) + w;
vertices[idx * 3] = w * diffW - this.width / 2;
vertices[idx * 3 + 1] = this.height / 2 - h * diffH;
normals[idx * 3] = 0;
normals[idx * 3 + 1] = 0;
normals[idx * 3 + 2] = 1;
uvs[idx * 2] = w / widthSegments;
uvs[idx * 2 + 1] = 1 - h / heightSegments;
if (h < heightSegments && w < widthSegments) {
let lb = (h + 1) * (widthSegments + 1) + w;
indices[indicesIdx++] = idx;
indices[indicesIdx++] = lb;
indices[indicesIdx++] = lb + 1;
indices[indicesIdx++] = idx;
indices[indicesIdx++] = lb + 1;
indices[indicesIdx++] = idx + 1;
}
}
}
this.vertices = new GeometryData(vertices, 3);
this.indices = new GeometryData(indices, 1);
this.normals = new GeometryData(normals, 3);
this.uvs = new GeometryData(uvs, 2);
},
_raycast(ray, side) {
const originZ = ray.origin.z;
const directionZ = ray.direction.z;
if (side === FRONT && (directionZ > 0 || originZ < 0)) {
return null;
}
if (side === BACK && (directionZ < 0 || originZ > 0)) {
return null;
}
const point = ray.intersectsPlane(normalData, 0);
if (point) {
const x = point.x;
const y = point.y;
const halfWidth = this.width * .5;
const halfHeight = this.height * .5;
if (x >= -halfWidth && x <= halfWidth && y >= -halfHeight && y <= halfHeight) {
return [point];
}
}
return null;
}
});
export default PlaneGeometry;