diff --git a/src/DtsObject.hx b/src/DtsObject.hx new file mode 100644 index 00000000..97e14e48 --- /dev/null +++ b/src/DtsObject.hx @@ -0,0 +1,9 @@ +import h3d.Matrix; +import h3d.scene.CustomObject; + +class DtsObject extends CustomObject { + public function getMountTransform(mountPoint:Int) { + // TODO FIX WHEN DTS SUPPORT + return Matrix.I(); + } +} diff --git a/src/ForceObject.hx b/src/ForceObject.hx new file mode 100644 index 00000000..86ca6637 --- /dev/null +++ b/src/ForceObject.hx @@ -0,0 +1,76 @@ +package src; + +import h3d.Vector; +import h3d.scene.CustomObject; + +enum ForceType { + NoForce; + ForceSpherical; + ForceField; + ForceCone; +} + +class ForceData { + public var forceType:ForceType; + public var forceNode:Int; + public var forceVector:Vector; + public var forceRadius:Float; + public var forceStrength:Float; + public var forceArc:Float; + + public function new() {} +} + +class ForceObject extends DtsObject { + var forceDatas:Array; + + public function getForce(pos:Vector) { + var strength = 0.0; + var dot = 0.0; + var posVec = new Vector(); + var retForce = new Vector(); + for (forceData in forceDatas) { + if (forceData.forceType == NoForce) { + continue; + } + + var node = this.getMountTransform(forceData.forceNode); + var nodeVec:Vector; + if (forceData.forceVector.length() == 0) { + nodeVec = new Vector(node._12, node._22, node._32); + } else { + nodeVec = forceData.forceVector; + } + + posVec = pos.sub(node.getPosition()); + dot = posVec.length(); + + if (forceData.forceRadius < dot) { + continue; + } + + var forceType = forceData.forceType; + strength = (1 - dot / forceData.forceRadius) * forceData.forceStrength; + + if (forceType == ForceSpherical) { + dot = strength / dot; + retForce = retForce.add(posVec.multiply(dot)); + } + + if (forceType == ForceField) { + retForce = retForce.add(nodeVec.multiply(strength)); + } + + if (forceType == ForceCone) { + posVec = posVec.multiply(1 / dot); + var newDot = nodeVec.dot(posVec); + var arc = forceData.forceArc; + if (arc < newDot) { + retForce = retForce.add(posVec.multiply(strength).multiply(newDot - arc).multiply(1 / (1 - arc))); + } + } + } + + return retForce; + } +} diff --git a/src/dts/Detail.hx b/src/dts/Detail.hx new file mode 100644 index 00000000..79e8d4da --- /dev/null +++ b/src/dts/Detail.hx @@ -0,0 +1,25 @@ +package dts; + +class Detail { + var name:Int; + var subShape:Int; + var objectDetail:Int; + var size:Float; + var avgError:Float; + var maxError:Float; + var polyCount:Int; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var d = new Detail(); + d.name = reader.readU32(); + d.subShape = reader.readU32(); + d.objectDetail = reader.readU32(); + d.size = reader.readF32(); + d.avgError = reader.readF32(); + d.maxError = reader.readF32(); + d.polyCount = reader.readU32(); + return d; + } +} diff --git a/src/dts/DtsAlloc.hx b/src/dts/DtsAlloc.hx new file mode 100644 index 00000000..ebbb49e7 --- /dev/null +++ b/src/dts/DtsAlloc.hx @@ -0,0 +1,124 @@ +package dts; + +import haxe.Exception; +import h3d.Matrix; +import dif.math.QuatF; +import dif.math.Box3F; +import dif.math.Point3F; +import dif.math.Point2F; +import dif.io.BytesReader; +import haxe.io.Bytes; + +class DtsAlloc { + public var buf:BytesReader; + + public var index32:Int; + + public var index16:Int; + + public var index8:Int; + + public var lastGuardValue:Int = 0; + + public function new(buf:BytesReader, start32:Int, start16:Int, start8:Int) { + this.buf = buf; + this.index32 = start32; + this.index16 = start32 + start16 * 4; + this.index8 = start32 + start8 * 4; + } + + public function readU32() { + buf.seek(this.index32); + var val = buf.readInt32(); + this.index32 += 4; + return val; + } + + public function readS32() { + buf.seek(this.index32); + var val = buf.readInt32(); + this.index32 += 4; + return val; + } + + public function readF32() { + buf.seek(this.index32); + var val = buf.readFloat(); + this.index32 += 4; + return val; + } + + public function readPoint2F():Point2F { + return new Point2F(this.readF32(), this.readF32()); + } + + public function readPoint3F():Point3F { + return new Point3F(this.readF32(), this.readF32(), this.readF32()); + } + + public function readBoxF():Box3F { + return new Box3F(this.readF32(), this.readF32(), this.readF32(), this.readF32(), this.readF32(), this.readF32()); + } + + public function readU16() { + buf.seek(this.index16); + var val = this.buf.readInt16(); + this.index16 += 2; + return val; + } + + public function readS16() { + buf.seek(this.index16); + var val = this.buf.readInt16(); + this.index16 += 2; + return val; + } + + public function readU8() { + buf.seek(this.index8); + var val = this.buf.readByte(); + this.index8 += 1; + return val; + } + + public function readQuat16() { + var quat = new QuatF(); + quat.x = this.readS16(); + quat.y = this.readS16(); + quat.z = this.readS16(); + quat.w = this.readS16(); + return quat; + } + + public function readMatrixF() { + var mat = new Matrix(); + mat._11 = this.readF32(); + mat._12 = this.readF32(); + mat._13 = this.readF32(); + mat._14 = this.readF32(); + mat._21 = this.readF32(); + mat._22 = this.readF32(); + mat._23 = this.readF32(); + mat._24 = this.readF32(); + mat._31 = this.readF32(); + mat._32 = this.readF32(); + mat._33 = this.readF32(); + mat._34 = this.readF32(); + mat._41 = this.readF32(); + mat._42 = this.readF32(); + mat._43 = this.readF32(); + mat._44 = this.readF32(); + return mat; + } + + public function guard() { + var guard32 = this.readU32(); + var guard16 = this.readU16(); + var guard8 = this.readU8(); + if (!(guard32 == guard16 && guard16 == guard8 && guard8 == this.lastGuardValue)) { + throw new Exception("Guard fail! Expected " + this.lastGuardValue + " but got " + guard32 + " for 32, " + guard16 + " for 16 and " + guard8 + + " for 8."); + } + this.lastGuardValue++; + } +} diff --git a/src/dts/DtsFile.hx b/src/dts/DtsFile.hx new file mode 100644 index 00000000..b5e431df --- /dev/null +++ b/src/dts/DtsFile.hx @@ -0,0 +1,354 @@ +package dts; + +import haxe.Exception; +import sys.io.File; +import dif.io.BytesReader; +import dif.math.QuatF; +import dif.math.Box3F; +import dif.math.Point3F; + +@:publicFields +class DtsFile { + var fileVersion:Int; + var exporterVersion:Int; + var sequences:Array; + var matNames:Array; + var matFlags:Array; + var matReflectanceMaps:Array; + var matBumpMaps:Array; + var matDetailMaps:Array; + var matDetailScales:Array; + var matReflectionAmounts:Array; + var smallestVisibleSize:Float; + var smallestVisibleDL:Float; + + var radius:Float; + var radiusTube:Float; + var center:Point3F; + var bounds:Box3F; + + var nodes:Array; + var objects:Array; + var mats:Array; + var subshapes:Array; + + var defaultRotations:Array; + var defaultTranslations:Array; + + var nodeTranslations:Array; + var nodeRotations:Array; + + var nodeUniformScales:Array; + var nodeAlignedScales:Array; + var nodeArbitraryScaleFactors:Array; + var nodeArbitraryScaleRots:Array; + + var groundTranslations:Array; + var groundRots:Array; + + var objectStates:Array; + var decalStates:Array; + var triggers:Array; + + var detailLevels:Array; + var meshes:Array; + + var names:Array; + + var alphaIn:Array; + var alphaOut:Array; + + public function new() {} + + public function read(filepath:String) { + var f = File.read(filepath); + var bytes = f.readAll(); + var br = new BytesReader(bytes); + + fileVersion = br.readInt16(); + exporterVersion = br.readInt16(); + fileVersion &= 0xFF; + + var memBuffer:BytesReader; + var start32:Int; + var start16:Int; + var start8:Int; + + if (fileVersion > 24) { + throw new Exception("Invalid DTS version"); + } + + if (fileVersion < 19) { + throw new Exception("Cant read this!"); + } else { + var sizeMemBuffer = br.readInt32(); + memBuffer = br; + start16 = br.readInt32(); + start8 = br.readInt32(); + start32 = br.tell(); + + br.seek(br.tell() + sizeMemBuffer * 4); + + var numSequences = br.readInt32(); + sequences = []; + for (i in 0...numSequences) { + var seq = new Sequence(); + seq.read(br, fileVersion, true); + sequences.push(seq); + } + + parseMaterialList(br, fileVersion); + } + + var alloc = new DtsAlloc(memBuffer, start32, start16, start8); + this.assembleShape(alloc); + } + + function assembleShape(ar:DtsAlloc) { + var numNodes = ar.readS32(); + var numObjects = ar.readS32(); + var numDecals = ar.readS32(); + var numSubShapes = ar.readS32(); + var numIflMaterials = ar.readS32(); + + var numNodeRots:Int; + var numNodeTrans:Int; + var numNodeUniformScales:Int; + var numNodeAlignedScales:Int; + var numNodeArbitraryScales:Int; + if (this.fileVersion < 22) { + numNodeRots = numNodeTrans = ar.readS32() - numNodes; + numNodeUniformScales = numNodeAlignedScales = numNodeArbitraryScales = 0; + } else { + numNodeRots = ar.readS32(); + numNodeTrans = ar.readS32(); + numNodeUniformScales = ar.readS32(); + numNodeAlignedScales = ar.readS32(); + numNodeArbitraryScales = ar.readS32(); + } + var numGroundFrames = 0; + if (this.fileVersion > 23) { + numGroundFrames = ar.readS32(); + } + var numObjectStates = ar.readS32(); + var numDecalStates = ar.readS32(); + var numTriggers = ar.readS32(); + var numDetails = ar.readS32(); + var numMeshes = ar.readS32(); + var numSkins = 0; + if (this.fileVersion < 23) { + numSkins = ar.readS32(); + } + var numNames = ar.readS32(); + this.smallestVisibleSize = ar.readF32(); + this.smallestVisibleDL = ar.readS32(); + + ar.guard(); + + radius = ar.readF32(); + radiusTube = ar.readF32(); + center = ar.readPoint3F(); + bounds = ar.readBoxF(); + + ar.guard(); + + nodes = []; + for (i in 0...numNodes) { + nodes.push(Node.read(ar)); + } + ar.guard(); + + objects = []; + for (i in 0...numObjects) { + objects.push(Object.read(ar)); + } + ar.guard(); + ar.guard(); + + mats = []; + for (i in 0...numIflMaterials) { + mats.push(IflMaterial.read(ar)); + } + ar.guard(); + + subshapes = []; + for (i in 0...numSubShapes) { + subshapes.push(new SubShape(0, 0, 0, 0, 0, 0)); + } + + for (i in 0...numSubShapes) + subshapes[i].firstNode = ar.readS32(); + for (i in 0...numSubShapes) + subshapes[i].firstObject = ar.readS32(); + for (i in 0...numSubShapes) + subshapes[i].firstDecal = ar.readS32(); + + ar.guard(); + + for (i in 0...numSubShapes) + subshapes[i].numNodes = ar.readS32(); + for (i in 0...numSubShapes) + subshapes[i].numObjects = ar.readS32(); + for (i in 0...numSubShapes) + subshapes[i].numDecals = ar.readS32(); + ar.guard(); + + if (fileVersion < 16) { + var num = ar.readS32(); + for (i in 0...num) + ar.readS32(); + } + + defaultRotations = []; + defaultTranslations = []; + for (i in 0...numNodes) { + defaultRotations.push(ar.readQuat16()); + defaultTranslations.push(ar.readPoint3F()); + } + + nodeTranslations = []; + for (i in 0...numNodeTrans) + nodeTranslations.push(ar.readPoint3F()); + + nodeRotations = []; + for (i in 0...numNodeRots) + nodeRotations.push(ar.readQuat16()); + + ar.guard(); + + nodeUniformScales = []; + nodeAlignedScales = []; + nodeArbitraryScaleFactors = []; + nodeArbitraryScaleRots = []; + + if (fileVersion > 21) { + for (i in 0...numNodeUniformScales) + nodeUniformScales.push(ar.readF32()); + for (i in 0...numNodeAlignedScales) + nodeAlignedScales.push(ar.readPoint3F()); + for (i in 0...numNodeArbitraryScales) + nodeArbitraryScaleFactors.push(ar.readPoint3F()); + for (i in 0...numNodeArbitraryScales) + nodeArbitraryScaleRots.push(ar.readQuat16()); + ar.guard(); + } else { + for (i in 0...numNodeUniformScales) + nodeUniformScales.push(1); + for (i in 0...numNodeAlignedScales) + nodeAlignedScales.push(new Point3F(1, 1, 1)); + for (i in 0...numNodeArbitraryScales) + nodeArbitraryScaleFactors.push(new Point3F(1, 1, 1)); + for (i in 0...numNodeArbitraryScales) + nodeArbitraryScaleRots.push(new QuatF()); + } + + groundTranslations = []; + groundRots = []; + if (fileVersion > 23) { + for (i in 0...numGroundFrames) { + groundTranslations.push(ar.readPoint3F()); + } + for (i in 0...numGroundFrames) { + groundRots.push(ar.readQuat16()); + } + ar.guard(); + } else { + for (i in 0...numGroundFrames) { + groundTranslations.push(new Point3F(1, 1, 1)); + } + for (i in 0...numGroundFrames) { + groundRots.push(new QuatF()); + } + } + + objectStates = []; + for (i in 0...numObjectStates) { + objectStates.push(ObjectState.read(ar)); + } + ar.guard(); + + decalStates = []; + for (i in 0...numDecalStates) { + decalStates.push(ar.readS32()); + } + ar.guard(); + + triggers = []; + for (i in 0...numTriggers) { + triggers.push(Trigger.read(ar)); + } + ar.guard(); + + detailLevels = []; + for (i in 0...numDetails) { + detailLevels.push(Detail.read(ar)); + } + ar.guard(); + + meshes = []; + for (i in 0...numMeshes) { + meshes.push(Mesh.read(this, ar)); + } + ar.guard(); + + names = []; + for (i in 0...numNames) { + var str = ""; + + while (true) { + var charCode = ar.readU8(); + if (charCode == 0) + break; + + str += String.fromCharCode(charCode); + } + + names.push(str); + } + ar.guard(); + + alphaIn = []; + alphaOut = []; + + if (fileVersion >= 26) { + for (i in 0...numDetails) { + alphaIn.push(ar.readS32()); + } + for (i in 0...numDetails) { + alphaOut.push(ar.readS32()); + } + } + } + + function parseMaterialList(br:BytesReader, version:Int) { + var matStreamType = br.readInt32(); + var numMaterials = br.readInt32(); + matNames = []; + for (i in 0...numMaterials) { + matNames.push(br.readStr()); + } + for (i in 0...numMaterials) { + matFlags.push(br.readInt32()); + } + for (i in 0...numMaterials) { + matReflectanceMaps.push(br.readInt32()); + } + for (i in 0...numMaterials) { + matBumpMaps.push(br.readInt32()); + } + for (i in 0...numMaterials) { + matDetailMaps.push(br.readInt32()); + } + if (version == 25) { + for (i in 0...numMaterials) { + br.readInt32(); + } + } + for (i in 0...numMaterials) { + matDetailScales.push(br.readFloat()); + } + for (i in 0...numMaterials) { + matReflectionAmounts.push(br.readFloat()); + } + } +} diff --git a/src/dts/IflMaterial.hx b/src/dts/IflMaterial.hx new file mode 100644 index 00000000..61515a9e --- /dev/null +++ b/src/dts/IflMaterial.hx @@ -0,0 +1,23 @@ +package dts; + +import dif.io.BytesReader; + +class IflMaterial { + var name:Int; + var slot:Int; + var firstFrame:Int; + var time:Int; + var numFrames:Int; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var ifl = new IflMaterial(); + ifl.name = reader.readU32(); + ifl.slot = reader.readU32(); + ifl.firstFrame = reader.readU32(); + ifl.time = reader.readU32(); + ifl.numFrames = reader.readU32(); + return ifl; + } +} diff --git a/src/dts/Mesh.hx b/src/dts/Mesh.hx new file mode 100644 index 00000000..b881ae14 --- /dev/null +++ b/src/dts/Mesh.hx @@ -0,0 +1,156 @@ +package dts; + +import haxe.Exception; +import dif.math.Point2F; +import dif.math.Point3F; +import dif.math.Box3F; + +class Mesh { + var meshType:Int; + var numFrames:Int; + var numMatFrames:Int; + var parent:Int; + var bounds:Box3F; + var center:Point3F; + var radius:Float; + var vertices:Array; + var uv:Array; + var normals:Array; + var enormals:Array; + var primitives:Array; + var indices:Array; + var mindices:Array; + var vertsPerFrame:Int; + var type:Int; + var shape:DtsFile; + + public function new() {} + + function readStandard(reader:DtsAlloc) { + reader.guard(); + + numFrames = reader.readU32(); + numMatFrames = reader.readU32(); + parent = reader.readS32(); + bounds = reader.readBoxF(); + center = reader.readPoint3F(); + radius = reader.readF32(); + + var numVerts = reader.readU32(); + vertices = []; + if (this.parent < 0) { + for (i in 0...numVerts) { + vertices.push(reader.readPoint3F()); + } + } else { + vertices = shape.meshes[this.parent].vertices; + } + + var tVerts = reader.readU32(); + uv = []; + if (this.parent < 0) { + for (i in 0...tVerts) { + uv.push(reader.readPoint2F()); + } + } else { + uv = shape.meshes[this.parent].uv; + } + + var numNormals = reader.readU32(); + normals = []; + if (this.parent < 0) { + for (i in 0...numNormals) { + normals.push(reader.readPoint3F()); + } + } else { + normals = shape.meshes[this.parent].normals; + } + + enormals = []; + if (this.parent < 0) { + for (i in 0...numVerts) { + enormals.push(reader.readU8()); + } + } + + primitives = []; + var numPrimitives = reader.readU32(); + for (i in 0...numPrimitives) { + primitives.push(Primitive.read(reader)); + } + + indices = []; + var numIndices = reader.readU32(); + for (i in 0...numIndices) { + indices.push(reader.readS16()); + } + + mindices = []; + var numMIndices = reader.readU32(); + for (i in 0...numMIndices) { + mindices.push(reader.readS16()); + } + + vertsPerFrame = reader.readS32(); + type = reader.readS32(); + + reader.guard(); + } + + function readSkinned(reader:DtsAlloc) { + readStandard(reader); + + var sz = reader.readS32(); + for (i in 0...sz) { + reader.readPoint3F(); + } + for (i in 0...sz) { + reader.readPoint3F(); + } + for (i in 0...sz) { + reader.readU8(); + } + + sz = reader.readS32(); + for (i in 0...sz) { + for (j in 0...16) { + reader.readF32(); + } + } + + sz = reader.readS32(); + for (i in 0...sz) { + reader.readS32(); + } + for (i in 0...sz) { + reader.readS32(); + } + for (i in 0...sz) { + reader.readF32(); + } + + sz = reader.readS32(); + for (i in 0...sz) { + reader.readS32(); + } + + reader.guard(); + } + + public static function read(shape:DtsFile, reader:DtsAlloc) { + var mesh = new Mesh(); + mesh.shape = shape; + mesh.meshType = reader.readS32() & 7; + + if (mesh.meshType == 0) + mesh.readStandard(reader); + else if (mesh.meshType == 1) + mesh.readSkinned(reader); + else if (mesh.meshType == 4) + return null; + else + throw new Exception("idk how to read this"); + + return mesh; + } +} diff --git a/src/dts/Node.hx b/src/dts/Node.hx new file mode 100644 index 00000000..9acd716b --- /dev/null +++ b/src/dts/Node.hx @@ -0,0 +1,23 @@ +package dts; + +import dif.io.BytesReader; + +class Node { + var name:Int; + var parent:Int; + var firstObject:Int = -1; + var firstChild:Int = -1; + var nextSibling:Int = -1; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var node = new Node(); + node.name = reader.readU32(); + node.parent = reader.readU32(); + node.firstObject = reader.readU32(); + node.firstChild = reader.readU32(); + node.nextSibling = reader.readU32(); + return node; + } +} diff --git a/src/dts/Object.hx b/src/dts/Object.hx new file mode 100644 index 00000000..b8272d38 --- /dev/null +++ b/src/dts/Object.hx @@ -0,0 +1,25 @@ +package dts; + +import dif.io.BytesReader; + +class Object { + var name:Int; + var numMeshes:Int; + var firstMesh:Int; + var node:Int; + var firstDecal:Int; + var nextSibling:Int; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var obj = new Object(); + obj.name = reader.readU32(); + obj.numMeshes = reader.readU32(); + obj.firstMesh = reader.readU32(); + obj.node = reader.readU32(); + obj.nextSibling = reader.readU32(); + obj.firstDecal = reader.readU32(); + return obj; + } +} diff --git a/src/dts/ObjectState.hx b/src/dts/ObjectState.hx new file mode 100644 index 00000000..1900bdcb --- /dev/null +++ b/src/dts/ObjectState.hx @@ -0,0 +1,19 @@ +package dts; + +import dif.io.BytesReader; + +class ObjectState { + var vis:Float; + var frame:Int; + var matFrame:Int; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var os = new ObjectState(); + os.vis = reader.readF32(); + os.frame = reader.readU32(); + os.matFrame = reader.readU32(); + return os; + } +} diff --git a/src/dts/Primitive.hx b/src/dts/Primitive.hx new file mode 100644 index 00000000..426b4b9e --- /dev/null +++ b/src/dts/Primitive.hx @@ -0,0 +1,19 @@ +package dts; + +import dif.io.BytesReader; + +class Primitive { + var firstElement:Int; + var numElements:Int; + var type:Int; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var p = new Primitive(); + p.firstElement = reader.readU16(); + p.numElements = reader.readU16(); + p.type = reader.readU32(); + return p; + } +} diff --git a/src/dts/Sequence.hx b/src/dts/Sequence.hx new file mode 100644 index 00000000..e8e00256 --- /dev/null +++ b/src/dts/Sequence.hx @@ -0,0 +1,106 @@ +package dts; + +import dif.io.BytesReader; +import hl.I64; + +class Sequence { + var nameIndex:Int; + var numKeyFrames:Int; + var duration:Float; + var baseRotation:Int; + var baseTranslation:Int; + var baseScale:Int; + var baseObjectState:Int; + var baseDecalState:Int; + var firstGroundFrame:Int; + var numGroundFrames:Int; + var firstTrigger:Int; + var numTriggers:Int; + var toolBegin:Float; + + var rotationMatters:Array; + var translationMatters:Array; + var scaleMatters:Array; + var visMatters:Array; + var frameMatters:Array; + var matFrameMatters:Array; + var decalMatters:Array; + var iflMatters:Array; + + var priority:Int; + var flags:Int; + var dirtyFlags:Int; + + public function new() {} + + public function read(reader:BytesReader, fileVersion:Int, readNameIndex:Bool) { + if (readNameIndex) { + this.nameIndex = reader.readInt32(); + } + this.flags = 0; + + if (fileVersion > 21) { + this.flags = reader.readInt32(); + } + this.numKeyFrames = reader.readInt32(); + this.duration = reader.readFloat(); + + if (fileVersion < 22) { + var tmp = reader.readByte(); + if (tmp > 0) { + flags |= ShapeFlags.Blend; + } + tmp = reader.readByte(); + if (tmp > 0) { + flags |= ShapeFlags.Cyclic; + } + tmp = reader.readByte(); + if (tmp > 0) { + flags |= ShapeFlags.MakePath; + } + } + + this.priority = reader.readInt32(); + this.firstGroundFrame = reader.readInt32(); + this.numGroundFrames = reader.readInt32(); + + if (fileVersion > 21) { + this.baseRotation = reader.readInt32(); + this.baseTranslation = reader.readInt32(); + this.baseScale = reader.readInt32(); + this.baseObjectState = reader.readInt32(); + this.baseDecalState = reader.readInt32(); + } else { + this.baseRotation = reader.readInt32(); + this.baseTranslation = this.baseRotation; + this.baseObjectState = reader.readInt32(); + this.baseDecalState = reader.readInt32(); + } + + this.firstTrigger = reader.readInt32(); + this.numTriggers = reader.readInt32(); + this.toolBegin = reader.readInt32(); + + rotationMatters = readBitSet(reader); + translationMatters = readBitSet(reader); + scaleMatters = readBitSet(reader); + decalMatters = readBitSet(reader); + iflMatters = readBitSet(reader); + visMatters = readBitSet(reader); + frameMatters = readBitSet(reader); + matFrameMatters = readBitSet(reader); + + this.dirtyFlags = 0; + return true; + } + + function readBitSet(reader:BytesReader) { + var dummy = reader.readInt32(); + var numWords = reader.readInt32(); + var ret = []; + for (i in 0...numWords) { + ret.push(reader.readInt32()); + } + return ret; + } +} diff --git a/src/dts/ShapeFlags.hx b/src/dts/ShapeFlags.hx new file mode 100644 index 00000000..d5e208b5 --- /dev/null +++ b/src/dts/ShapeFlags.hx @@ -0,0 +1,13 @@ +package dts; + +class ShapeFlags { + public static var UniformScale = 0; + public static var AlignedScale = 1; + public static var ArbitraryScale = 2; + public static var Blend = 4; + public static var Cyclic = 8; + public static var MakePath = 16; + public static var IflInit = 32; + public static var HasTranslucency = 64; + public static var AnyScale = 3; +} diff --git a/src/dts/SubShape.hx b/src/dts/SubShape.hx new file mode 100644 index 00000000..9fc690ae --- /dev/null +++ b/src/dts/SubShape.hx @@ -0,0 +1,19 @@ +package dts; + +class SubShape { + public var firstNode:Int; + public var firstObject:Int; + public var firstDecal:Int; + public var numNodes:Int; + public var numObjects:Int; + public var numDecals:Int; + + public function new(firstNode:Int, firstObject:Int, firstDecal:Int, numNodes:Int, numObjects:Int, numDecals:Int) { + this.firstNode = firstNode; + this.firstObject = firstObject; + this.firstDecal = firstDecal; + this.numNodes = numNodes; + this.numObjects = numObjects; + this.numDecals = numDecals; + } +} diff --git a/src/dts/Trigger.hx b/src/dts/Trigger.hx new file mode 100644 index 00000000..538db106 --- /dev/null +++ b/src/dts/Trigger.hx @@ -0,0 +1,17 @@ +package dts; + +import dif.io.BytesReader; + +class Trigger { + var state:Int; + var position:Float; + + public function new() {} + + public static function read(reader:DtsAlloc) { + var t = new Trigger(); + t.state = reader.readU32(); + t.position = reader.readU32(); + return t; + } +}