cleanup unused, added scale matrix to scene layouts

This commit is contained in:
Harvey Fong 2025-04-01 11:31:07 -06:00
parent e1c2743bf8
commit 2a9ba11350
2 changed files with 28 additions and 106 deletions

View File

@ -20,75 +20,11 @@ using json = nlohmann::json;
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "thirdparty/stb_image.h" // STB Image library #include "thirdparty/stb_image.h" // STB Image library
struct VmaxVector3 {
double x, y, z;
};
// Converts axis-angle rotation to Euler angles (in XYZ order)
// Parameters:
// ax, ay, az: The axis vector to rotate around (doesn't need to be normalized)
// angle: The angle to rotate by (in radians)
// Returns: Vector3 containing Euler angles (x=pitch, y=yaw, z=roll) in radians
VmaxVector3 axisAngleToEulerXYZ(double ax, double ay, double az, double angle) {
// First normalize the axis
double length = sqrt(ax*ax + ay*ay + az*az);
if (length != 0) {
ax /= length;
ay /= length;
az /= length;
}
// Compute sin and cos of angle
double s = sin(angle);
double c = cos(angle);
double t = 1.0 - c;
// Build rotation matrix from axis-angle
// This is the Rodrigues' rotation formula
double m11 = t*ax*ax + c;
double m12 = t*ax*ay - s*az;
double m13 = t*ax*az + s*ay;
double m21 = t*ax*ay + s*az;
double m22 = t*ay*ay + c;
double m23 = t*ay*az - s*ax;
double m31 = t*ax*az - s*ay;
double m32 = t*ay*az + s*ax;
double m33 = t*az*az + c;
// Convert rotation matrix to euler angles
VmaxVector3 euler;
// Handle gimbal lock cases
if (m13 > 0.998) { // singularity at north pole
euler.y = atan2(m12, m22);
euler.x = M_PI/2;
euler.z = 0;
}
else if (m13 < -0.998) { // singularity at south pole
euler.y = atan2(m12, m22);
euler.x = -M_PI/2;
euler.z = 0;
}
else {
euler.x = asin(-m13);
euler.y = atan2(m23, m33);
euler.z = atan2(m12, m11);
}
return euler;
}
// Structure to represent a 4x4 matrix for 3D transformations // Structure to represent a 4x4 matrix for 3D transformations
// The matrix is stored as a 2D array where m[i][j] represents row i, column j // The matrix is stored as a 2D array where m[i][j] represents row i, column j
struct VmaxMatrix4x4 { struct VmaxMatrix4x4 {
double m[4][4]; double m[4][4];
// Constructor: Creates an identity matrix (1's on diagonal, 0's elsewhere) // Constructor: Creates an identity matrix (1's on diagonal, 0's elsewhere)
// This is the default starting point for any transformation
VmaxMatrix4x4() { VmaxMatrix4x4() {
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) { for(int j = 0; j < 4; j++) {
@ -101,7 +37,6 @@ struct VmaxMatrix4x4 {
// Returns: A new matrix that represents the combined transformation // Returns: A new matrix that represents the combined transformation
VmaxMatrix4x4 operator*(const VmaxMatrix4x4& other) const { VmaxMatrix4x4 operator*(const VmaxMatrix4x4& other) const {
VmaxMatrix4x4 result; VmaxMatrix4x4 result;
// Perform matrix multiplication // Perform matrix multiplication
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) { for(int j = 0; j < 4; j++) {
@ -419,17 +354,13 @@ inline std::vector<VmaxVoxel> decodeVoxels(const std::vector<uint8_t>& dsData, i
uint8_t material; uint8_t material;
uint8_t color; uint8_t color;
for (int i = 0; i < dsData.size() - 1; i += 2) { for (int i = 0; i < dsData.size() - 1; i += 2) {
//dsVoxel _vxVoxel; // VoxelMax data [todo] - should I use uint8_t for x, y, z?
material = dsData[i]; // also known as a layer color material = dsData[i]; // also known as a layer color
//_vxVoxel.material = static_cast<int>(dsData[i]); // also known as a layer color
color = dsData[i + 1]; color = dsData[i + 1];
//_vxVoxel.color = static_cast<uint8_t>(dsData[i + 1]);
uint32_t _tempx, _tempy, _tempz; uint32_t _tempx, _tempy, _tempz;
decodeMorton3DOptimized(i/2 + mortonOffset, decodeMorton3DOptimized(i/2 + mortonOffset,
_tempx, _tempx,
_tempy, _tempy,
_tempz); // index IS the morton code _tempz); // index IS the morton code
//std::cout << "i: " << i << " _tempx: " << _tempx << " _tempy: " << _tempy << " _tempz: " << _tempz << std::endl;
if (color != 0) { if (color != 0) {
VmaxVoxel voxel = { VmaxVoxel voxel = {
static_cast<uint8_t>(_tempx), static_cast<uint8_t>(_tempx),
@ -442,7 +373,6 @@ inline std::vector<VmaxVoxel> decodeVoxels(const std::vector<uint8_t>& dsData, i
}; };
voxels.push_back(voxel); voxels.push_back(voxel);
} }
} }
return voxels; return voxels;
} }
@ -698,7 +628,7 @@ struct JsonModelInfo {
std::string name; std::string name;
std::string dataFile; // The .vmaxb file std::string dataFile; // The .vmaxb file
std::string paletteFile; // The palette PNG std::string paletteFile; // The palette PNG
std::string historyFile; // The history file std::string historyFile; // The history file, not sure what this is
// Transform information // Transform information
std::vector<double> position; // t_p std::vector<double> position; // t_p
@ -878,7 +808,7 @@ public:
for (const auto& [file, count] : modelFiles) { for (const auto& [file, count] : modelFiles) {
std::cout << " " << file << " (used " << count << " times)" << std::endl; std::cout << " " << file << " (used " << count << " times)" << std::endl;
} }
/*
std::cout << "\nGroups:" << std::endl; std::cout << "\nGroups:" << std::endl;
for (const auto& [id, group] : groups) { for (const auto& [id, group] : groups) {
std::cout << " " << group.name << " (ID: " << id << ")" << std::endl; std::cout << " " << group.name << " (ID: " << id << ")" << std::endl;
@ -903,15 +833,6 @@ public:
<< model.position[1] << ", " << model.position[1] << ", "
<< model.position[2] << "]" << std::endl; << model.position[2] << "]" << std::endl;
} }
if (!model.rotation.empty()) {
VmaxVector3 VmaxEuler = axisAngleToEulerXYZ(model.rotation[0], model.rotation[1], model.rotation[2], model.rotation[3]);
std::cout << " Rotation: ["
<< VmaxEuler.x << ", "
<< VmaxEuler.y << ", "
<< VmaxEuler.z << "]" << std::endl;
} }
} }
*/
}
}; };

View File

@ -235,16 +235,25 @@ int DL_main(dl::Args& args) {
belGroupUUID = belGroupUUID.replace("-", "_"); // Make sure the group name is valid for a Bella node name belGroupUUID = belGroupUUID.replace("-", "_"); // Make sure the group name is valid for a Bella node name
belGroupUUID = "_" + belGroupUUID; // Make sure the group name is valid for a Bella node name belGroupUUID = "_" + belGroupUUID; // Make sure the group name is valid for a Bella node name
belGroupNodes[belGroupUUID] = belScene.createNode("xform", belGroupUUID, belGroupUUID); // Create a Bella node for the group belGroupNodes[belGroupUUID] = belScene.createNode("xform", belGroupUUID, belGroupUUID); // Create a Bella node for the group
// Rotate the object
VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( groupInfo.rotation[0], VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( groupInfo.rotation[0],
groupInfo.rotation[1], groupInfo.rotation[1],
groupInfo.rotation[2], groupInfo.rotation[2],
groupInfo.rotation[3]); groupInfo.rotation[3]);
// Translate the object
VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4(); VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4();
//std::vector<double> translation = extentCenter-position;
objectTransMat4 = objectTransMat4.createTranslation(groupInfo.position[0], objectTransMat4 = objectTransMat4.createTranslation(groupInfo.position[0],
groupInfo.position[1], groupInfo.position[1],
groupInfo.position[2]); groupInfo.position[2]);
objectMat4 = objectMat4 * objectTransMat4;
// Scale the object
VmaxMatrix4x4 objectScaleMat4 = VmaxMatrix4x4();
objectScaleMat4 = objectScaleMat4.createScale(groupInfo.scale[0],
groupInfo.scale[1],
groupInfo.scale[2]);
objectMat4 = objectScaleMat4 * objectMat4 * objectTransMat4;
belGroupNodes[belGroupUUID]["steps"][0]["xform"] = dl::Mat4({ belGroupNodes[belGroupUUID]["steps"][0]["xform"] = dl::Mat4({
objectMat4.m[0][0], objectMat4.m[0][1], objectMat4.m[0][2], objectMat4.m[0][3], objectMat4.m[0][0], objectMat4.m[0][1], objectMat4.m[0][2], objectMat4.m[0][3],
@ -298,28 +307,19 @@ int DL_main(dl::Args& args) {
std::vector<double> scale = jsonModelInfo.scale; std::vector<double> scale = jsonModelInfo.scale;
std::vector<double> extentCenter = jsonModelInfo.extentCenter; std::vector<double> extentCenter = jsonModelInfo.extentCenter;
//what is this for? // Rotate the object
/*
auto jsonParentId = jsonModelInfo.parentId;
auto belParentId = dl::String(jsonParentId.c_str());
dl::String belParentGroupUUID = belParentId.replace("-", "_");
if (jsonParentId != "") {
belGroupNodes[belParentGroupUUID].parentTo(belWorld);
}
*/
VmaxMatrix4x4 modelMatrix = axisAngleToMatrix4x4(rotation[0], rotation[1], rotation[2], rotation[3]); VmaxMatrix4x4 modelMatrix = axisAngleToMatrix4x4(rotation[0], rotation[1], rotation[2], rotation[3]);
// Translate the object
VmaxMatrix4x4 transMatrix = VmaxMatrix4x4(); VmaxMatrix4x4 transMatrix = VmaxMatrix4x4();
//std::vector<double> translation = extentCenter-position;
//transMatrix = transMatrix.createTranslation(extentCenter[0]-position[0], extentCenter[1]-position[1], extentCenter[2]-position[2]);
transMatrix = transMatrix.createTranslation(position[0], transMatrix = transMatrix.createTranslation(position[0],
position[1], position[1],
position[2]); position[2]);
modelMatrix = transMatrix*modelMatrix; VmaxMatrix4x4 scaleMatrix = VmaxMatrix4x4();
//std::cout << modelMatrix.m[0][0] << "," << modelMatrix.m[0][1] << "," << modelMatrix.m[0][2] << "," << modelMatrix.m[0][3] << std::endl; scaleMatrix = scaleMatrix.createScale(scale[0],
//std::cout << modelMatrix.m[1][0] << "," << modelMatrix.m[1][1] << "," << modelMatrix.m[1][2] << "," << modelMatrix.m[1][3] << std::endl; scale[1],
//std::cout << modelMatrix.m[2][0] << "," << modelMatrix.m[2][1] << "," << modelMatrix.m[2][2] << "," << modelMatrix.m[2][3] << std::endl; scale[2]);
//std::cout << modelMatrix.m[3][0] << "," << modelMatrix.m[3][1] << "," << modelMatrix.m[3][2] << "," << modelMatrix.m[3][3] << std::endl; modelMatrix = scaleMatrix * modelMatrix * transMatrix;
// Get file names // Get file names
dl::String materialName = vmaxDirName + "/" + jsonModelInfo.paletteFile.c_str(); dl::String materialName = vmaxDirName + "/" + jsonModelInfo.paletteFile.c_str();
@ -410,7 +410,6 @@ int DL_main(dl::Args& args) {
dl::String canonicalName = getCanonicalName.replace(".vmaxb", ""); dl::String canonicalName = getCanonicalName.replace(".vmaxb", "");
//get bel node from canonical name //get bel node from canonical name
auto belCanonicalNode = belCanonicalNodes[canonicalName.buf()]; auto belCanonicalNode = belCanonicalNodes[canonicalName.buf()];
// create a new xform
auto foofoo = belScene.findNode(canonicalName); auto foofoo = belScene.findNode(canonicalName);
VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( rotation[0], VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( rotation[0],
@ -418,14 +417,16 @@ int DL_main(dl::Args& args) {
rotation[2], rotation[2],
rotation[3]); rotation[3]);
VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4(); VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4();
//std::vector<double> translation = extentCenter-position;
/*objectTransMat4 = objectTransMat4.createTranslation(extentCenter[0]-position[0],
extentCenter[1]-position[1],
extentCenter[2]-position[2]);*/
objectTransMat4 = objectTransMat4.createTranslation(position[0], objectTransMat4 = objectTransMat4.createTranslation(position[0],
position[1], position[1],
position[2]); position[2]);
objectMat4 = objectMat4 * objectTransMat4;
VmaxMatrix4x4 objectScaleMat4 = VmaxMatrix4x4();
objectScaleMat4 = objectScaleMat4.createScale(scale[0],
scale[1],
scale[2]);
objectMat4 = objectScaleMat4 * objectMat4 * objectTransMat4;
auto belNodeObjectInstance = belScene.createNode("xform", belObjectId, belObjectId); auto belNodeObjectInstance = belScene.createNode("xform", belObjectId, belObjectId);
belNodeObjectInstance["steps"][0]["xform"] = dl::Mat4({ belNodeObjectInstance["steps"][0]["xform"] = dl::Mat4({