Public
Edited
Dec 4, 2022
Fork of gltf load?
Insert cell
Insert cell
Insert cell
Insert cell
viewof transformParameters = columns({
xRotate: slider({
min: -360,
max: 360,
step: 1,
value: 0,
title: "Rotate X",
description: ""
}),
xAngle: slider({
min: -89,
max: 89,
step: 1,
value: 0,
title: "Rotation Around X-axis degrees",
description: "Camera Orbiting around the scene center."
}),
yAngle : slider({
min: -180,
max: 180,
step: 1,
value: 0,
title: "Rotation around Y-axis degrees",
description: "Camera Orbiting around the scene center."
}),
fov: slider({
min: 15,
max: 120,
step: 1,
value: 45,
title: "Vertical FOV Degrees",
})
})
Insert cell
Insert cell
Insert cell
indices = cube.scene.children[2].geometry.index.array
Insert cell
positions = cube.scene.children[2].geometry.attributes.position.array//num components 3
Insert cell
normals = cube.scene.children[2].geometry.attributes.normal.array //num components 3
Insert cell
uvs = cube.scene.children[2].geometry.attributes.uv.array //num components 2
Insert cell
skinWeights = cube.scene.children[2].geometry.attributes.skinWeight.array //num components 4
Insert cell
skinIndices = cube.scene.children[2].geometry.attributes.skinIndex.array //num components 4
Insert cell
Insert cell
gl = {
const myCanvas = DOM.canvas(720, 480);
const gl = myCanvas.getContext("webgl2");
gl.enable(gl.DEPTH_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
shaders = ({
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 bones[3];
out vec3 fragNormal;
out vec3 fragPosition;
void main () {
vec4 newPosition =
(
bones[skinIndices[0]] * vec4(position,1.0) * skinWeights[0] +
bones[skinIndices[1]] * vec4(position,1.0) * skinWeights[1] +
bones[skinIndices[2]] * vec4(position,1.0) * skinWeights[2] +
bones[skinIndices[3]] * vec4(position,1.0) * skinWeights[3]
);
fragPosition = newPosition.xyz;
gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4(position,1);
mat4 normalMatrix = transpose(inverse(modelMatrix));
fragNormal = normalize((normalMatrix*vec4(normal,0)).xyz);

// gl_Position = projectionMatrix * viewMatrix * newPosition;
}`,

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);

}`
});
Insert cell
errorBlock = html`<textarea style="height : 20px; width : ${width}px; font-size: 0.8em; display: block"></textarea>`
Insert cell
Insert cell
Insert cell
bufferInfo = twgl.createBufferInfoFromArrays(gl, vertexAttributes);
Insert cell
Insert cell
miniCubeBufferInfo = twgl.primitives.createCubeBufferInfo(gl,2)
Insert cell
lookAtPosition = [0,0,0]
Insert cell
eyePosition = [-3.37,6.47,1.29]
Insert cell
transformedEyePosition = m4.transformPoint(m4.multiply(m4.rotationY(viewParameters.yAngle*Math.PI/180),m4.rotationX(viewParameters.xAngle*Math.PI/180)), eyePosition)
Insert cell
fov = 55;
Insert cell
modelMatrix = m4.identity();
Insert cell
transformedMatrix = composeMatrixQuat(cubeJointListFlat[0].position,cubeJointListFlat[0].rotationQuat,[1,1,1])
Insert cell
rotateMatrix = m4.rotationZ(degToRad(transformParameters.xRotate))
Insert cell
m4.multiply(transformedMatrix, rotateMatrix, transformedMatrix)
Insert cell
m4.copy(transformedMatrix, modelMatrix)
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.multiply(transformedMatrix, m4.rotationZ(degToRad(transformParameters.xRotate))),
eyePosition: eyePosition,
material: [1, 1, 1, 0.5],
bones: bonesUniform
})
Insert cell
uniformsMiniCube01 = ({
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: [1, 1, 1, 0.5],
// bones: bonesUniform
})
Insert cell
Insert cell
cube = {
const gltfLoader = new THREE.GLTFLoader();
const blob = await FileAttachment("cubeRigNoScale002.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[2].skeleton
Insert cell
cubeInverseBindMatrices = cube.scene.children[2].skeleton.boneInverses

Insert cell
cubeJointListFlat = {
const cubeJointListFlat = []
const numBones = 3;
for(let i = 0; i < numBones; i++){
const currentJoint = createJoint(cubeSkeleton, cubeInverseBindMatrices, i);
cubeJointListFlat.push(currentJoint);
}
return cubeJointListFlat;
}
Insert cell
Insert cell
bonesUniform = [
m4.identity(),
m4.identity(),
m4.identity()
]
Insert cell
Insert cell
miniCubeURL = await FileAttachment("miniCube.obj").url()
Insert cell
miniCubeObj = loadModelFromURL(miniCubeURL, "obj")
Insert cell
Insert cell
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
twgl = require("twgl.js")
Insert cell
m4 = twgl.m4;
Insert cell
import {slider, radio} from "@jashkenas/inputs"
Insert cell
import {columns} from "@bcardiff/observable-columns"
Insert cell
import {node, composeMatrix, composeMatrixQuat, degToRad} from "@dboyd/scene-graph-functions"
Insert cell
import {loadModelFromURL, computeModelExtent} from "@spattana/model-loaders-using-threejs"
Insert cell
function getParentIndex(joint, jointList)
{
for(let i = 0; i < 3; i++){
if(jointList[i].name == joint.futureParent){
return jointList[i].index;
} else {
return null;
}
}
}

Insert cell
function createJoint(skeleton, inverseBindMatrices, i) {
let parent = null;
if(skeleton.bones[i].parent.type == "Bone"){
parent = skeleton.bones[i].parent.name;
}
let currentJoint = ({
index: i,
name: skeleton.bones[i].name,
futureParent: parent,
parent: null,
children: [],
position:
[
cubeSkeleton.bones[i].position.x,
cubeSkeleton.bones[i].position.y,
cubeSkeleton.bones[i].position.z
],
rotation:
[
cubeSkeleton.bones[i].rotation._x,
cubeSkeleton.bones[i].rotation._y,
cubeSkeleton.bones[i].rotation._z
],
rotationQuat:
[
cubeSkeleton.bones[i].quaternion._x,
cubeSkeleton.bones[i].quaternion._y,
cubeSkeleton.bones[i].quaternion._z,
cubeSkeleton.bones[i].quaternion._w
],
scale: [1,1,1],
localMatrix: m4.identity(),
worldMatrix: m4.identity(),
inverseBindMatrix: cubeInverseBindMatrices[i].elements
})

composeMatrixQuat(currentJoint.position, currentJoint.rotationQuat, currentJoint.scale, currentJoint.localMatrix);

return currentJoint;

}
Insert cell
function createJointTree(inputJointList)
{
let jointList = inputJointList;
for(let i = 0; i < jointList.length; i++){
if(getParentIndex(jointList[i], jointList)){
jointList[getParentIndex(jointList[i], jointList)].children.push(jointList[i])
}
}
return jointList[0]
}
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