mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
Fix tornado
This commit is contained in:
parent
5f3163b85d
commit
04f2b4f480
3 changed files with 534 additions and 197 deletions
338
src/DtsObject.hx
338
src/DtsObject.hx
|
|
@ -1,5 +1,11 @@
|
|||
package src;
|
||||
|
||||
import hxd.FloatBuffer;
|
||||
import h3d.prim.DynamicPrimitive;
|
||||
import h3d.scene.Trail;
|
||||
import src.DynamicPolygon;
|
||||
import h3d.mat.Data.Blend;
|
||||
import h3d.prim.Cube;
|
||||
import dts.Sequence;
|
||||
import h3d.scene.Mesh;
|
||||
import h3d.scene.CustomObject;
|
||||
|
|
@ -56,22 +62,21 @@ class DtsObject extends Object {
|
|||
var sequenceKeyframeOverride:Map<Sequence, Float> = new Map();
|
||||
var lastSequenceKeyframes:Map<Sequence, Float> = new Map();
|
||||
|
||||
var graphNodes:Array<GraphNode> = [];
|
||||
var rootGraphNodes:Array<GraphNode> = [];
|
||||
var nodeTransforms:Array<Matrix> = [];
|
||||
|
||||
var dynamicGeometryLookup:Map<Object, Int> = new Map();
|
||||
var graphNodes:Array<Object> = [];
|
||||
|
||||
var isTSStatic:Bool;
|
||||
var isCollideable:Bool;
|
||||
var showSequences:Bool = true;
|
||||
var hasNonVisualSequences:Bool = true;
|
||||
|
||||
var geometries:Array<Object> = [];
|
||||
var _regenNormals:Bool = false;
|
||||
|
||||
var skinMeshData:SkinMeshData;
|
||||
|
||||
var fs:Loader;
|
||||
|
||||
var rootObject:Object;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -80,44 +85,30 @@ class DtsObject extends Object {
|
|||
this.dts = ResourceLoader.loadDts(this.dtsPath);
|
||||
this.directoryPath = Path.directory(this.dtsPath);
|
||||
|
||||
for (i in 0...dts.nodes.length)
|
||||
this.nodeTransforms.push(new Matrix());
|
||||
|
||||
this.computeMaterials();
|
||||
|
||||
var graphNodes = [];
|
||||
for (i in 0...dts.nodes.length) {
|
||||
var graphNode:GraphNode = {
|
||||
index: i,
|
||||
node: dts.nodes[i],
|
||||
children: [],
|
||||
parent: null
|
||||
};
|
||||
graphNodes.push(graphNode);
|
||||
var rootNodesIdx = [];
|
||||
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
graphNodes.push(new Object());
|
||||
}
|
||||
for (i in 0...dts.nodes.length) {
|
||||
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
var node = this.dts.nodes[i];
|
||||
if (node.parent != -1) {
|
||||
graphNodes[i].parent = graphNodes[node.parent];
|
||||
graphNodes[node.parent].children.push(graphNodes[i]);
|
||||
graphNodes[node.parent].addChild(graphNodes[i]);
|
||||
} else {
|
||||
rootNodesIdx.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
this.graphNodes = graphNodes;
|
||||
this.rootGraphNodes = graphNodes.filter(node -> node.parent == null);
|
||||
// this.rootGraphNodes = graphNodes.filter(node -> node.parent == null);
|
||||
this.updateNodeTransforms();
|
||||
|
||||
var affectedBySequences = this.dts.sequences.length > 0 ? (this.dts.sequences[0].rotationMatters.length < 0 ? 0 : this.dts.sequences[0].rotationMatters[0]) | (this.dts.sequences[0].translationMatters.length > 0 ? this.dts.sequences[0].translationMatters[0] : 0) : 0;
|
||||
|
||||
var staticMaterialGeometries = [];
|
||||
var dynamicMaterialGeometries = [];
|
||||
var dynamicGeometriesMatrices = [];
|
||||
var collisionMaterialGeometries = [];
|
||||
|
||||
var staticGeometries = [];
|
||||
var dynamicGeometries = [];
|
||||
var collisionGeometries = [];
|
||||
|
||||
for (i in 0...dts.nodes.length) {
|
||||
var objects = dts.objects.filter(object -> object.node == i);
|
||||
var sequenceAffected = ((1 << i) & affectedBySequences) != 0;
|
||||
|
|
@ -125,113 +116,80 @@ class DtsObject extends Object {
|
|||
for (object in objects) {
|
||||
var isCollisionObject = dts.names[object.name].substr(0, 3).toLowerCase() == "col";
|
||||
|
||||
if (!isCollisionObject || this.isCollideable) {
|
||||
var mat = this.nodeTransforms[i];
|
||||
if (isCollisionObject)
|
||||
continue;
|
||||
|
||||
for (i in object.firstMesh...(object.firstMesh + object.numMeshes)) {
|
||||
if (i >= this.dts.meshes.length)
|
||||
for (j in object.firstMesh...(object.firstMesh + object.numMeshes)) {
|
||||
if (j >= this.dts.meshes.length)
|
||||
continue;
|
||||
|
||||
var mesh = this.dts.meshes[j];
|
||||
if (mesh == null)
|
||||
continue;
|
||||
|
||||
var vertices = mesh.vertices.map(v -> new Vector(v.x, v.y, v.z));
|
||||
var vertexNormals = mesh.normals.map(v -> new Vector(v.x, v.y, v.z));
|
||||
|
||||
var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals);
|
||||
for (k in 0...geometry.length) {
|
||||
if (geometry[k].vertices.length == 0)
|
||||
continue;
|
||||
|
||||
var mesh = this.dts.meshes[i];
|
||||
var poly = new Polygon(geometry[k].vertices.map(x -> x.toPoint()));
|
||||
poly.normals = geometry[k].normals.map(x -> x.toPoint());
|
||||
poly.uvs = geometry[k].uvs;
|
||||
|
||||
var vertices = mesh.vertices.map(v -> new Vector(v.x, v.y, v.z));
|
||||
var vertexNormals = mesh.normals.map(v -> new Vector(v.x, v.y, v.z));
|
||||
|
||||
if (!sequenceAffected)
|
||||
for (vector in vertices) {
|
||||
vector.transform(mat);
|
||||
}
|
||||
if (!sequenceAffected)
|
||||
for (vector in vertexNormals) {
|
||||
vector.transform3x3(mat);
|
||||
}
|
||||
|
||||
var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals);
|
||||
if (!sequenceAffected) {
|
||||
staticMaterialGeometries.push(geometry);
|
||||
} else {
|
||||
dynamicMaterialGeometries.push(geometry);
|
||||
dynamicGeometriesMatrices.push(mat);
|
||||
}
|
||||
|
||||
if (isCollisionObject)
|
||||
collisionMaterialGeometries.push(geometry);
|
||||
var obj = new Mesh(poly, materials[k], this.graphNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var skinnedMeshIndex:Int = -1;
|
||||
for (i in 0...dts.meshes.length) {
|
||||
var dtsMesh = this.dts.meshes[i];
|
||||
|
||||
if (dtsMesh == null || dtsMesh.type != 1)
|
||||
for (i in 0...this.dts.meshes.length) {
|
||||
var mesh = this.dts.meshes[i];
|
||||
if (mesh == null)
|
||||
continue;
|
||||
|
||||
var vertices = [];
|
||||
for (i in 0...dtsMesh.vertices.length)
|
||||
vertices.push(new Vector());
|
||||
if (mesh.meshType == 1) {
|
||||
var vertices = mesh.vertices.map(v -> new Vector(v.x, v.y, v.z));
|
||||
var vertexNormals = mesh.normals.map(v -> new Vector(v.x, v.y, v.z));
|
||||
|
||||
var vertexNormals = [];
|
||||
for (i in 0...dtsMesh.normals.length)
|
||||
vertexNormals.push(new Vector());
|
||||
var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals);
|
||||
var skinObj = new Object();
|
||||
for (k in 0...geometry.length) {
|
||||
if (geometry[k].vertices.length == 0)
|
||||
continue;
|
||||
|
||||
var materialGeometry = this.generateMaterialGeometry(dtsMesh, vertices, vertexNormals);
|
||||
staticMaterialGeometries.push(materialGeometry);
|
||||
var poly = new DynamicPolygon(geometry[k].vertices.map(x -> x.toPoint()));
|
||||
poly.normals = geometry[k].normals.map(x -> x.toPoint());
|
||||
poly.uvs = geometry[k].uvs;
|
||||
|
||||
skinnedMeshIndex = i;
|
||||
break; // Bruh
|
||||
}
|
||||
|
||||
var staticNonCollision = staticMaterialGeometries.filter(x -> !collisionMaterialGeometries.contains(x));
|
||||
var staticCollision = staticMaterialGeometries.filter(x -> collisionMaterialGeometries.contains(x));
|
||||
|
||||
if (staticNonCollision.length > 0) {
|
||||
var merged = this.mergeMaterialGeometries(staticNonCollision);
|
||||
var geometry = this.createGeometryFromMaterialGeometry(merged);
|
||||
staticGeometries.push(geometry);
|
||||
this.geometries.push(geometry);
|
||||
|
||||
if (skinnedMeshIndex != -1) {
|
||||
this.skinMeshData = {
|
||||
meshIndex: skinnedMeshIndex,
|
||||
vertices: this.dts.meshes[skinnedMeshIndex].vertices.map(x -> new Vector()),
|
||||
normals: this.dts.meshes[skinnedMeshIndex].normals.map(x -> new Vector()),
|
||||
indices: [],
|
||||
geometry: geometry
|
||||
var obj = new Mesh(poly, materials[k], skinObj);
|
||||
}
|
||||
var idx = merged.map(x -> x.indices);
|
||||
for (i in idx) {
|
||||
this.skinMeshData.indices = this.skinMeshData.indices.concat(i);
|
||||
skinMeshData = {
|
||||
meshIndex: i,
|
||||
vertices: vertices,
|
||||
normals: vertexNormals,
|
||||
indices: [],
|
||||
geometry: skinObj
|
||||
};
|
||||
var idx = geometry.map(x -> x.indices);
|
||||
for (indexes in idx) {
|
||||
skinMeshData.indices = skinMeshData.indices.concat(indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (staticCollision.length > 0) {
|
||||
var geometry = this.createGeometryFromMaterialGeometry(this.mergeMaterialGeometries(staticCollision));
|
||||
staticGeometries.push(geometry);
|
||||
collisionGeometries.push(geometry);
|
||||
this.geometries.push(geometry);
|
||||
rootObject = new Object(this);
|
||||
|
||||
for (i in rootNodesIdx) {
|
||||
rootObject.addChild(this.graphNodes[i]);
|
||||
}
|
||||
if (this.skinMeshData != null) {
|
||||
rootObject.addChild(this.skinMeshData.geometry);
|
||||
}
|
||||
|
||||
for (materialGeom in dynamicMaterialGeometries) {
|
||||
var geometry = this.createGeometryFromMaterialGeometry(materialGeom);
|
||||
dynamicGeometries.push(geometry);
|
||||
if (collisionMaterialGeometries.contains(materialGeom))
|
||||
collisionGeometries.push(geometry);
|
||||
this.geometries.push(geometry);
|
||||
}
|
||||
|
||||
for (geometry in staticGeometries) {
|
||||
this.addChild(geometry);
|
||||
}
|
||||
|
||||
for (i in 0...dynamicGeometries.length) {
|
||||
var geometry = dynamicGeometries[i];
|
||||
dynamicGeometryLookup.set(geometry, this.nodeTransforms.indexOf(dynamicGeometriesMatrices[i]));
|
||||
geometry.setTransform(dynamicGeometriesMatrices[i]);
|
||||
this.addChild(geometry);
|
||||
}
|
||||
rootObject.scaleX = -1;
|
||||
}
|
||||
|
||||
function computeMaterials() {
|
||||
|
|
@ -262,6 +220,10 @@ class DtsObject extends Object {
|
|||
material.texture = texture;
|
||||
// TODO TRANSLUENCY SHIT
|
||||
}
|
||||
if (flags & 4 > 0) {
|
||||
material.blendMode = BlendMode.Alpha;
|
||||
material.mainPass.culling = h3d.mat.Data.Face.Front;
|
||||
}
|
||||
// TODO TRANSPARENCY SHIT
|
||||
if (flags & 8 > 0)
|
||||
material.blendMode = BlendMode.Add;
|
||||
|
|
@ -284,57 +246,16 @@ class DtsObject extends Object {
|
|||
}
|
||||
|
||||
function updateNodeTransforms(quaternions:Array<Quat> = null, translations:Array<Vector> = null, bitField = 0xffffffff) {
|
||||
if (quaternions == null) {
|
||||
quaternions = [];
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
var rotation = this.dts.defaultRotations[i];
|
||||
var quat = new Quat(rotation.x, rotation.y, rotation.z, rotation.w);
|
||||
quat.normalize();
|
||||
quat.conjugate();
|
||||
quaternions.push(quat);
|
||||
}
|
||||
}
|
||||
|
||||
if (translations == null) {
|
||||
translations = [];
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
var translation = this.dts.defaultTranslations[i];
|
||||
translations.push(new Vector(translation.x, translation.y, translation.z));
|
||||
}
|
||||
}
|
||||
|
||||
var utiltyMatrix = new Matrix();
|
||||
|
||||
function traverse(node:GraphNode, needsUpdate:Bool) {
|
||||
if (((1 << node.index) & bitField) != 0)
|
||||
needsUpdate = true;
|
||||
|
||||
if (needsUpdate) {
|
||||
// Recompute the matrix
|
||||
var mat = this.nodeTransforms[node.index];
|
||||
|
||||
if (node.parent == null) {
|
||||
mat = Matrix.I();
|
||||
} else {
|
||||
mat = this.nodeTransforms[node.parent.index].clone(); // mat.load(this.nodeTransforms[node.parent.index]);
|
||||
}
|
||||
|
||||
var quat = quaternions[node.index];
|
||||
var translation = translations[node.index];
|
||||
quat.toMatrix(utiltyMatrix);
|
||||
utiltyMatrix.scale(1 / utiltyMatrix.getDeterminant());
|
||||
utiltyMatrix.setPosition(translation);
|
||||
mat.multiply(mat, utiltyMatrix);
|
||||
this.nodeTransforms[node.index] = mat;
|
||||
}
|
||||
|
||||
for (i in 0...node.children.length)
|
||||
traverse(node.children[i], needsUpdate);
|
||||
}
|
||||
|
||||
for (i in 0...this.rootGraphNodes.length) {
|
||||
var rootNode = this.rootGraphNodes[i];
|
||||
traverse(rootNode, false);
|
||||
for (i in 0...this.graphNodes.length) {
|
||||
var translation = this.dts.defaultTranslations[i];
|
||||
var rotation = this.dts.defaultRotations[i];
|
||||
var mat = Matrix.I();
|
||||
var quat = new Quat(rotation.x, rotation.y, rotation.z, rotation.w);
|
||||
quat.normalize();
|
||||
quat.conjugate();
|
||||
quat.toMatrix(mat);
|
||||
mat.setPosition(new Vector(translation.x, translation.y, translation.z));
|
||||
this.graphNodes[i].setTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +283,7 @@ class DtsObject extends Object {
|
|||
i3 = temp;
|
||||
}
|
||||
|
||||
for (index in [i1, i2, i3]) {
|
||||
for (index in [i3, i2, i1]) {
|
||||
var vertex = vertices[index];
|
||||
geometrydata.vertices.push(new Vector(vertex.x, vertex.y, vertex.z));
|
||||
|
||||
|
|
@ -464,15 +385,17 @@ class DtsObject extends Object {
|
|||
var quat = new Quat();
|
||||
quat.slerp(q1, q2, t);
|
||||
quat.normalize();
|
||||
|
||||
this.graphNodes[i].setRotationQuat(quat);
|
||||
affectedCount++;
|
||||
quaternions.push(quat);
|
||||
// quaternions.push(quat);
|
||||
} else {
|
||||
var rotation = this.dts.defaultRotations[i];
|
||||
var quat = new Quat(rotation.x, rotation.y, rotation.z, rotation.w);
|
||||
quat.normalize();
|
||||
quat.conjugate();
|
||||
|
||||
quaternions.push(quat);
|
||||
this.graphNodes[i].setRotationQuat(quat);
|
||||
// quaternions.push(quat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -490,23 +413,18 @@ class DtsObject extends Object {
|
|||
|
||||
var v1 = new Vector(trans1.x, trans1.y, trans1.z);
|
||||
var v2 = new Vector(trans2.x, trans2.y, trans2.z);
|
||||
var trans = Util.lerpThreeVectors(v1, v2, t);
|
||||
this.graphNodes[i].setPosition(trans.x, trans.y, trans.z);
|
||||
|
||||
translations.push(Util.lerpThreeVectors(v1, v2, t));
|
||||
// translations.push(Util.lerpThreeVectors(v1, v2, t));
|
||||
} else {
|
||||
var translation = this.dts.defaultTranslations[i];
|
||||
translations.push(new Vector(translation.x, translation.y, translation.z));
|
||||
var trans = new Vector(translation.x, translation.y, translation.z);
|
||||
this.graphNodes[i].setPosition(trans.x, trans.y, trans.z);
|
||||
// translations.push();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rot > 0 || trans > 0) {
|
||||
this.updateNodeTransforms(quaternions, translations, rot | trans);
|
||||
}
|
||||
}
|
||||
|
||||
for (kvp in dynamicGeometryLookup.keyValueIterator()) {
|
||||
var tform = this.nodeTransforms[kvp.value];
|
||||
kvp.key.setTransform(tform);
|
||||
}
|
||||
|
||||
if (this.skinMeshData != null) {
|
||||
|
|
@ -519,27 +437,24 @@ class DtsObject extends Object {
|
|||
}
|
||||
|
||||
var boneTransformations = [];
|
||||
var boneTransformationsTransposed = [];
|
||||
|
||||
for (i in 0...mesh.nodeIndices.length) {
|
||||
var mat = mesh.initialTransforms[i].clone();
|
||||
mat.transpose();
|
||||
mat.multiply(this.nodeTransforms[mesh.nodeIndices[i]], mat);
|
||||
var tform = this.graphNodes[mesh.nodeIndices[i]].getAbsPos().clone();
|
||||
mat.multiply(mat, tform);
|
||||
|
||||
boneTransformations.push(mat);
|
||||
var m = mat.clone();
|
||||
m.transpose();
|
||||
boneTransformationsTransposed.push(m);
|
||||
}
|
||||
|
||||
var vec = new Vector();
|
||||
var vec2 = new Vector();
|
||||
|
||||
for (i in 0...mesh.vertexIndices.length) {
|
||||
var vIndex = mesh.vertexIndices[i];
|
||||
var vertex = mesh.vertices[vIndex];
|
||||
var normal = mesh.normals[vIndex];
|
||||
|
||||
var vec = new Vector();
|
||||
var vec2 = new Vector();
|
||||
|
||||
vec.set(vertex.x, vertex.y, vertex.z);
|
||||
vec2.set(normal.x, normal.y, normal.z);
|
||||
var mat = boneTransformations[mesh.boneIndices[i]];
|
||||
|
|
@ -563,26 +478,57 @@ class DtsObject extends Object {
|
|||
|
||||
var meshIndex = 0;
|
||||
var mesh:Mesh = cast info.geometry.children[meshIndex];
|
||||
var prim:Polygon = cast mesh.primitive;
|
||||
var prim:DynamicPolygon = cast mesh.primitive;
|
||||
var vbuffer:FloatBuffer = null;
|
||||
if (prim.buffer != null) {
|
||||
vbuffer = prim.getBuffer(prim.points.length);
|
||||
}
|
||||
var pos = 0;
|
||||
for (i in info.indices) {
|
||||
if (pos >= prim.points.length) {
|
||||
meshIndex++;
|
||||
if (prim.buffer != null)
|
||||
prim.buffer.dispose();
|
||||
if (prim.buffer != null) {
|
||||
prim.addNormals();
|
||||
prim.flush();
|
||||
// prim.buffer.uploadBytes()
|
||||
// prim.buffer.dispose();
|
||||
}
|
||||
mesh.primitive = prim;
|
||||
mesh = cast info.geometry.children[meshIndex];
|
||||
prim = cast mesh.primitive;
|
||||
pos = 0;
|
||||
if (prim.buffer != null) {
|
||||
vbuffer = prim.getBuffer(prim.points.length);
|
||||
}
|
||||
}
|
||||
// if (prim.buffer == null) {
|
||||
var vertex = info.vertices[i];
|
||||
var normal = info.normals[i];
|
||||
prim.points[pos] = vertex.toPoint();
|
||||
prim.normals[pos] = normal.toPoint();
|
||||
if (prim.buffer != null) {
|
||||
prim.dirtyFlags[pos] = true;
|
||||
}
|
||||
// } else {
|
||||
// vbuffer[pos * 8] = info.vertices[i].x;
|
||||
// vbuffer[(pos * 8) + 1] = info.vertices[i].y;
|
||||
// vbuffer[(pos * 8) + 2] = info.vertices[i].z;
|
||||
// var fb = new FloatBuffer();
|
||||
// fb.push(info.vertices[i].x);
|
||||
// fb.push(info.vertices[i].y);
|
||||
// fb.push(info.vertices[i].z);
|
||||
// prim.buffer.uploadVector(fb, pos * 8, 1);
|
||||
// }
|
||||
// prim.normals[pos] = normal.toPoint();
|
||||
pos++;
|
||||
}
|
||||
if (prim.buffer != null)
|
||||
prim.buffer.dispose();
|
||||
if (prim.buffer != null) {
|
||||
prim.addNormals();
|
||||
prim.flush();
|
||||
// prim.buffer.dispose();
|
||||
}
|
||||
if (_regenNormals) {
|
||||
_regenNormals = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
391
src/DynamicPolygon.hx
Normal file
391
src/DynamicPolygon.hx
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
package src;
|
||||
|
||||
import hxd.FloatBuffer;
|
||||
import h3d.prim.UV;
|
||||
import h3d.prim.MeshPrimitive;
|
||||
import h3d.col.Point;
|
||||
|
||||
/*
|
||||
DynamicPolygon rough implementation, doesn't support tangents and colors unlike Polygon, most of the code was taken from Polygon.hx and DynamicPrimitive.hx.
|
||||
Usage:
|
||||
Set your points, normals and stuff like usual Polygon
|
||||
To update points/normals/uvs, just change the points/normals/uvs array and set dirtyFlags[i] to true for all index of changed points/normals/uvs where i is index of point and call flush();
|
||||
*/
|
||||
class DynamicPolygon extends MeshPrimitive {
|
||||
public var points:Array<Point>;
|
||||
public var normals:Array<Point>;
|
||||
public var uvs:Array<UV>;
|
||||
public var idx:hxd.IndexBuffer;
|
||||
|
||||
// A list of bools having the same length as points/normals/uv and each bool corresponds to point/normal/uv having the same index as the bool
|
||||
// Basically this is just used to tell apart vertices that changed so it will be flushed, it will be created after alloc has been called
|
||||
public var dirtyFlags:Array<Bool>;
|
||||
|
||||
var vbuf:FloatBuffer;
|
||||
|
||||
@:s var scaled = 1.;
|
||||
@:s var translatedX = 0.;
|
||||
@:s var translatedY = 0.;
|
||||
@:s var translatedZ = 0.;
|
||||
|
||||
public function new(points, ?idx) {
|
||||
this.points = points;
|
||||
this.idx = idx;
|
||||
}
|
||||
|
||||
override function getBounds() {
|
||||
var b = new h3d.col.Bounds();
|
||||
for (p in points)
|
||||
b.addPoint(p);
|
||||
return b;
|
||||
}
|
||||
|
||||
public function flush() {
|
||||
var alloc = hxd.impl.Allocator.get();
|
||||
var vsize = points.length;
|
||||
if (vsize == 0) {
|
||||
if (buffer != null) {
|
||||
alloc.disposeBuffer(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
if (indexes != null) {
|
||||
alloc.disposeIndexBuffer(indexes);
|
||||
indexes = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer != null && (buffer.isDisposed() || buffer.vertices < vsize)) {
|
||||
alloc.disposeBuffer(buffer);
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
buffer = alloc.allocBuffer(hxd.Math.imax(0, vsize), 8, Dynamic);
|
||||
|
||||
var off = 0;
|
||||
for (k in 0...points.length) {
|
||||
if (dirtyFlags[k]) {
|
||||
var p = points[k];
|
||||
vbuf[off++] = p.x;
|
||||
vbuf[off++] = p.y;
|
||||
vbuf[off++] = p.z;
|
||||
if (normals != null) {
|
||||
var n = normals[k];
|
||||
vbuf[off++] = n.x;
|
||||
vbuf[off++] = n.y;
|
||||
vbuf[off++] = n.z;
|
||||
}
|
||||
if (uvs != null) {
|
||||
var uv = uvs[k];
|
||||
vbuf[off++] = uv.u;
|
||||
vbuf[off++] = uv.v;
|
||||
}
|
||||
dirtyFlags[k] = false;
|
||||
} else {
|
||||
off += 3;
|
||||
if (normals != null)
|
||||
off += 3;
|
||||
if (uvs != null)
|
||||
off += 2;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.uploadVector(vbuf, 0, vsize);
|
||||
if (idx != null)
|
||||
indexes = h3d.Indexes.alloc(idx);
|
||||
}
|
||||
|
||||
override function alloc(engine:h3d.Engine) {
|
||||
dispose();
|
||||
|
||||
var allocator = hxd.impl.Allocator.get();
|
||||
|
||||
dirtyFlags = [];
|
||||
|
||||
var size = 3;
|
||||
var names = ["position"];
|
||||
var positions = [0];
|
||||
if (normals != null) {
|
||||
names.push("normal");
|
||||
positions.push(size);
|
||||
size += 3;
|
||||
}
|
||||
if (uvs != null) {
|
||||
names.push("uv");
|
||||
positions.push(size);
|
||||
size += 2;
|
||||
}
|
||||
|
||||
vbuf = new hxd.FloatBuffer();
|
||||
for (k in 0...points.length) {
|
||||
var p = points[k];
|
||||
vbuf.push(p.x);
|
||||
vbuf.push(p.y);
|
||||
vbuf.push(p.z);
|
||||
if (normals != null) {
|
||||
var n = normals[k];
|
||||
vbuf.push(n.x);
|
||||
vbuf.push(n.y);
|
||||
vbuf.push(n.z);
|
||||
}
|
||||
if (uvs != null) {
|
||||
var t = uvs[k];
|
||||
vbuf.push(t.u);
|
||||
vbuf.push(t.v);
|
||||
}
|
||||
dirtyFlags.push(false);
|
||||
}
|
||||
var flags:Array<h3d.Buffer.BufferFlag> = [];
|
||||
if (idx == null)
|
||||
flags.push(Triangles);
|
||||
if (normals == null)
|
||||
flags.push(RawFormat);
|
||||
flags.push(Dynamic);
|
||||
buffer = allocator.allocBuffer(hxd.Math.imax(0, vertexCount()), 8, Dynamic); // h3d.Buffer.ofFloats(buf, size, flags);
|
||||
buffer.uploadVector(vbuf, 0, points.length);
|
||||
|
||||
for (i in 0...names.length)
|
||||
addBuffer(names[i], buffer, positions[i]);
|
||||
|
||||
if (idx != null)
|
||||
indexes = h3d.Indexes.alloc(idx);
|
||||
}
|
||||
|
||||
public function getBuffer(vertices:Int) {
|
||||
if (vbuf == null)
|
||||
vbuf = hxd.impl.Allocator.get().allocFloats(vertices * 8)
|
||||
else
|
||||
vbuf.grow(vertices * 8);
|
||||
return vbuf;
|
||||
}
|
||||
|
||||
public function unindex() {
|
||||
if (idx != null && points.length != idx.length) {
|
||||
var p = [];
|
||||
var used = [];
|
||||
for (i in 0...idx.length)
|
||||
p.push(points[idx[i]].clone());
|
||||
if (normals != null) {
|
||||
var n = [];
|
||||
for (i in 0...idx.length)
|
||||
n.push(normals[idx[i]].clone());
|
||||
normals = n;
|
||||
}
|
||||
if (uvs != null) {
|
||||
var t = [];
|
||||
for (i in 0...idx.length)
|
||||
t.push(uvs[idx[i]].clone());
|
||||
uvs = t;
|
||||
}
|
||||
points = p;
|
||||
idx = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function translate(dx, dy, dz) {
|
||||
translatedX += dx;
|
||||
translatedY += dy;
|
||||
translatedZ += dz;
|
||||
for (p in points) {
|
||||
p.x += dx;
|
||||
p.y += dy;
|
||||
p.z += dz;
|
||||
}
|
||||
}
|
||||
|
||||
public function scale(s:Float) {
|
||||
scaled *= s;
|
||||
for (p in points) {
|
||||
p.x *= s;
|
||||
p.y *= s;
|
||||
p.z *= s;
|
||||
}
|
||||
}
|
||||
|
||||
public function addNormals() {
|
||||
// make per-point normal
|
||||
normals = new Array();
|
||||
for (i in 0...points.length)
|
||||
normals[i] = new Point();
|
||||
var pos = 0;
|
||||
for (i in 0...triCount()) {
|
||||
var i0, i1, i2;
|
||||
if (idx == null) {
|
||||
i0 = pos++;
|
||||
i1 = pos++;
|
||||
i2 = pos++;
|
||||
} else {
|
||||
i0 = idx[pos++];
|
||||
i1 = idx[pos++];
|
||||
i2 = idx[pos++];
|
||||
}
|
||||
var p0 = points[i0];
|
||||
var p1 = points[i1];
|
||||
var p2 = points[i2];
|
||||
// this is the per-face normal
|
||||
var n = p1.sub(p0).cross(p2.sub(p0));
|
||||
// add it to each point
|
||||
normals[i0].x += n.x;
|
||||
normals[i0].y += n.y;
|
||||
normals[i0].z += n.z;
|
||||
normals[i1].x += n.x;
|
||||
normals[i1].y += n.y;
|
||||
normals[i1].z += n.z;
|
||||
normals[i2].x += n.x;
|
||||
normals[i2].y += n.y;
|
||||
normals[i2].z += n.z;
|
||||
}
|
||||
// normalize all normals
|
||||
for (n in normals)
|
||||
n.normalize();
|
||||
}
|
||||
|
||||
public function addUVs() {
|
||||
uvs = [];
|
||||
for (i in 0...points.length)
|
||||
uvs[i] = new UV(points[i].x, points[i].y);
|
||||
}
|
||||
|
||||
public function uvScale(su:Float, sv:Float) {
|
||||
if (uvs == null)
|
||||
throw "Missing UVs";
|
||||
var m = new Map<UV, Bool>();
|
||||
for (t in uvs) {
|
||||
if (m.exists(t))
|
||||
continue;
|
||||
m.set(t, true);
|
||||
t.u *= su;
|
||||
t.v *= sv;
|
||||
}
|
||||
}
|
||||
|
||||
override function triCount() {
|
||||
var n = super.triCount();
|
||||
if (n != 0)
|
||||
return n;
|
||||
return Std.int((idx == null ? points.length : idx.length) / 3);
|
||||
}
|
||||
|
||||
override function vertexCount() {
|
||||
return points.length;
|
||||
}
|
||||
|
||||
override function getCollider():h3d.col.Collider {
|
||||
var vertexes = new haxe.ds.Vector<hxd.impl.Float32>(points.length * 3);
|
||||
var indexes = new haxe.ds.Vector<Int>(idx.length);
|
||||
var vid = 0;
|
||||
for (p in points) {
|
||||
vertexes[vid++] = p.x;
|
||||
vertexes[vid++] = p.y;
|
||||
vertexes[vid++] = p.z;
|
||||
}
|
||||
for (i in 0...idx.length)
|
||||
indexes[i] = idx[i];
|
||||
var poly = new h3d.col.Polygon();
|
||||
poly.addBuffers(vertexes, indexes);
|
||||
return poly;
|
||||
}
|
||||
|
||||
override function render(engine:h3d.Engine) {
|
||||
if (buffer == null || buffer.isDisposed())
|
||||
alloc(engine);
|
||||
var bufs = getBuffers(engine);
|
||||
if (indexes != null)
|
||||
engine.renderMultiBuffers(bufs, indexes);
|
||||
else if (buffer.flags.has(Quads))
|
||||
engine.renderMultiBuffers(bufs, engine.mem.quadIndexes, 0, triCount());
|
||||
else
|
||||
engine.renderMultiBuffers(bufs, engine.mem.triIndexes, 0, triCount());
|
||||
}
|
||||
|
||||
#if hxbit
|
||||
override function customSerialize(ctx:hxbit.Serializer) {
|
||||
ctx.addInt(points.length);
|
||||
for (p in points) {
|
||||
ctx.addDouble(p.x);
|
||||
ctx.addDouble(p.y);
|
||||
ctx.addDouble(p.z);
|
||||
}
|
||||
if (normals == null)
|
||||
ctx.addInt(0);
|
||||
else {
|
||||
ctx.addInt(normals.length);
|
||||
for (p in normals) {
|
||||
ctx.addDouble(p.x);
|
||||
ctx.addDouble(p.y);
|
||||
ctx.addDouble(p.z);
|
||||
}
|
||||
}
|
||||
if (tangents == null)
|
||||
ctx.addInt(0);
|
||||
else {
|
||||
ctx.addInt(tangents.length);
|
||||
for (p in tangents) {
|
||||
ctx.addDouble(p.x);
|
||||
ctx.addDouble(p.y);
|
||||
ctx.addDouble(p.z);
|
||||
}
|
||||
}
|
||||
if (uvs == null)
|
||||
ctx.addInt(0);
|
||||
else {
|
||||
ctx.addInt(uvs.length);
|
||||
for (uv in uvs) {
|
||||
ctx.addDouble(uv.u);
|
||||
ctx.addDouble(uv.v);
|
||||
}
|
||||
}
|
||||
if (idx == null)
|
||||
ctx.addInt(0);
|
||||
else {
|
||||
ctx.addInt(idx.length);
|
||||
for (i in idx)
|
||||
ctx.addInt(i);
|
||||
}
|
||||
if (colors == null)
|
||||
ctx.addInt(0);
|
||||
else {
|
||||
ctx.addInt(colors.length);
|
||||
for (c in colors) {
|
||||
ctx.addDouble(c.x);
|
||||
ctx.addDouble(c.y);
|
||||
ctx.addDouble(c.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override function customUnserialize(ctx:hxbit.Serializer) {
|
||||
points = [
|
||||
for (i in 0...ctx.getInt())
|
||||
new h3d.col.Point(ctx.getDouble(), ctx.getDouble(), ctx.getDouble())
|
||||
];
|
||||
normals = [
|
||||
for (i in 0...ctx.getInt())
|
||||
new h3d.col.Point(ctx.getDouble(), ctx.getDouble(), ctx.getDouble())
|
||||
];
|
||||
tangents = [
|
||||
for (i in 0...ctx.getInt())
|
||||
new h3d.col.Point(ctx.getDouble(), ctx.getDouble(), ctx.getDouble())
|
||||
];
|
||||
uvs = [for (i in 0...ctx.getInt()) new UV(ctx.getDouble(), ctx.getDouble())];
|
||||
if (normals.length == 0)
|
||||
normals = null;
|
||||
if (uvs.length == 0)
|
||||
uvs = null;
|
||||
var nindex = ctx.getInt();
|
||||
if (nindex > 0) {
|
||||
idx = new hxd.IndexBuffer();
|
||||
idx.grow(nindex);
|
||||
for (i in 0...nindex)
|
||||
idx[i] = ctx.getInt();
|
||||
}
|
||||
colors = [
|
||||
for (i in 0...ctx.getInt())
|
||||
new h3d.col.Point(ctx.getDouble(), ctx.getDouble(), ctx.getDouble())
|
||||
];
|
||||
if (colors.length == 0)
|
||||
colors = null;
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ class Main extends hxd.App {
|
|||
var loader = new Loader(fileSystem);
|
||||
|
||||
dtsObj = new DtsObject();
|
||||
dtsObj.dtsPath = "data/shapes/hazards/trapdoor.dts";
|
||||
dtsObj.dtsPath = "data/shapes/hazards/tornado.dts";
|
||||
dtsObj.isCollideable = false;
|
||||
dtsObj.isTSStatic = false;
|
||||
dtsObj.fs = loader;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue