diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 9425717f..2cfe43ad 100644 --- a/src/DtsObject.hx +++ b/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 = new Map(); var lastSequenceKeyframes:Map = new Map(); - var graphNodes:Array = []; - var rootGraphNodes:Array = []; - var nodeTransforms:Array = []; - - var dynamicGeometryLookup:Map = new Map(); + var graphNodes:Array = []; var isTSStatic:Bool; var isCollideable:Bool; var showSequences:Bool = true; var hasNonVisualSequences:Bool = true; - var geometries:Array = []; + 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 = null, translations:Array = 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; + } } } diff --git a/src/DynamicPolygon.hx b/src/DynamicPolygon.hx new file mode 100644 index 00000000..4099dfea --- /dev/null +++ b/src/DynamicPolygon.hx @@ -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; + public var normals:Array; + public var uvs:Array; + 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; + + 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 = []; + 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(); + 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(points.length * 3); + var indexes = new haxe.ds.Vector(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 +} diff --git a/src/Main.hx b/src/Main.hx index 109b9efa..1abcc83b 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -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;