Skip to content

Commit

Permalink
Merge branch 'master' into map_tile_export
Browse files Browse the repository at this point in the history
# Conflicts:
#	modules/decima-ext-model-exporter/src/main/java/com/shade/decima/ui/data/viewer/model/dmf/DMFExporter.java
#	modules/decima-ext-model-exporter/src/main/java/com/shade/decima/ui/data/viewer/model/utils/Quaternion.java
  • Loading branch information
REDxEYE committed Mar 27, 2024
2 parents 016e259 + f80ab87 commit 257de27
Show file tree
Hide file tree
Showing 34 changed files with 445 additions and 647 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'com.shade'
version '0.1.21'
version '0.1.22'

application {
mainClass = 'com.shade.platform.Launcher'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,62 @@
import com.shade.decima.model.rtti.objects.RTTIReference;
import com.shade.decima.model.rtti.registry.RTTITypeRegistry;
import com.shade.decima.model.rtti.types.RTTITypeEnum;
import com.shade.decima.ui.data.viewer.model.utils.Matrix3x3;
import com.shade.decima.ui.data.viewer.model.utils.Matrix4x4;
import com.shade.decima.ui.data.viewer.model.utils.Transform;
import com.shade.decima.ui.data.viewer.model.utils.Vector3;
import com.shade.platform.model.util.MathUtils;
import com.shade.util.NotNull;
import org.joml.Matrix4d;

import java.util.UUID;

public class BaseModelExporter {
@NotNull
protected static Transform worldTransformToTransform(@NotNull RTTIObject transform) {
protected static Matrix4d worldTransformToMatrix(@NotNull RTTIObject transform) {
if (!transform.type().isInstanceOf("WorldTransform")) {
throw new IllegalArgumentException("Expected WorldTransform instance, but got " + transform.type());
}
final var pos = transform.obj("Position");
final var ori = transform.obj("Orientation");
final var col0 = ori.obj("Col0");
final var col1 = ori.obj("Col1");
final var col2 = ori.obj("Col2");

final Vector3 translation = new Vector3(new double[]{
pos.f64("X"),
pos.f64("Y"),
pos.f64("Z")
});

final Matrix3x3 rotationAndScale = new Matrix3x3(new double[][]{
new double[]{col0.f32("X"), col0.f32("Y"), col0.f32("Z")},
new double[]{col1.f32("X"), col1.f32("Y"), col1.f32("Z")},
new double[]{col2.f32("X"), col2.f32("Y"), col2.f32("Z")}
});

return new Transform(translation, rotationAndScale.toQuaternion(), rotationAndScale.toScale());
return new Matrix4d(
col0.f32("X"), col0.f32("Y"), col0.f32("Z"), 0,
col1.f32("X"), col1.f32("Y"), col1.f32("Z"), 0,
col2.f32("X"), col2.f32("Y"), col2.f32("Z"), 0,
pos.f64("X"), pos.f64("Y"), pos.f64("Z"), 1
);
}

@NotNull
protected static Transform mat34ToTransform(@NotNull RTTIObject object) {
protected static Matrix4d mat34ToMatrix(@NotNull RTTIObject object) {
final RTTIObject row0 = object.obj("Row0");
final RTTIObject row1 = object.obj("Row1");
final RTTIObject row2 = object.obj("Row2");
final Matrix4x4 mat = new Matrix4x4(new double[][]{
{row0.f32("X"), row0.f32("Y"), row0.f32("Z"), row0.f32("W")},
{row1.f32("X"), row1.f32("Y"), row1.f32("Z"), row1.f32("W")},
{row2.f32("X"), row2.f32("Y"), row2.f32("Z"), row2.f32("W")},
{0.0, 0.0, 0.0, 1.0}
});

return new Transform(mat.toTranslation(), mat.toQuaternion(), mat.toScale());
return new Matrix4d(
row0.f32("X"), row1.f32("X"), row2.f32("X"), 0.0f,
row0.f32("Y"), row1.f32("Y"), row2.f32("Y"), 0.0f,
row0.f32("Z"), row1.f32("Z"), row2.f32("Z"), 0.0f,
row0.f32("W"), row1.f32("W"), row2.f32("W"), 1.0f
);
}


@NotNull
protected static Matrix4x4 mat44TransformToMatrix4x4(@NotNull RTTIObject transform) {
protected static Matrix4d mat44TransformToMatrix(@NotNull RTTIObject transform) {
if (!transform.type().isInstanceOf("Mat44")) {
throw new IllegalArgumentException("Expected Mat44 instance, but got " + transform.type());
}
final var col0 = transform.obj("Col0");
final var col1 = transform.obj("Col1");
final var col2 = transform.obj("Col2");
final var col3 = transform.obj("Col3");

return new Matrix4x4(new double[][]{
new double[]{col0.f32("X"), col1.f32("X"), col2.f32("X"), col3.f32("X")},
new double[]{col0.f32("Y"), col1.f32("Y"), col2.f32("Y"), col3.f32("Y")},
new double[]{col0.f32("Z"), col1.f32("Z"), col2.f32("Z"), col3.f32("Z")},
new double[]{col0.f32("W"), col1.f32("W"), col2.f32("W"), col3.f32("W")}
});
return new Matrix4d(
col0.f32("X"), col0.f32("Y"), col0.f32("Z"), col0.f32("W"),
col1.f32("X"), col1.f32("Y"), col1.f32("Z"), col1.f32("W"),
col2.f32("X"), col2.f32("Y"), col2.f32("Z"), col2.f32("W"),
col3.f32("X"), col3.f32("Y"), col3.f32("Z"), col3.f32("W")
);
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
@Selector(type = @Type(name = "PrefabResource")),
@Selector(type = @Type(name = "PrefabInstance")),
@Selector(type = @Type(name = "ModelPartResource")),
@Selector(type = @Type(name = "HumanoidBodyVariant"), game = GameType.HZD),
@Selector(type = @Type(name = "HairModelComponentResource")),
@Selector(type = @Type(name = "HairSkinnedMeshLod")),
@Selector(type = @Type(name = "HairSkinnedMesh")),
@Selector(type = @Type(name = "SkinnedModelResource"), game = GameType.HZD),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private void exportControlledEntityResource(
task.worked(1);
}

final RTTIReference[] convertedParts = destructibilityResourceRef.object().get("ConvertedParts");
final var convertedParts = destructibilityResourceRef.object().refs("ConvertedParts");
try (ProgressMonitor.Task cpTask = task.split(1).begin("Exporting ControlledEntity ConvertedParts", convertedParts.length)) {
for (RTTIReference part : convertedParts) {
final RTTIReference.FollowResult partRef = part.follow(project, destructibilityResourceRef.file());
Expand Down Expand Up @@ -342,7 +342,7 @@ private void exportTerrain(
primitive.setMaterial(material, scene);


final Transform transform = worldTransformToTransform(object.get("Orientation"));
final Matrix4dc transform = worldTransformToMatrix(object.get("Orientation"));
model.transform = new DMFTransform(transform);

scene.models.add(model);
Expand Down Expand Up @@ -402,18 +402,7 @@ private void exportArtPartsDataResource(
final RTTIObject[] joints = repSkeleton.objs("Joints");
for (short i = 0; i < joints.length; i++) {
final RTTIObject joint = joints[i];
final Quaternion rotations;
if (defaultRot.length > 0) {
rotations = new Quaternion(defaultRot[i].f32("X"), defaultRot[i].f32("Y"), defaultRot[i].f32("Z"), defaultRot[i].f32("W"));
} else {
rotations = Quaternion.identity();
}

DMFTransform matrix = new DMFTransform(
new Vector3(defaultPos[i].f32("X"), defaultPos[i].f32("Y"), defaultPos[i].f32("Z")),
new Vector3(1, 1, 1),
rotations
);
final DMFTransform matrix = poseToMatrix(i, defaultRot, defaultPos);
final DMFBone bone = masterSkeleton.findBone(joint.str("Name"));
if (bone != null) {
bone.transform = matrix;
Expand Down Expand Up @@ -627,18 +616,7 @@ private DMFNode artPartsSubModelResourceToModel(
final RTTIObject[] joints = skeleton.objs("Joints");
for (short i = 0; i < joints.length; i++) {
final RTTIObject joint = joints[i];
final Quaternion rotations;
if (defaultRot.length > 0) {
rotations = new Quaternion(defaultRot[i].f32("X"), defaultRot[i].f32("Y"), defaultRot[i].f32("Z"), defaultRot[i].f32("W"));
} else {
rotations = Quaternion.identity();
}

DMFTransform matrix = new DMFTransform(
new Vector3(defaultPos[i].f32("X"), defaultPos[i].f32("Y"), defaultPos[i].f32("Z")),
new Vector3(1, 1, 1),
rotations
);
DMFTransform matrix = poseToMatrix(i, defaultRot, defaultPos);
final DMFBone bone = masterSkeleton.findBone(joint.str("Name"));
if (bone != null) {
bone.transform = matrix;
Expand Down Expand Up @@ -675,6 +653,27 @@ private DMFNode artPartsSubModelResourceToModel(
return model;
}

private static DMFTransform poseToMatrix(short jointId, RTTIObject[] defaultRot, RTTIObject[] defaultPos) {
final Quaterniond rotations;
final Vector3d position;
if (jointId < defaultRot.length) {
rotations = new Quaterniond(defaultRot[jointId].f32("X"), defaultRot[jointId].f32("Y"), defaultRot[jointId].f32("Z"), defaultRot[jointId].f32("W"));
} else {
rotations = new Quaterniond(0, 0, 0, 1);
}
if (jointId < defaultPos.length) {
position = new Vector3d(defaultPos[jointId].f32("X"), defaultPos[jointId].f32("Y"), defaultPos[jointId].f32("Z"));
} else {
position = new Vector3d(0, 0, 0);
}

return new DMFTransform(
position,
new Vector3d(1, 1, 1),
rotations
);
}

@Nullable
private DMFNode artPartsSubModelWithChildrenResourceToModel(
@NotNull ProgressMonitor monitor,
Expand Down Expand Up @@ -802,7 +801,7 @@ private DMFNode prefabInstanceToModel(

final DMFInstance instance = new DMFInstance(resourceName, instanceId);

final Transform transform = worldTransformToTransform(object.get("Orientation"));
final Matrix4dc transform = worldTransformToMatrix(object.get("Orientation"));
instance.transform = new DMFTransform(transform);
return instance;
}
Expand Down Expand Up @@ -834,7 +833,7 @@ private DMFNode staticMeshInstanceToModel(
}

final DMFInstance instance = new DMFInstance(resourceName, instanceId);
final Transform transform = worldTransformToTransform(object.get("Orientation"));
final Matrix4dc transform = worldTransformToMatrix(object.get("Orientation"));
instance.transform = new DMFTransform(transform);
return instance;

Expand Down Expand Up @@ -881,7 +880,7 @@ private DMFAttachment destructibilityPartToModel(
if (state == null) {
return null;
}
DMFAttachment node = new DMFAttachment(object.str("Name"), object.str("BoneName"), new DMFTransform(mat44TransformToMatrix4x4(object.obj("LocalMatrix"))));
DMFAttachment node = new DMFAttachment(object.str("Name"), object.str("BoneName"), new DMFTransform(mat44TransformToMatrix(object.obj("LocalMatrix"))));
node.children.add(state);
return node;
}
Expand All @@ -901,7 +900,7 @@ private DMFNode destructibilityPartStateResourceToModel(
if (state == null) {
return null;
}
final Matrix4x4 offsetMatrix = mat44TransformToMatrix4x4(object.obj("OffsetMatrix"));
final Matrix4dc offsetMatrix = mat44TransformToMatrix(object.obj("OffsetMatrix"));
DMFNode node = new DMFModelGroup(resourceName);
node.transform = new DMFTransform(offsetMatrix);
node.children.add(state);
Expand Down Expand Up @@ -1012,7 +1011,7 @@ private DMFNode multiMeshResourceToModel(
if (model.transform != null) {
throw new IllegalStateException("Model already had transforms, please handle me!");
}
model.transform = new DMFTransform(mat34ToTransform(transforms[partId]));
model.transform = new DMFTransform(mat34ToMatrix(transforms[partId]));
}
group.children.add(model);
}
Expand All @@ -1025,15 +1024,14 @@ private DMFNode multiMeshResourceToModel(
final RTTIObject part = parts[partId];
final RTTIReference meshRef = part.ref("Mesh");
final RTTIReference.FollowResult mesh = Objects.requireNonNull(meshRef.follow(project, file));
final Transform transform = worldTransformToTransform(part.obj("Transform"));
final DMFNode model = toModel(task.split(1), mesh.file(), mesh.object(), "%s_Part%d".formatted(nameFromReference(meshRef, resourceName), partId));
if (model == null) {
continue;
}
if (model.transform != null) {
throw new IllegalStateException("Model already had transforms, please handle me!");
}
model.transform = new DMFTransform(transform);
model.transform = new DMFTransform(worldTransformToMatrix(part.get("Transform")));
group.children.add(model);
}
}
Expand Down Expand Up @@ -1079,13 +1077,11 @@ private DMFNode regularSkinnedMeshResourceToModel(
if (localBoneId == -1) {
continue;
}
DMFTransform matrix;
DMFBone bone = currentSkeleton.findBone(joints[i].str("Name"));
if (bone == null) {
throw new IllegalStateException("All new bones should've been created in validateSkeleton call");
}
matrix = new DMFTransform(mat44TransformToMatrix4x4(inverseBindMatrices[localBoneId]).inverted());
bone.transform = matrix;
bone.transform = new DMFTransform(mat44TransformToMatrix(inverseBindMatrices[localBoneId]).invert());
bone.localSpace = false;
}

Expand Down Expand Up @@ -1458,7 +1454,7 @@ private DMFSkeleton exportSkeleton(@NotNull RTTIObject skeleton) {
final DMFSkeleton dmfSkeleton = new DMFSkeleton();
RTTIObject[] bones = skeleton.objs("Joints");
for (final RTTIObject bone : bones) {
dmfSkeleton.newBone(bone.str("Name"), new DMFTransform(Matrix4x4.identity()), bone.i16("ParentIndex"));
dmfSkeleton.newBone(bone.str("Name"), DMFTransform.IDENTITY, bone.i16("ParentIndex"));
}
return dmfSkeleton;
}
Expand All @@ -1468,7 +1464,7 @@ private void validateSkeleton(@NotNull DMFSkeleton currentSkeleton, @NotNull RTT
for (final RTTIObject bone : bones) {
final String boneName = bone.str("Name");
if (currentSkeleton.findBone(boneName) == null) {
currentSkeleton.newBone(boneName, new DMFTransform(Matrix4x4.identity()), bone.i16("ParentIndex"));
currentSkeleton.newBone(boneName, DMFTransform.IDENTITY, bone.i16("ParentIndex"));
}
}
}
Expand All @@ -1480,14 +1476,14 @@ private void exportHelpers(@NotNull RTTIObject helper, @NotNull DMFSkeleton mast
if (boneId == -1) {
masterSkeleton.newBone(
helperNode.str("Name"),
new DMFTransform(mat44TransformToMatrix4x4(helperNode.obj("Matrix"))),
new DMFTransform(mat44TransformToMatrix(helperNode.obj("Matrix"))),
-1
).localSpace = false;
} else {
String boneName = bones[boneId].str("Name");
masterSkeleton.newBone(
helperNode.str("Name"),
new DMFTransform(mat44TransformToMatrix4x4(helperNode.obj("Matrix"))),
new DMFTransform(mat44TransformToMatrix(helperNode.obj("Matrix"))),
masterSkeleton.findBoneId(boneName)
).localSpace = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
package com.shade.decima.ui.data.viewer.model.dmf.data;

import com.shade.decima.ui.data.viewer.model.utils.Matrix4x4;
import com.shade.decima.ui.data.viewer.model.utils.Quaternion;
import com.shade.decima.ui.data.viewer.model.utils.Transform;
import com.shade.decima.ui.data.viewer.model.utils.Vector3;
import com.shade.util.NotNull;
import org.joml.*;

import java.util.Arrays;

public class DMFTransform {
public static final DMFTransform IDENTITY = new DMFTransform(new Vector3(0, 0, 0), new Vector3(1, 1, 1), new Quaternion(0, 0, 0, 1));
public static final DMFTransform IDENTITY = new DMFTransform(new double[]{0, 0, 0}, new double[]{1, 1, 1}, new double[]{0, 0, 0, 1});

public final double[] position;
public final double[] scale;
public final double[] rotation;

public DMFTransform(@NotNull Vector3 position, @NotNull Vector3 scale, @NotNull Quaternion rotation) {
this.position = position.toArray();
this.scale = scale.toArray();
this.rotation = rotation.toArray();
public DMFTransform(@NotNull double[] position, @NotNull double[] scale, @NotNull double[] rotation) {
this.position = position;
this.scale = scale;
this.rotation = rotation;
}

public DMFTransform(@NotNull Transform transform) {
this.position = transform.translation().toArray();
this.scale = transform.scale().toArray();
this.rotation = transform.rotation().toArray();
public DMFTransform(@NotNull Matrix4dc matrix) {
final Vector3d translation = matrix.getTranslation(new Vector3d());
final Vector3d scale = matrix.getScale(new Vector3d());
final Quaterniond rotation = matrix.getUnnormalizedRotation(new Quaterniond());
this.position = new double[]{translation.x(), translation.y(), translation.z()};
this.scale = new double[]{scale.x(), scale.y(), scale.z()};
this.rotation = new double[]{rotation.x(), rotation.y(), rotation.z(), rotation.w()};
}

public DMFTransform(@NotNull Matrix4x4 matrix) {
this(matrix.toTranslation(), matrix.toScale(), matrix.toQuaternion());
public DMFTransform(@NotNull Vector3dc translation, @NotNull Vector3dc scale, @NotNull Quaterniondc rotation) {
this.position = new double[]{translation.x(), translation.y(), translation.z()};
this.scale = new double[]{scale.x(), scale.y(), scale.z()};
this.rotation = new double[]{rotation.x(), rotation.y(), rotation.z(), rotation.w()};
}

@Override
Expand Down
Loading

0 comments on commit 257de27

Please sign in to comment.