mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
attempt dts
This commit is contained in:
parent
5e09678bc5
commit
5f3163b85d
13 changed files with 747 additions and 40 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
|||
interiors
|
||||
data
|
||||
*.hl
|
||||
*.js
|
||||
*.js.map
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import src.ResourceLoader;
|
||||
import src.PathedInterior;
|
||||
import h3d.Vector;
|
||||
import collision.CollisionSurface;
|
||||
|
|
@ -70,7 +71,7 @@ class DifBuilder {
|
|||
];
|
||||
|
||||
public static function loadDif(path:String, loader:Loader, itr:InteriorGeometry) {
|
||||
var dif = Dif.Load(path);
|
||||
var dif = ResourceLoader.loadInterior(path);
|
||||
|
||||
var geo = dif.interiors[0];
|
||||
|
||||
|
|
|
|||
590
src/DtsObject.hx
590
src/DtsObject.hx
|
|
@ -1,7 +1,591 @@
|
|||
import h3d.Matrix;
|
||||
import h3d.scene.CustomObject;
|
||||
package src;
|
||||
|
||||
import dts.Sequence;
|
||||
import h3d.scene.Mesh;
|
||||
import h3d.scene.CustomObject;
|
||||
import h3d.prim.Polygon;
|
||||
import h3d.prim.UV;
|
||||
import h3d.Vector;
|
||||
import h3d.Quat;
|
||||
import dts.Node;
|
||||
import h3d.mat.BlendMode;
|
||||
import h3d.mat.Data.Wrap;
|
||||
import h3d.mat.Texture;
|
||||
import hxd.res.Loader;
|
||||
import h3d.mat.Material;
|
||||
import h3d.scene.Object;
|
||||
import haxe.io.Path;
|
||||
import src.ResourceLoader;
|
||||
import dts.DtsFile;
|
||||
import h3d.Matrix;
|
||||
import src.Util;
|
||||
|
||||
var DROP_TEXTURE_FOR_ENV_MAP = ['shapes/items/superjump.dts', 'shapes/items/antigravity.dts'];
|
||||
|
||||
typedef GraphNode = {
|
||||
var index:Int;
|
||||
var node:Node;
|
||||
var children:Array<GraphNode>;
|
||||
var parent:GraphNode;
|
||||
}
|
||||
|
||||
typedef MaterialGeometry = {
|
||||
var vertices:Array<Vector>;
|
||||
var normals:Array<Vector>;
|
||||
var uvs:Array<UV>;
|
||||
var indices:Array<Int>;
|
||||
}
|
||||
|
||||
typedef SkinMeshData = {
|
||||
var meshIndex:Int;
|
||||
var vertices:Array<Vector>;
|
||||
var normals:Array<Vector>;
|
||||
var indices:Array<Int>;
|
||||
var geometry:Object;
|
||||
}
|
||||
|
||||
@:publicFields
|
||||
class DtsObject extends Object {
|
||||
var dtsPath:String;
|
||||
var directoryPath:String;
|
||||
var dts:DtsFile;
|
||||
|
||||
var materials:Array<Material> = [];
|
||||
var matNameOverride:Map<String, String> = new Map();
|
||||
|
||||
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 isTSStatic:Bool;
|
||||
var isCollideable:Bool;
|
||||
var showSequences:Bool = true;
|
||||
var hasNonVisualSequences:Bool = true;
|
||||
|
||||
var geometries:Array<Object> = [];
|
||||
var skinMeshData:SkinMeshData;
|
||||
|
||||
var fs:Loader;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
}
|
||||
|
||||
public function init() {
|
||||
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);
|
||||
}
|
||||
for (i in 0...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]);
|
||||
}
|
||||
}
|
||||
|
||||
this.graphNodes = graphNodes;
|
||||
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;
|
||||
|
||||
for (object in objects) {
|
||||
var isCollisionObject = dts.names[object.name].substr(0, 3).toLowerCase() == "col";
|
||||
|
||||
if (!isCollisionObject || this.isCollideable) {
|
||||
var mat = this.nodeTransforms[i];
|
||||
|
||||
for (i in object.firstMesh...(object.firstMesh + object.numMeshes)) {
|
||||
if (i >= this.dts.meshes.length)
|
||||
continue;
|
||||
|
||||
var mesh = this.dts.meshes[i];
|
||||
|
||||
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 skinnedMeshIndex:Int = -1;
|
||||
for (i in 0...dts.meshes.length) {
|
||||
var dtsMesh = this.dts.meshes[i];
|
||||
|
||||
if (dtsMesh == null || dtsMesh.type != 1)
|
||||
continue;
|
||||
|
||||
var vertices = [];
|
||||
for (i in 0...dtsMesh.vertices.length)
|
||||
vertices.push(new Vector());
|
||||
|
||||
var vertexNormals = [];
|
||||
for (i in 0...dtsMesh.normals.length)
|
||||
vertexNormals.push(new Vector());
|
||||
|
||||
var materialGeometry = this.generateMaterialGeometry(dtsMesh, vertices, vertexNormals);
|
||||
staticMaterialGeometries.push(materialGeometry);
|
||||
|
||||
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 idx = merged.map(x -> x.indices);
|
||||
for (i in idx) {
|
||||
this.skinMeshData.indices = this.skinMeshData.indices.concat(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (staticCollision.length > 0) {
|
||||
var geometry = this.createGeometryFromMaterialGeometry(this.mergeMaterialGeometries(staticCollision));
|
||||
staticGeometries.push(geometry);
|
||||
collisionGeometries.push(geometry);
|
||||
this.geometries.push(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);
|
||||
}
|
||||
}
|
||||
|
||||
function computeMaterials() {
|
||||
var environmentMaterial:Material = null;
|
||||
|
||||
for (i in 0...dts.matNames.length) {
|
||||
var matName = matNameOverride.exists(dts.matNames[i]) ? matNameOverride.get(dts.matNames[i]) : this.dts.matNames[i];
|
||||
var flags = dts.matFlags[i];
|
||||
var fullNames = ResourceLoader.getFullNamesOf(this.directoryPath + '/' + matName).filter(x -> Path.extension(x) != "dts");
|
||||
var fullName = fullNames.length > 0 ? fullNames[0] : null;
|
||||
|
||||
if (this.isTSStatic && environmentMaterial != null && DROP_TEXTURE_FOR_ENV_MAP.contains(this.dtsPath)) {
|
||||
this.materials.push(environmentMaterial);
|
||||
continue;
|
||||
}
|
||||
|
||||
var material = Material.create();
|
||||
|
||||
if (fullName == null || (this.isTSStatic && ((flags & (1 << 31) > 0)))) {
|
||||
if (this.isTSStatic) {
|
||||
// TODO USE PBR???
|
||||
}
|
||||
} else if (Path.extension(fullName) == "ifl") {
|
||||
// TODO IFL SHIT
|
||||
} else {
|
||||
var texture:Texture = this.fs.load(this.directoryPath + "/" + fullName).toImage().toTexture();
|
||||
texture.wrap = Wrap.Repeat;
|
||||
material.texture = texture;
|
||||
// TODO TRANSLUENCY SHIT
|
||||
}
|
||||
// TODO TRANSPARENCY SHIT
|
||||
if (flags & 8 > 0)
|
||||
material.blendMode = BlendMode.Add;
|
||||
if (flags & 16 > 0)
|
||||
material.blendMode = BlendMode.Sub;
|
||||
|
||||
if (this.isTSStatic && !(flags & 64 > 0)) {
|
||||
// TODO THIS SHIT
|
||||
}
|
||||
// ((flags & 32) || environmentMaterial) ? new Materia
|
||||
|
||||
this.materials.push(material);
|
||||
}
|
||||
|
||||
if (this.materials.length == 0) {
|
||||
var mat = Material.create();
|
||||
this.materials.push(mat);
|
||||
// TODO THIS
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
function generateMaterialGeometry(dtsMesh:dts.Mesh, vertices:Array<Vector>, vertexNormals:Array<Vector>) {
|
||||
var materialGeometry:Array<MaterialGeometry> = this.materials.map(x -> {
|
||||
vertices: [],
|
||||
normals: [],
|
||||
uvs: [],
|
||||
indices: []
|
||||
});
|
||||
|
||||
for (primitive in dtsMesh.primitives) {
|
||||
var k = 0;
|
||||
var geometrydata = materialGeometry[primitive.matIndex];
|
||||
|
||||
for (i in primitive.firstElement...(primitive.firstElement + primitive.numElements - 2)) {
|
||||
var i1 = dtsMesh.indices[i];
|
||||
var i2 = dtsMesh.indices[i + 1];
|
||||
var i3 = dtsMesh.indices[i + 2];
|
||||
|
||||
if (k % 2 == 0) {
|
||||
// Swap the first and last index to mainting correct winding order
|
||||
var temp = i1;
|
||||
i1 = i3;
|
||||
i3 = temp;
|
||||
}
|
||||
|
||||
for (index in [i1, i2, i3]) {
|
||||
var vertex = vertices[index];
|
||||
geometrydata.vertices.push(new Vector(vertex.x, vertex.y, vertex.z));
|
||||
|
||||
var uv = dtsMesh.uv[index];
|
||||
geometrydata.uvs.push(new UV(uv.x, uv.y));
|
||||
|
||||
var normal = vertexNormals[index];
|
||||
geometrydata.normals.push(new Vector(normal.x, normal.y, normal.z));
|
||||
}
|
||||
|
||||
geometrydata.indices.push(i1);
|
||||
geometrydata.indices.push(i2);
|
||||
geometrydata.indices.push(i3);
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return materialGeometry;
|
||||
}
|
||||
|
||||
function mergeMaterialGeometries(materialGeometries:Array<Array<MaterialGeometry>>) {
|
||||
var merged = materialGeometries[0].map(x -> {
|
||||
vertices: [],
|
||||
normals: [],
|
||||
uvs: [],
|
||||
indices: []
|
||||
});
|
||||
|
||||
for (matGeom in materialGeometries) {
|
||||
for (i in 0...matGeom.length) {
|
||||
merged[i].vertices = merged[i].vertices.concat(matGeom[i].vertices);
|
||||
merged[i].normals = merged[i].normals.concat(matGeom[i].normals);
|
||||
merged[i].uvs = merged[i].uvs.concat(matGeom[i].uvs);
|
||||
merged[i].indices = merged[i].indices.concat(matGeom[i].indices);
|
||||
}
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
function createGeometryFromMaterialGeometry(materialGeometry:Array<MaterialGeometry>) {
|
||||
var geo = new Object();
|
||||
for (i in 0...materialGeometry.length) {
|
||||
if (materialGeometry[i].vertices.length == 0)
|
||||
continue;
|
||||
|
||||
var poly = new Polygon(materialGeometry[i].vertices.map(x -> x.toPoint()));
|
||||
poly.normals = materialGeometry[i].normals.map(x -> x.toPoint());
|
||||
poly.uvs = materialGeometry[i].uvs;
|
||||
|
||||
var obj = new Mesh(poly, materials[i], geo);
|
||||
}
|
||||
return geo;
|
||||
}
|
||||
|
||||
public function update(currentTime:Float, dt:Float) {
|
||||
for (sequence in this.dts.sequences) {
|
||||
if (!this.showSequences)
|
||||
break;
|
||||
if (!this.hasNonVisualSequences)
|
||||
break;
|
||||
|
||||
var rot = sequence.rotationMatters.length > 0 ? sequence.rotationMatters[0] : 0;
|
||||
var trans = sequence.translationMatters.length > 0 ? sequence.translationMatters[0] : 0;
|
||||
var affectedCount = 0;
|
||||
var completion = (currentTime + dt) / sequence.duration;
|
||||
|
||||
var quaternions:Array<Quat> = null;
|
||||
var translations:Array<Vector> = null;
|
||||
|
||||
var actualKeyframe = this.sequenceKeyframeOverride.exists(sequence) ? this.sequenceKeyframeOverride.get(sequence) : ((completion * sequence.numKeyFrames) % sequence.numKeyFrames);
|
||||
if (this.lastSequenceKeyframes.get(sequence) == actualKeyframe)
|
||||
continue;
|
||||
lastSequenceKeyframes.set(sequence, actualKeyframe);
|
||||
|
||||
var keyframeLow = Math.floor(actualKeyframe);
|
||||
var keyframeHigh = Math.ceil(actualKeyframe) % sequence.numKeyFrames;
|
||||
var t = (actualKeyframe - keyframeLow) % 1;
|
||||
|
||||
if (rot > 0) {
|
||||
quaternions = [];
|
||||
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
var affected = ((1 << i) & rot) != 0;
|
||||
|
||||
if (affected) {
|
||||
var rot1 = this.dts.nodeRotations[sequence.numKeyFrames * affectedCount + keyframeLow];
|
||||
var rot2 = this.dts.nodeRotations[sequence.numKeyFrames * affectedCount + keyframeHigh];
|
||||
|
||||
var q1 = new Quat(rot1.x, rot1.y, rot1.z, rot1.w);
|
||||
q1.normalize();
|
||||
q1.conjugate();
|
||||
|
||||
var q2 = new Quat(rot2.x, rot2.y, rot2.z, rot2.w);
|
||||
q2.normalize();
|
||||
q2.conjugate();
|
||||
|
||||
var quat = new Quat();
|
||||
quat.slerp(q1, q2, t);
|
||||
quat.normalize();
|
||||
affectedCount++;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
affectedCount = 0;
|
||||
if (trans > 0) {
|
||||
translations = [];
|
||||
|
||||
for (i in 0...this.dts.nodes.length) {
|
||||
var affected = ((1 << i) & trans) != 0;
|
||||
|
||||
if (affected) {
|
||||
var trans1 = this.dts.nodeTranslations[sequence.numKeyFrames * affectedCount + keyframeLow];
|
||||
var trans2 = this.dts.nodeTranslations[sequence.numKeyFrames * affectedCount + keyframeHigh];
|
||||
|
||||
var v1 = new Vector(trans1.x, trans1.y, trans1.z);
|
||||
var v2 = new Vector(trans2.x, trans2.y, trans2.z);
|
||||
|
||||
translations.push(Util.lerpThreeVectors(v1, v2, t));
|
||||
} else {
|
||||
var translation = this.dts.defaultTranslations[i];
|
||||
translations.push(new Vector(translation.x, translation.y, translation.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
var info = this.skinMeshData;
|
||||
var mesh = this.dts.meshes[info.meshIndex];
|
||||
|
||||
for (i in 0...info.vertices.length) {
|
||||
info.vertices[i] = new Vector();
|
||||
info.normals[i] = new Vector();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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];
|
||||
|
||||
vec.set(vertex.x, vertex.y, vertex.z);
|
||||
vec2.set(normal.x, normal.y, normal.z);
|
||||
var mat = boneTransformations[mesh.boneIndices[i]];
|
||||
|
||||
vec.transform(mat);
|
||||
vec = vec.multiply(mesh.weights[i]);
|
||||
vec2.transform3x3(mat);
|
||||
vec2 = vec2.multiply(mesh.weights[i]);
|
||||
|
||||
info.vertices[vIndex] = info.vertices[vIndex].add(vec);
|
||||
info.normals[vIndex] = info.normals[vIndex].add(vec2);
|
||||
}
|
||||
|
||||
for (i in 0...info.normals.length) {
|
||||
var norm = info.normals[i];
|
||||
var len2 = norm.lengthSq();
|
||||
|
||||
if (len2 > 0.01)
|
||||
norm.normalize();
|
||||
}
|
||||
|
||||
var meshIndex = 0;
|
||||
var mesh:Mesh = cast info.geometry.children[meshIndex];
|
||||
var prim:Polygon = cast mesh.primitive;
|
||||
var pos = 0;
|
||||
for (i in info.indices) {
|
||||
if (pos >= prim.points.length) {
|
||||
meshIndex++;
|
||||
if (prim.buffer != null)
|
||||
prim.buffer.dispose();
|
||||
mesh.primitive = prim;
|
||||
mesh = cast info.geometry.children[meshIndex];
|
||||
prim = cast mesh.primitive;
|
||||
pos = 0;
|
||||
}
|
||||
var vertex = info.vertices[i];
|
||||
var normal = info.normals[i];
|
||||
prim.points[pos] = vertex.toPoint();
|
||||
prim.normals[pos] = normal.toPoint();
|
||||
pos++;
|
||||
}
|
||||
if (prim.buffer != null)
|
||||
prim.buffer.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class DtsObject extends CustomObject {
|
||||
public function getMountTransform(mountPoint:Int) {
|
||||
// TODO FIX WHEN DTS SUPPORT
|
||||
return Matrix.I();
|
||||
|
|
|
|||
15
src/Main.hx
15
src/Main.hx
|
|
@ -1,5 +1,6 @@
|
|||
package;
|
||||
|
||||
import dts.DtsFile;
|
||||
import src.InteriorGeometry;
|
||||
import h3d.Quat;
|
||||
import src.PathedInteriorMarker;
|
||||
|
|
@ -16,12 +17,14 @@ import h3d.scene.fwd.DirLight;
|
|||
import h3d.mat.Material;
|
||||
import h3d.prim.Cube;
|
||||
import h3d.scene.*;
|
||||
import src.DtsObject;
|
||||
|
||||
class Main extends hxd.App {
|
||||
var scene:Scene;
|
||||
var fileSystem:FileSystem;
|
||||
|
||||
var world:MarbleWorld;
|
||||
var dtsObj:DtsObject;
|
||||
|
||||
override function init() {
|
||||
super.init();
|
||||
|
|
@ -30,14 +33,20 @@ class Main extends hxd.App {
|
|||
|
||||
var loader = new Loader(fileSystem);
|
||||
|
||||
dtsObj = new DtsObject();
|
||||
dtsObj.dtsPath = "data/shapes/hazards/trapdoor.dts";
|
||||
dtsObj.isCollideable = false;
|
||||
dtsObj.isTSStatic = false;
|
||||
dtsObj.fs = loader;
|
||||
|
||||
world = new MarbleWorld(s3d);
|
||||
|
||||
var db = new InteriorGeometry();
|
||||
DifBuilder.loadDif("interiors/beginner/training_friction.dif", loader, db);
|
||||
DifBuilder.loadDif("data/interiors/beginner/training_friction.dif", loader, db);
|
||||
world.addInterior(db);
|
||||
|
||||
var pi = new PathedInterior();
|
||||
DifBuilder.loadDif("interiors/addon/smallplatform.dif", loader, pi);
|
||||
DifBuilder.loadDif("data/interiors/addon/smallplatform.dif", loader, pi);
|
||||
var pim = pi.getTransform();
|
||||
pim.setPosition(new Vector(5, 0, 0));
|
||||
pi.setTransform(pim);
|
||||
|
|
@ -69,6 +78,8 @@ class Main extends hxd.App {
|
|||
|
||||
world.addPathedInterior(pi);
|
||||
|
||||
world.addDtsObject(dtsObj);
|
||||
|
||||
// for (surf in db.collider.surfaces) {
|
||||
// var surfmin = new CustomObject(cube, mat, s3d);
|
||||
// var bound = surf.boundingBox;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import src.DtsObject;
|
||||
import src.PathedInterior;
|
||||
import hxd.Key;
|
||||
import h3d.Vector;
|
||||
|
|
@ -15,6 +16,7 @@ class MarbleWorld {
|
|||
public var interiors:Array<InteriorGeometry> = [];
|
||||
public var pathedInteriors:Array<PathedInterior> = [];
|
||||
public var marbles:Array<Marble> = [];
|
||||
public var dtsObjects:Array<DtsObject> = [];
|
||||
|
||||
public var currentTime:Float = 0;
|
||||
|
||||
|
|
@ -38,6 +40,12 @@ class MarbleWorld {
|
|||
obj.init();
|
||||
}
|
||||
|
||||
public function addDtsObject(obj:DtsObject) {
|
||||
this.dtsObjects.push(obj);
|
||||
this.scene.addChild(obj);
|
||||
obj.init();
|
||||
}
|
||||
|
||||
public function addMarble(marble:Marble) {
|
||||
this.marbles.push(marble);
|
||||
if (marble.controllable) {
|
||||
|
|
@ -48,6 +56,9 @@ class MarbleWorld {
|
|||
}
|
||||
|
||||
public function update(dt:Float) {
|
||||
for (obj in dtsObjects) {
|
||||
obj.update(currentTime, dt);
|
||||
}
|
||||
for (marble in marbles) {
|
||||
marble.update(currentTime, dt, collisionWorld, this.pathedInteriors);
|
||||
}
|
||||
|
|
|
|||
52
src/ResourceLoader.hx
Normal file
52
src/ResourceLoader.hx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package src;
|
||||
|
||||
import sys.FileSystem;
|
||||
import sys.io.File;
|
||||
import haxe.io.Path;
|
||||
import dts.DtsFile;
|
||||
import dif.Dif;
|
||||
|
||||
class ResourceLoader {
|
||||
static var interiorResources:Map<String, Dif> = new Map();
|
||||
static var dtsResources:Map<String, DtsFile> = new Map();
|
||||
|
||||
public static function loadInterior(path:String) {
|
||||
if (interiorResources.exists(path))
|
||||
return interiorResources.get(path);
|
||||
else {
|
||||
var itr = Dif.Load(path);
|
||||
interiorResources.set(path, itr);
|
||||
return itr;
|
||||
}
|
||||
}
|
||||
|
||||
public static function loadDts(path:String) {
|
||||
if (dtsResources.exists(path))
|
||||
return dtsResources.get(path);
|
||||
else {
|
||||
var dts = new DtsFile();
|
||||
dts.read(path);
|
||||
dtsResources.set(path, dts);
|
||||
return dts;
|
||||
}
|
||||
}
|
||||
|
||||
public static function clearInteriorResources() {
|
||||
interiorResources = new Map();
|
||||
}
|
||||
|
||||
public static function clearDtsResources() {
|
||||
dtsResources = new Map();
|
||||
}
|
||||
|
||||
public static function getFullNamesOf(path:String) {
|
||||
var files = FileSystem.readDirectory(Path.directory(path));
|
||||
var names = [];
|
||||
var fname = Path.withoutExtension(Path.withoutDirectory(path)).toLowerCase();
|
||||
for (file in files) {
|
||||
if (Path.withoutExtension(Path.withoutDirectory(file)).toLowerCase() == fname)
|
||||
names.push(file);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
|
@ -53,7 +53,10 @@ class DtsAlloc {
|
|||
}
|
||||
|
||||
public function readPoint3F():Point3F {
|
||||
return new Point3F(this.readF32(), this.readF32(), this.readF32());
|
||||
var x = this.readF32();
|
||||
var y = this.readF32();
|
||||
var z = this.readF32();
|
||||
return new Point3F(x, y, z);
|
||||
}
|
||||
|
||||
public function readBoxF():Box3F {
|
||||
|
|
@ -70,6 +73,8 @@ class DtsAlloc {
|
|||
public function readS16() {
|
||||
buf.seek(this.index16);
|
||||
var val = this.buf.readInt16();
|
||||
if (val > 32767)
|
||||
val -= 65536;
|
||||
this.index16 += 2;
|
||||
return val;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,9 +321,15 @@ class DtsFile {
|
|||
}
|
||||
|
||||
function parseMaterialList(br:BytesReader, version:Int) {
|
||||
var matStreamType = br.readInt32();
|
||||
var matStreamType = br.readByte();
|
||||
var numMaterials = br.readInt32();
|
||||
matNames = [];
|
||||
matFlags = [];
|
||||
matReflectanceMaps = [];
|
||||
matBumpMaps = [];
|
||||
matDetailMaps = [];
|
||||
matDetailScales = [];
|
||||
matReflectionAmounts = [];
|
||||
for (i in 0...numMaterials) {
|
||||
matNames.push(br.readStr());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package dts;
|
||||
|
||||
import hxsl.Types.Matrix;
|
||||
import haxe.Exception;
|
||||
import dif.math.Point2F;
|
||||
import dif.math.Point3F;
|
||||
import dif.math.Box3F;
|
||||
|
||||
@:publicFields
|
||||
class Mesh {
|
||||
var meshType:Int;
|
||||
var numFrames:Int;
|
||||
|
|
@ -23,6 +25,11 @@ class Mesh {
|
|||
var vertsPerFrame:Int;
|
||||
var type:Int;
|
||||
var shape:DtsFile;
|
||||
var initialTransforms:Array<Matrix>;
|
||||
var vertexIndices:Array<Int>;
|
||||
var boneIndices:Array<Int>;
|
||||
var weights:Array<Float>;
|
||||
var nodeIndices:Array<Int>;
|
||||
|
||||
public function new() {}
|
||||
|
||||
|
|
@ -56,10 +63,9 @@ class Mesh {
|
|||
uv = shape.meshes[this.parent].uv;
|
||||
}
|
||||
|
||||
var numNormals = reader.readU32();
|
||||
normals = [];
|
||||
if (this.parent < 0) {
|
||||
for (i in 0...numNormals) {
|
||||
for (i in 0...numVerts) {
|
||||
normals.push(reader.readPoint3F());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -100,40 +106,66 @@ class Mesh {
|
|||
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();
|
||||
var numVerts = reader.readS32();
|
||||
if (parent < 0) {
|
||||
vertices = [];
|
||||
for (i in 0...numVerts) {
|
||||
vertices.push(reader.readPoint3F());
|
||||
}
|
||||
normals = [];
|
||||
for (i in 0...numVerts) {
|
||||
normals.push(reader.readPoint3F());
|
||||
}
|
||||
if (parent < 0) {
|
||||
for (i in 0...numVerts) {
|
||||
reader.readU8();
|
||||
}
|
||||
}
|
||||
var sz = reader.readS32();
|
||||
initialTransforms = [];
|
||||
for (i in 0...sz) {
|
||||
initialTransforms.push(reader.readMatrixF());
|
||||
}
|
||||
}
|
||||
|
||||
sz = reader.readS32();
|
||||
for (i in 0...sz) {
|
||||
sz = reader.readS32();
|
||||
vertexIndices = [];
|
||||
for (i in 0...sz) {
|
||||
vertexIndices.push(reader.readS32());
|
||||
}
|
||||
boneIndices = [];
|
||||
for (i in 0...sz) {
|
||||
boneIndices.push(reader.readS32());
|
||||
}
|
||||
weights = [];
|
||||
for (i in 0...sz) {
|
||||
weights.push(reader.readF32());
|
||||
}
|
||||
sz = reader.readS32();
|
||||
nodeIndices = [];
|
||||
for (i in 0...sz) {
|
||||
nodeIndices.push(reader.readS32());
|
||||
}
|
||||
} else {
|
||||
var other = this.shape.meshes[parent];
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
vertices = other.vertices;
|
||||
normals = other.normals;
|
||||
if (parent < 0) {
|
||||
for (i in 0...numVerts) {
|
||||
reader.readU8();
|
||||
}
|
||||
}
|
||||
reader.readS32();
|
||||
}
|
||||
for (i in 0...sz) {
|
||||
initialTransforms = other.initialTransforms;
|
||||
reader.readS32();
|
||||
}
|
||||
for (i in 0...sz) {
|
||||
reader.readF32();
|
||||
}
|
||||
|
||||
sz = reader.readS32();
|
||||
for (i in 0...sz) {
|
||||
vertexIndices = other.vertexIndices;
|
||||
boneIndices = other.boneIndices;
|
||||
weights = other.weights;
|
||||
reader.readS32();
|
||||
nodeIndices = other.nodeIndices;
|
||||
}
|
||||
|
||||
reader.guard();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package dts;
|
|||
|
||||
import dif.io.BytesReader;
|
||||
|
||||
@:publicFields
|
||||
class Node {
|
||||
var name:Int;
|
||||
var parent:Int;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package dts;
|
|||
|
||||
import dif.io.BytesReader;
|
||||
|
||||
@:publicFields
|
||||
class Object {
|
||||
var name:Int;
|
||||
var numMeshes:Int;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ package dts;
|
|||
|
||||
import dif.io.BytesReader;
|
||||
|
||||
@:publicFields
|
||||
class Primitive {
|
||||
var firstElement:Int;
|
||||
var numElements:Int;
|
||||
var type:Int;
|
||||
var matIndex:Int;
|
||||
|
||||
public function new() {}
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ class Primitive {
|
|||
var p = new Primitive();
|
||||
p.firstElement = reader.readU16();
|
||||
p.numElements = reader.readU16();
|
||||
p.type = reader.readU32();
|
||||
p.matIndex = (reader.readU32() & 0x00ffffff);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package dts;
|
|||
import dif.io.BytesReader;
|
||||
import hl.I64;
|
||||
|
||||
@:publicFields
|
||||
class Sequence {
|
||||
var nameIndex:Int;
|
||||
var numKeyFrames:Int;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue