Public
Edited
Dec 29, 2022
Insert cell
Insert cell
cubeRig = FileAttachment("cubeRigAssimpDAE.json").json()
Insert cell
vertCount = 216
Insert cell
numBones = 4
Insert cell
Insert cell
Insert cell
jointArray = []
Insert cell
weightArrays = createWeightArrays(weightObjects, vertCount)
Insert cell
jointChain = cubeRig.rootnode.children[1]
Insert cell
boneCopy = cubeRig.meshes[0].bones
Insert cell
weightObjects = createWeightObjects(boneCopy)
Insert cell
function createWeightObjects(boneArray) {
let weights = []
for(let i = 0; i < boneArray.length; i++){
for(let j = 0; j < boneArray[i].weights.length; j++){
boneArray[i].weights[j].push(i);
weights.push(
//push new Weight object
Weights(
boneArray[i].weights[j][0], //vert
boneArray[i].weights[j][1], //weight
i //joint
)
)
}
}
return weights
}
Insert cell
Insert cell
function Weights(vert, weight, joint) {
return {
vert: vert,
weight: weight,
joint: joint
}
}
Insert cell
function createWeightArrays(weights, vertCount) {
let weightArr = []
let weightIndices = []
for(let i = 0; i < vertCount; i++){
let vertWeights = weights.filter(weights => weights.vert === i);
for(let j = 0; j < 4; j++){
if(vertWeights[j] === undefined){
weightArr.push(0);
weightIndices.push(0);
}else{
weightArr.push(vertWeights[j].weight);
weightIndices.push(vertWeights[j].joint);
}
}
}
return{
weights: weightArr,
weightIndices: weightIndices
}
}
Insert cell
function Joint(joint, parent) {
let currentJoint =
(
{
index: null,
name: joint.name,
index: null,
parent: parent,
parentIndex: null,
localMatrix: joint.transformation,
worldMatrix: m4.identity(),
inverseBindMatrix: m4.identity(),
}
)
return currentJoint;
}
Insert cell
function processJoints(joint, parent, jointArray) {
jointArray.push(Joint(joint, parent));
if(joint.children){
let parentName = joint.name;
joint.children.forEach(child => {
processJoints(child, parentName, jointArray);
})
}
}
Insert cell
function setJointIndices(jointArray, boneArray) {
jointArray.forEach(joint =>{
//boneIndex is in the official bone order
let boneIndex = boneArray.findIndex(bone => bone.name === joint.name);
//parentIndex is the index of the parent in the flat jointArray
let parentIndex = jointArray.findIndex(jnt => jnt.name === joint.parent);
joint.index = boneIndex;
joint.parentIndex = parentIndex;
})
}
Insert cell
function updateWorldMatrices(jointArray) {
for(let i = 0; i < numBones; i++){
if(jointArray[i].parentIndex != -1){
m4.multiply(
jointArray[jointArray[i].parentIndex].worldMatrix,
jointArray[i].localMatrix,
jointArray[i].worldMatrix //dst
)
} else {
// m4.copy(jointArray[i].localMatrix, jointArray[i].worldMatrix)
m4.multiply(
rootTransformation,
jointArray[i].localMatrix,
jointArray[i].worldMatrix //dst
)
}
}
}
Insert cell
function calculateInverseBindMatrices(jointArray) {
for(let i = 0; i < numBones; i++){
m4.inverse(jointArray[i].worldMatrix, jointArray[i].inverseBindMatrix);
}
}
Insert cell
{
processJoints(jointChain, null, jointArray);
setJointIndices(jointArray, boneCopy);
updateWorldMatrices(jointArray);
calculateInverseBindMatrices(jointArray);
}
Insert cell
Insert cell
twgl = require("twgl.js")
Insert cell
m4 = twgl.m4
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more