ts-game-engine
Version:
Simple WebGL game/render engine written in TypeScript
94 lines (93 loc) • 5.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Mesh_1 = require("./Mesh");
const gl_matrix_1 = require("gl-matrix");
class SphereMesh extends Mesh_1.Mesh {
constructor(scene, widthSegments, heightSegments) {
super(scene);
this.widthSegments = Math.max(3, Math.floor(widthSegments));
this.heightSegments = Math.max(3, Math.floor(heightSegments));
const radius = 0.5;
const phiStart = 0;
const phiLength = Math.PI * 2;
const thetaStart = 0;
const thetaLength = Math.PI;
const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
const tempVec3 = gl_matrix_1.vec3.create();
const vertexCount = (this.widthSegments + 1) * (this.heightSegments + 1) - 2;
const vertexData = new Float32Array(vertexCount * (Mesh_1.VERTEX_POSITION_SIZE + Mesh_1.VERTEX_COLOR_SIZE + Mesh_1.VERTEX_NORMAL_SIZE + Mesh_1.VERTEX_UV_SIZE));
let i = 0;
for (let iy = 0; iy <= this.heightSegments; iy++) {
const v = iy / this.heightSegments;
let uOffset = 0;
if ((iy === 0 && thetaStart === 0) || (iy === this.heightSegments && thetaEnd === Math.PI)) {
uOffset = 0.5 / this.widthSegments;
}
for (let ix = 0; ix <= this.widthSegments; ix++) {
if (ix === this.widthSegments && (iy === 0 || iy === this.heightSegments))
continue;
const u = ix / this.widthSegments;
// Position
tempVec3[0] = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
tempVec3[1] = radius * Math.cos(thetaStart + v * thetaLength);
tempVec3[2] = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
vertexData[i++] = tempVec3[0];
vertexData[i++] = tempVec3[1];
vertexData[i++] = tempVec3[2];
// Color
vertexData[i++] = 1;
vertexData[i++] = 1;
vertexData[i++] = 1;
vertexData[i++] = 1;
// Normal
gl_matrix_1.vec3.normalize(tempVec3, tempVec3);
vertexData[i++] = tempVec3[0];
vertexData[i++] = tempVec3[1];
vertexData[i++] = tempVec3[2];
// UV0
vertexData[i++] = u + uOffset;
vertexData[i++] = 1 - v;
}
}
const triangleCount = this.widthSegments * (this.heightSegments - 1) * 2;
const indexCount = triangleCount * 3;
const indexData = new Uint16Array(indexCount);
i = 0;
for (let iy = 0; iy < this.heightSegments; iy++) {
for (let ix = 0; ix < this.widthSegments; ix++) {
if (iy === 0) {
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 0) + iy;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + iy;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 1) + iy;
}
else if (iy === 1) {
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 1) + iy - 1;
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 0) + iy - 1;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + iy;
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 1);
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + 1;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 1) + 1;
}
else if (iy > 1 && iy < this.heightSegments - 1) {
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 1) + iy - 1;
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 0) + iy - 1;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + iy;
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 1) + iy - 1;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + iy;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 1) + iy;
}
else if (iy === this.heightSegments - 1) {
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 1) + iy - 1;
indexData[i++] = (iy + 0) * (this.widthSegments) + (ix + 0) + iy - 1;
indexData[i++] = (iy + 1) * (this.widthSegments) + (ix + 0) + iy;
}
}
}
const vertexFormat = 1 /* Position */ | 2 /* Color */ | 4 /* Normal */ | 8 /* UV0 */;
this.SetVertexData(vertexFormat, 4 /* Triangles */, vertexCount, vertexData, false);
this.SetIndexData(indexData);
this.SetBounds(gl_matrix_1.vec3.fromValues(-0.5, -0.5, -0.5), gl_matrix_1.vec3.fromValues(0.5, 0.5, 0.5)); // { center: vec3.fromValues(0, 0, 0), radius: 0.707107 }
this.isLoaded = true;
}
}
exports.SphereMesh = SphereMesh;