Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Copyright 2018 Kion
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- "use strict";
- const fs = require("fs");
- const THREE = require("three");
- const util = require("util");
- const buffer = fs.readFileSync("/home/kion/Github/mml2/DAT/ST0F00.BIN");
- const SCALE = 0.05;
- var ofs = 0x30;
- var nb_models = buffer.readUInt32LE(ofs);
- console.log("Number of models: %d", nb_models);
- ofs = 0x34;
- var models = new Array();
- for (var i = 0; i < nb_models; i++) {
- var model = {
- "flag": buffer.readUInt32LE(ofs + 0x00),
- "mesh": buffer.readUInt32LE(ofs + 0x04),
- "bone": buffer.readUInt32LE(ofs + 0x08),
- "anim": buffer.readUInt32LE(ofs + 0x0c)
- };
- console.log("Offset: 0x%s", ofs.toString(16));
- console.log("Flag: 0x%s", model.flag.toString(16));
- console.log("Mesh Offset: 0x%s", model.mesh.toString(16));
- console.log("Anim Offset: 0x%s", model.bone.toString(16));
- console.log("Time Offset: 0x%s", model.anim.toString(16));
- console.log();
- if (model.mesh) {
- model.mesh += 0x30;
- }
- if (model.bone) {
- model.bone += 0x30;
- }
- if (model.anim) {
- model.anim += 0x30;
- }
- ofs += 0x10;
- models.push(model);
- }
- process.exit();
- console.log(models);
- for (var i = 0; i < models.length; i++) {
- var index = i;
- read_model(models[index].mesh, models[index].bone, index);
- }
- function read_model(mesh_ofs, bone_ofs, index) {
- var nb_prim = buffer.readUInt8(mesh_ofs);
- var dword = buffer.readUInt32LE(mesh_ofs);
- var header_ptr = buffer.readUInt32LE(mesh_ofs + 4) + 0x30;
- var med_lod_ptr = buffer.readUInt32LE(mesh_ofs + 8) + 0x30;
- var low_lod_ptr = buffer.readUInt32LE(mesh_ofs + 0x0c) + 0x30;
- var bone_ptr = buffer.readUInt32LE(mesh_ofs + 0x10);
- var hierarchy_ptr = buffer.readUInt32LE(mesh_ofs + 0x14);
- var bone_length = hierarchy_ptr - bone_ptr;
- var nb_bone = Math.floor(bone_length / 6);
- console.log("Number of bones: %d", nb_bone);
- var bones = new Array(nb_prim);
- for(var i = 0; i < bones.length; i++) {
- bones[i] = new THREE.Bone();
- }
- if(bone_ptr) {
- var ofs = bone_ptr + 0x30;
- for(var i = 0; i < nb_bone; i++) {
- if(i === 0) {
- continue;
- }
- var x = buffer.readInt16LE(ofs + (i*6) + 0);
- var y = buffer.readInt16LE(ofs + (i*6) + 2);
- var z = buffer.readInt16LE(ofs + (i*6) + 4);
- bones[i].position.x = x * SCALE * 0.4;
- bones[i].position.y = y * SCALE * -1 * 0.4;
- bones[i].position.z = z * SCALE * 0.4;
- bones[i].updateMatrix();
- console.log("Bone %d (%d %d %d)", i, x, y, z);
- }
- }
- if(hierarchy_ptr) {
- var ofs = hierarchy_ptr + 0x30;
- for(var i = 0; i < nb_bone; i++) {
- var child = buffer.readUInt8(ofs + 0);
- var parent = buffer.readUInt8(ofs + 1);
- ofs += 4;
- if(child === 0) {
- continue;
- }
- bones[parent].add(bones[child]);
- }
- }
- for(var i = 0; i < bones.length; i++) {
- bones[i].updateMatrixWorld();
- }
- console.log("Index: %d, %s (%s)", index, dword.toString(16), bone_ofs ? "yes" : "no");
- console.log("Header Pointer: %s", header_ptr.toString(16));
- var vertices = [];
- var faces = [];
- var vertex_ofs = 0;
- console.log("bone: %s", bone_ofs.toString(16));
- for (var n = 0; n < nb_prim; n++) {
- var header = {
- "nb_tri": buffer.readUInt8(header_ptr + (n*0x10) + 0x00),
- "nb_quad": buffer.readUInt8(header_ptr + (n*0x10) + 0x01),
- "nb_vert": buffer.readUInt8(header_ptr + (n*0x10) + 0x02),
- "tri_ofs": buffer.readUInt32LE(header_ptr + (n*0x10) + 0x04) + 0x30,
- "quad_ofs": buffer.readUInt32LE(header_ptr + (n*0x10) + 0x08) + 0x30,
- "vert_ofs": buffer.readUInt32LE(header_ptr + (n*0x10) + 0x0c) + 0x30
- };
- var mask = 0b1111111;
- var ofs = header.tri_ofs;
- for (var i = 0; i < header.nb_tri; i++) {
- var dword = buffer.readUInt32LE(ofs + 8);
- var a = dword & mask;
- var b = (dword >> 7) & mask;
- var c = (dword >> 14) & mask;
- ofs += 0x0c;
- faces.push({
- "a": a + vertex_ofs,
- "b": b + vertex_ofs,
- "c": c + vertex_ofs
- });
- }
- var ofs = header.quad_ofs;
- for (var i = 0; i < header.nb_quad; i++) {
- var dword = buffer.readUInt32LE(ofs + 8);
- var a = dword & mask;
- var b = (dword >> 7) & mask;
- var c = (dword >> 14) & mask;
- var d = (dword >> 21) & mask;
- ofs += 0x0c;
- faces.push({
- "a": a + vertex_ofs,
- "b": b + vertex_ofs,
- "c": c + vertex_ofs
- });
- faces.push({
- "a": b + vertex_ofs,
- "b": d + vertex_ofs,
- "c": c + vertex_ofs
- });
- }
- mask = 0b1111111111;
- var msb = 0b1000000000;
- var lsb = 0b0111111111;
- var ofs = header.vert_ofs;
- for (var i = 0; i < header.nb_vert; i++) {
- var dword = buffer.readUInt32LE(ofs);
- ofs += 4;
- var x = dword & mask;
- var y = (dword >> 10) & mask;
- var z = (dword >> 20) & mask;
- if (x & msb) {
- x = (msb - (x & lsb)) * -1;
- }
- if (y & msb) {
- y = (msb - (y & lsb)) * -1;
- }
- if (z & msb) {
- z = (msb - (z & lsb)) * -1;
- }
- x *= SCALE;
- y *= SCALE * -1;
- z *= SCALE;
- var vertex = new THREE.Vector3(x, y, z);
- vertex.applyMatrix4(bones[n].matrixWorld);
- vertices.push({
- "x": vertex.x,
- "y": vertex.y,
- "z": vertex.z
- });
- }
- vertex_ofs += header.nb_vert;
- }
- var out = "";
- vertices.forEach(function (v) {
- out += util.format("v %s %s %s\n", v.x.toFixed(2), v.y.toFixed(2), v.z.toFixed(2));
- });
- faces.forEach(function (f) {
- out += util.format("f %d %d %d\n", f.a + 1, f.b + 1, f.c + 1);
- });
- fs.writeFileSync("mesh_" + index + ".obj", out);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement