Fix tornado

This commit is contained in:
RandomityGuy 2021-06-02 21:35:08 +05:30
parent 5f3163b85d
commit 04f2b4f480
3 changed files with 534 additions and 197 deletions

View file

@ -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
View 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
}

View file

@ -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;