Public
Edited
Dec 6, 2022
Fork of twgl cubes
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
indices = cube.scene.children[1].geometry.index.array
Insert cell
positions = cube.scene.children[1].geometry.attributes.position.array//num components 3
Insert cell
normals = cube.scene.children[1].geometry.attributes.normal.array //num components 3
Insert cell
uvs = cube.scene.children[1].geometry.attributes.uv.array //num components 2
Insert cell
skinWeights = cube.scene.children[1].geometry.attributes.skinWeight.array //num components 4
Insert cell
skinIndices = cube.scene.children[1].geometry.attributes.skinIndex.array //num components 4
Insert cell
Insert cell
gl = {
const myCanvas = DOM.canvas(width, 480);
const gl = myCanvas.getContext("webgl2");
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.SCISSOR_TEST);
gl.clearColor(.8,.8,1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
return gl;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
programInfoDiffuse = {
errorBlock.style.height = "20px";
errorBlock.innerHTML = "Program Shader compilation successful";
return twgl.createProgramInfo(gl, [shadersDiffuse.vs, shadersDiffuse.fs], (message) => {
errorBlock.style.height = "400px";
errorBlock.innerHTML = "Program Shader compilation error\n" + message;
});
}
Insert cell
Insert cell
shadersSkin = ({
vs: `#version 300 es
precision mediump float;
in vec3 position;
in vec3 normal;
in vec4 skinWeights;
in uvec4 skinIndices;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 bonesMatrix[4];
out vec3 fragNormal;
out vec3 fragPosition;
void main () {

mat4 skinMatrix = (
skinWeights.x * bonesMatrix[int(skinIndices.x)] +
skinWeights.y * bonesMatrix[int(skinIndices.y)] +
skinWeights.z * bonesMatrix[int(skinIndices.z)] +
skinWeights.w * bonesMatrix[int(skinIndices.w)]
);

vec4 newPosition = modelMatrix*skinMatrix*vec4(position,1);
fragPosition = newPosition.xyz;

gl_Position = projectionMatrix*viewMatrix*modelMatrix*skinMatrix*vec4(position,1);
mat4 normalMatrix = transpose(inverse(modelMatrix));
fragNormal = normalize((normalMatrix*vec4(normal,0)).xyz);
}`,

fs: `#version 300 es
precision mediump float;
in vec3 fragNormal;
in vec3 fragPosition;

uniform vec4 light;
uniform vec4 material;

out vec4 outColor;
void main () {
vec3 N = normalize(fragNormal);
vec3 L;
if(light.w == 0.0){
L = normalize(light.xyz);
}else{
L = normalize(light.xyz - fragPosition);
}

vec3 color = material.rgb * clamp(dot(N,L), 0.0, 1.0);//Compute color
// vec3 color = vec3(1,1,1);
outColor = vec4(color, material.a);
// outcolor = vec4(material.rgba);

}`
});
Insert cell
Insert cell
Insert cell
Insert cell
bufferInfo = twgl.createBufferInfoFromArrays(gl, vertexAttributes);
Insert cell
sphereBufferInfo = twgl.primitives.createCubeBufferInfo(gl, .08)
Insert cell
lookAtPosition = [0,1,0]
Insert cell
eyePosition = [0,0,10]
Insert cell
transformedEyePosition = m4.transformPoint(m4.multiply(m4.rotationY(viewParameters.yAngle*Math.PI/180),m4.rotationX(viewParameters.xAngle*Math.PI/180)), eyePosition)
Insert cell
Insert cell
uniforms = ({
light: [1,1,3,0],
projectionMatrix: m4.perspective(viewParameters.fov * Math.PI/180, gl.canvas.width/gl.canvas.height, 0.1,20),
viewMatrix: m4.inverse( m4.lookAt(transformedEyePosition, lookAtPosition, [0,1,0])),
modelMatrix: m4.identity(),
eyePosition: eyePosition,
material: [.5, .5, .5, 1],
bonesMatrix: bonesUniformFlat
})
Insert cell
Insert cell
modelMatrix1 = composeMatrix([0,0,0],[0,0,0],[1,1,1])
Insert cell
uniforms1 = ({
light: [1,1,3,0],
projectionMatrix: m4.perspective(viewParameters.fov * Math.PI/180, gl.canvas.width/gl.canvas.height, 0.1,20),
viewMatrix: m4.inverse( m4.lookAt(transformedEyePosition, lookAtPosition, [0,1,0])),
modelMatrix: jointArray[0].worldMatrix,
eyePosition: eyePosition,
material: [1, 0, 0, .5],
})
Insert cell
### Joint2
Insert cell
modelMatrix2 = composeMatrix([0,.1,0],[0,0,0],[1,1,1])
Insert cell
uniforms2 = ({
light: [1,1,3,0],
projectionMatrix: m4.perspective(viewParameters.fov * Math.PI/180, gl.canvas.width/gl.canvas.height, 0.1,20),
viewMatrix: m4.inverse( m4.lookAt(transformedEyePosition, lookAtPosition, [0,1,0])),
modelMatrix: jointArray[1].worldMatrix,
eyePosition: eyePosition,
material: [0, 1, 0, 0.5],
})
Insert cell
Insert cell
modelMatrix3 = composeMatrix([0,.2,0],[0,0,0],[1,1,1])
Insert cell
uniforms3 = ({
light: [1,1,3,0],
projectionMatrix: m4.perspective(viewParameters.fov * Math.PI/180, gl.canvas.width/gl.canvas.height, 0.1,20),
viewMatrix: m4.inverse( m4.lookAt(transformedEyePosition, lookAtPosition, [0,1,0])),
modelMatrix: jointArray[2].worldMatrix,
eyePosition: eyePosition,
material: [0, 0, 1, 0.5],
})
Insert cell
Insert cell
modelMatrix4 = composeMatrix([0,.3,0],[0,0,0],[1,1,1])
Insert cell
uniforms4 = ({
light: [1,1,3,0],
projectionMatrix: m4.perspective(viewParameters.fov * Math.PI/180, gl.canvas.width/gl.canvas.height, 0.1,20),
viewMatrix: m4.inverse( m4.lookAt(transformedEyePosition, lookAtPosition, [0,1,0])),
modelMatrix: jointArray[3].worldMatrix,
eyePosition: eyePosition,
material: [1, 1, 1, 0.5],
})
Insert cell
Insert cell
jointArray =
[
({
name: "joint1",
parentId: -1,
localMatrix: jointList[0].localMatrix,
worldMatrix: m4.identity(),
inverseBindMatrix: jointList[0].inverseBindMatrix
}),
({
name: "joint2",
parentId: 0,
localMatrix: jointList[1].localMatrix,
worldMatrix: m4.identity(),
inverseBindMatrix: jointList[1].inverseBindMatrix
}),
({
name: "joint3",
parentId: 1,
localMatrix: jointList[2].localMatrix,
worldMatrix: m4.identity(),
inverseBindMatrix: jointList[2].inverseBindMatrix
}),
({
name: "joint4",
parentId: 2,
localMatrix: jointList[3].localMatrix,
worldMatrix: m4.identity(),
inverseBindMatrix: jointList[3].inverseBindMatrix
})
]
Insert cell
updateWorldMatrices(jointArray)
Insert cell
Insert cell
bonesUniform = [
m4.identity(),
m4.identity(),
m4.identity(),
m4.identity()
]
Insert cell
bonesUniformFlat = []
Insert cell
function flattenBonesUniform() {
bonesUniformFlat.splice(0,bonesUniform.length);
for(let i = 0; i < numBones; i++){
for(let j = 0; j < 16; j++){
bonesUniformFlat.push(bonesUniform[i][j])
}
}
}
Insert cell
flattenBonesUniform()
Insert cell
function flatArray(arr) {
let newArray = [];

for (let i = 0; i < arr.length; i++) {
const element = arr[i];

if (Array.isArray(element)) {
// recursive call
newArray = newArray.concat(flatArray(element));
} else {
newArray.push(element);
}
}

return newArray;
}
Insert cell
Insert cell
numFrames = 24;
Insert cell
joint1Tracks = ({
positions: cube.animations[0].tracks[0].values,
quaternions: cube.animations[0].tracks[1].values,
next: 0
})
Insert cell
joint2Tracks = ({
positions: cube.animations[0].tracks[3].values,
quaternions: cube.animations[0].tracks[4].values,
next: 0
})
Insert cell
joint3Tracks = ({
positions: cube.animations[0].tracks[6].values,
quaternions: cube.animations[0].tracks[7].values,
next: 0
})
Insert cell
joint4Tracks = ({
positions: cube.animations[0].tracks[9].values,
quaternions: cube.animations[0].tracks[10].values,
next: 0
})
Insert cell
function getNextMatrix(jointTrack) {
//get T [x,y,z]
let T =
[
jointTrack.positions[jointTrack.next],
jointTrack.positions[jointTrack.next + 1],
jointTrack.positions[jointTrack.next + 2]
]

//get R [x,y,z,w]
let R =
[
jointTrack.quaternions[jointTrack.next],
jointTrack.quaternions[jointTrack.next + 1],
jointTrack.quaternions[jointTrack.next + 2],
jointTrack.quaternions[jointTrack.next + 3]
]

//composeMatrixQuat
let matrix = composeMatrixQuat(T, R, [1,1,1]);

//increment next
jointTrack.next++;
if(jointTrack.next > numFrames + 1){
jointTrack.next = 0;
}
return matrix;
}
Insert cell
function updatePose() {
let temp = getNextMatrix(joint1Tracks)
m4.copy(temp, jointArray[0].localMatrix);
temp = getNextMatrix(joint2Tracks)
m4.copy(temp, jointArray[1].localMatrix);
temp = getNextMatrix(joint3Tracks)
m4.copy(temp, jointArray[2].localMatrix);
temp = getNextMatrix(joint4Tracks)
m4.copy(temp, jointArray[3].localMatrix);
}
Insert cell
Insert cell
cube = {
const gltfLoader = new THREE.GLTFLoader();
const blob = await FileAttachment("cubeRig4Joint.glb").blob();
const url = URL.createObjectURL(blob);

const dracoLoader = new THREE.DRACOLoader();
dracoLoader.setDecoderPath("https://www.gstatic.com/draco/v1/decoders/")
gltfLoader.setDRACOLoader( dracoLoader );

const gltf = await new Promise( resolve => gltfLoader.load(url, gltf => resolve(gltf) ));
const cube = gltf;

return cube;
}
Insert cell
Insert cell
cubeSkeleton = cube.scene.children[1].skeleton
Insert cell
cubeInverseBindMatrices = cube.scene.children[1].skeleton.boneInverses
Insert cell
Insert cell
Insert cell
Insert cell
twgl = require("twgl.js")
Insert cell
m4 = twgl.m4;
Insert cell
import {columns} from "@bcardiff/observable-columns"
Insert cell
import {slider, radio} from "@jashkenas/inputs"
Insert cell
import {node, composeMatrix, composeMatrixQuat, degToRad} from "@dboyd/scene-graph-functions"
Insert cell
THREE = {
const THREE = window.THREE = await require('three');
await require('three/examples/js/loaders/GLTFLoader.js').catch(() => {});
await require('three/examples/js/loaders/DRACOLoader.js').catch(() => {});
return THREE;
}
Insert cell
Insert cell
function updateWorldMatrices(jointArray) {
for(let i = 0; i < numBones; i++){
if(jointArray[i].parentId != -1){
m4.multiply(
jointArray[jointArray[i].parentId].worldMatrix,
jointArray[i].localMatrix,
jointArray[i].worldMatrix //dst
)
} else {
m4.copy(jointArray[i].localMatrix, jointArray[i].worldMatrix)
}
}
}
Insert cell
function updateBonesUniform()
{
for(let i = 0; i < numBones; i++){
m4.multiply(jointArray[i].worldMatrix, jointArray[i].inverseBindMatrix, bonesUniform[i])
}
}
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