collada-dae-parser
Advanced tools
Comparing version 0.8.0 to 0.9.0
var fs = require('fs') | ||
var dae2json = require('../../../') | ||
var initShaders = require('../shader/init-shader.js') | ||
var expandVertices = require('./expand-vertices.js') | ||
var drawModel = require('./draw-model.js') | ||
module.exports = LoadModel | ||
// TODO: clean up | ||
function LoadModel (gl, callback) { | ||
function LoadModel (gl, opts) { | ||
// TODO: Read using xhr request | ||
var parsedDae = dae2json(fs.readFileSync('./demo/assets/animated-male-figure.dae')) | ||
var parsedDae = dae2json(fs.readFileSync('./demo/assets/collada-demo-animated-male.dae')) | ||
var vertexData = expandVertices(parsedDae) | ||
// Vertex normals | ||
// TODO: Comment this | ||
var vertexNormals = [] | ||
// TODO: naming | ||
var vertexJointAffectors = [] | ||
var vertexJointWeights = [] | ||
/* | ||
parsedDae.vertexJointWeights.forEach(function (jointsAndWeights) { | ||
for (var i = 0; i < 4; i++) { | ||
var jointIndex = Object.keys(jointsAndWeights)[i] | ||
vertexJointAffectors.push(Number(jointIndex) || 0) | ||
vertexJointWeights.push(jointsAndWeights[jointIndex] || 0) | ||
} | ||
}) | ||
*/ | ||
// TODO: Can probably make this more efficient by indexing duplicate index -> normal -> new tail end index | ||
// TODO: generally inefficient. Running calculations more than necessary. Still figuring out how to do this... | ||
// Throwing things in for now then optimize later | ||
var encounteredIndices = {} | ||
var vertexPositionIndices = [] | ||
var largestPositionIndex = 0 | ||
parsedDae.vertexPositionIndices.forEach(function (vertexPositionIndex, counter) { | ||
largestPositionIndex = Math.max(largestPositionIndex, vertexPositionIndex) | ||
if (!encounteredIndices[vertexPositionIndex]) { | ||
var jointsAndWeights = parsedDae.vertexJointWeights[vertexPositionIndex] | ||
// First time seeing the vertex position index | ||
vertexPositionIndices[counter] = vertexPositionIndex | ||
for (var i = 0; i < 4; i++) { | ||
if (i < 3) { | ||
vertexNormals[vertexPositionIndex * 3 + i] = parsedDae.vertexNormals[parsedDae.vertexNormalIndices[counter] * 3 + i] | ||
} | ||
var jointIndex = Object.keys(jointsAndWeights)[i] | ||
vertexJointAffectors[vertexPositionIndex * 4 + i] = Number(jointIndex) || 0 | ||
vertexJointWeights[vertexPositionIndex * 4 + i] = jointsAndWeights[jointIndex] || 0 | ||
} | ||
encounteredIndices[vertexPositionIndex] = true | ||
} | ||
}) | ||
parsedDae.vertexPositionIndices.forEach(function (vertexPositionIndex, counter) { | ||
if (encounteredIndices[vertexPositionIndex]) { | ||
vertexPositionIndices[counter] = ++largestPositionIndex | ||
var jointsAndWeights = parsedDae.vertexJointWeights[vertexPositionIndex] | ||
for (var i = 0; i < 4; i++) { | ||
if (i < 3) { | ||
parsedDae.vertexPositions[largestPositionIndex * 3 + i] = parsedDae.vertexPositions[vertexPositionIndex * 3 + i] | ||
vertexNormals[largestPositionIndex * 3 + i] = parsedDae.vertexNormals[parsedDae.vertexNormalIndices[counter] * 3 + i] | ||
} | ||
var jointIndex = Object.keys(jointsAndWeights)[i] | ||
vertexJointAffectors[largestPositionIndex * 4 + i] = Number(jointIndex) || 0 | ||
vertexJointWeights[largestPositionIndex * 4 + i] = jointsAndWeights[jointIndex] || 0 | ||
} | ||
} | ||
}) | ||
var vertexPositionBuffer = gl.createBuffer() | ||
@@ -73,3 +24,3 @@ gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer) | ||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexPositionIndexBuffer) | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexPositionIndices), gl.STATIC_DRAW) | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexData.vertexPositionIndices), gl.STATIC_DRAW) | ||
@@ -80,3 +31,3 @@ // Joints the affect each vertex | ||
gl.bindBuffer(gl.ARRAY_BUFFER, affectingJointIndexBuffer) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexJointAffectors), gl.STATIC_DRAW) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData.vertexJointAffectors), gl.STATIC_DRAW) | ||
@@ -87,18 +38,28 @@ // Weights of affecting joints | ||
gl.bindBuffer(gl.ARRAY_BUFFER, weightBuffer) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexJointWeights), gl.STATIC_DRAW) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData.vertexJointWeights), gl.STATIC_DRAW) | ||
var vertexNormalBuffer = gl.createBuffer() | ||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexNormalBuffer) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW) | ||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData.vertexNormals), gl.STATIC_DRAW) | ||
var stuff = { | ||
vertexNormalBuffer: vertexNormalBuffer, | ||
vertexPositionBuffer: vertexPositionBuffer, | ||
vertexPositionIndexBuffer: vertexPositionIndexBuffer, | ||
affectingJointIndexBuffer: affectingJointIndexBuffer, | ||
weightBuffer: weightBuffer, | ||
var shaderObj = initShaders(gl, { | ||
numJoints: vertexData.numJoints | ||
}) | ||
// Return our draw function and keyframes | ||
// TODO: Can/should we avoid returning keyframes? Wrap their usage in a service? | ||
return { | ||
draw: drawModel.bind(null, gl, { | ||
vertexNormalBuffer: vertexNormalBuffer, | ||
vertexPositionBuffer: vertexPositionBuffer, | ||
vertexPositionIndexBuffer: vertexPositionIndexBuffer, | ||
affectingJointIndexBuffer: affectingJointIndexBuffer, | ||
weightBuffer: weightBuffer, | ||
numElements: vertexData.vertexPositionIndices.length, | ||
shaderObj: shaderObj | ||
}), | ||
keyframes: parsedDae.keyframes, | ||
numElements: vertexPositionIndices.length | ||
// TODO: num joints has nothing to do with vertex data. parse this value elsewhere | ||
numJoints: vertexData.numJoints | ||
} | ||
callback(null, stuff) | ||
} |
@@ -5,6 +5,7 @@ var render = require('./render/render.js') | ||
var loadModel = require('./3d-model/load-model.js') | ||
var initShaders = require('./shader/init-shader.js') | ||
var SS = require('solid-state') | ||
var animate = require('./animate/animate.js') | ||
var initControls = require('./control/orbit-controls.js') | ||
var viewportResize = require('./viewport/viewport-resize.js') | ||
var initControls = require('./control/init-control.js') | ||
var initTargets = require('./init-target/init-target.js') | ||
@@ -16,7 +17,12 @@ module.exports = BlenderCubeCanvas | ||
currentlyPressedKeys: {}, | ||
orbit: {yRadians: -1.9, xRadians: 1.05} | ||
currentAnimation: [0, 4], | ||
orbit: {yRadians: -1.9, xRadians: 1.05}, | ||
viewport: { width: 680, height: 420 } | ||
}) | ||
AppState.set('targets', initTargets(AppState)) | ||
var canvas = document.createElement('canvas') | ||
canvas.width = 680 | ||
canvas.height = 420 | ||
canvas.style.width = '100%' | ||
canvas.style.height = '100%' | ||
viewportResize(AppState, canvas) | ||
@@ -27,17 +33,18 @@ var gl = canvas.getContext('webgl') | ||
var viewport = {height: canvas.height, width: canvas.width} | ||
var shaderObject = initShaders(gl) | ||
initControls(AppState) | ||
loadModel(gl, function (err, modelData) { | ||
if (err) { console.log(err) } | ||
loop(function (dt) { | ||
animate(AppState) | ||
// TODO: Pull out some of the animation happening in render | ||
// TODO: Clean up params | ||
render(gl, viewport, modelData, shaderObject, dt, AppState.get()) | ||
}).start() | ||
var modelData = loadModel(gl, { | ||
animations: { | ||
'foo': [0, 1], | ||
'bar': [2, 3] | ||
} | ||
}) | ||
loop(function (dt) { | ||
animate(AppState) | ||
// TODO: Pull out some of the animation happening in render | ||
// TODO: Clean up params | ||
render(gl, modelData, dt, AppState.get()) | ||
}).start() | ||
return { | ||
@@ -44,0 +51,0 @@ element: canvas |
@@ -1,17 +0,6 @@ | ||
var matrixMultiply = require('./matrix-math/multiply.js') | ||
var makeTranslation = require('./matrix-math/make-translation.js') | ||
var makePerspective = require('./matrix-math/make-perspective.js') | ||
var makeYRotation = require('./matrix-math/make-y-rotation.js') | ||
var makeXRotation = require('./matrix-math/make-x-rotation.js') | ||
var makeLookAt = require('./matrix-math/make-look-at.js') | ||
var makeInverse = require('./matrix-math/make-inverse.js') | ||
var interpolate = require('mat4-interpolate') | ||
var createMatrix = require('gl-mat4/create') | ||
var vec3Normalize = require('gl-vec3/normalize') | ||
var vec3Scale = require('gl-vec3/scale') | ||
var mat3FromMat4 = require('gl-mat3/from-mat4') | ||
var mat3Invert = require('gl-mat3/invert') | ||
var mat3Transpose = require('gl-mat3/transpose') | ||
var animationClock = 0 | ||
var interpolateJoints = require('./temporary-refactor-zone/interpolate-joints.js') | ||
var makeCamera = require('./temporary-refactor-zone/make-camera.js') | ||
@@ -23,124 +12,31 @@ module.exports = Render | ||
// will be easier to split out once we know what we're doing | ||
function Render (gl, viewport, animatedModel, shaderObject, dt, state) { | ||
var min | ||
var max | ||
Object.keys(animatedModel.keyframes).forEach(function (frame) { | ||
if (!min && !max) { | ||
min = frame | ||
max = frame | ||
} else { | ||
min = Math.min(min, frame) | ||
max = Math.max(max, frame) | ||
} | ||
}) | ||
animationClock += dt / 1000 | ||
var animationDuration = max - min | ||
if (animationClock > animationDuration) { | ||
animationClock %= animationDuration | ||
} | ||
// Find two closest keyframes | ||
var lowestKeyframe = null | ||
min = max = null | ||
var minJoints = [] | ||
var maxJoints = [] | ||
Object.keys(animatedModel.keyframes).sort().forEach(function (frame, index) { | ||
frame = Number(frame) | ||
if (index === 0) { lowestKeyframe = frame } | ||
if (frame <= lowestKeyframe + animationClock) { | ||
min = frame | ||
minJoints = animatedModel.keyframes['' + frame] | ||
} | ||
if (frame >= lowestKeyframe + animationClock && !max) { | ||
max = frame | ||
maxJoints = animatedModel.keyframes['' + frame] | ||
} | ||
}) | ||
var percentBetweenKeyframes = (lowestKeyframe + animationClock - min) / (max - min) | ||
var interpolatedJoints = [] | ||
function Render (gl, animatedModel, dt, state) { | ||
// TODO: get # joints from model | ||
var numJoints = 5 | ||
for (var i = 0; i < numJoints; i++) { | ||
interpolatedJoints[i] = createMatrix() | ||
interpolate(interpolatedJoints[i], minJoints[i] || createMatrix(), maxJoints[i] || createMatrix(), percentBetweenKeyframes) | ||
} | ||
var selectedKeyframes = Object.keys(animatedModel.keyframes) | ||
.sort() | ||
.slice(state.currentAnimation[0], state.currentAnimation[1] + 1) | ||
.reduce(function (selectedKeyframes, currentKeyframe) { | ||
selectedKeyframes[currentKeyframe] = animatedModel.keyframes[currentKeyframe] | ||
return selectedKeyframes | ||
}, {}) | ||
gl.viewport(0, 0, viewport.width, viewport.height) | ||
var interpolatedJoints = interpolateJoints(selectedKeyframes, dt, animatedModel.numJoints) | ||
gl.viewport(0, 0, state.viewport.width, state.viewport.height) | ||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) | ||
var pMatrix = makePerspective(Math.PI / 3, viewport.width / viewport.height, 1, 2000) | ||
var pMatrix = makePerspective(Math.PI / 3, state.viewport.width / state.viewport.height, 1, 2000) | ||
var modelPosition = [0, 0, 0] | ||
var cameraMatrix = makeTranslation(0, 0, 3) | ||
cameraMatrix = matrixMultiply(cameraMatrix, makeXRotation(-state.orbit.xRadians)) | ||
cameraMatrix = matrixMultiply(cameraMatrix, makeYRotation(state.orbit.yRadians)) | ||
var cameraPosition = [ | ||
cameraMatrix[12], | ||
cameraMatrix[13], | ||
cameraMatrix[14] | ||
] | ||
var up = [0, 1, 0] | ||
cameraMatrix = makeLookAt(cameraPosition, modelPosition, up) | ||
var cameraMatrix = makeCamera(state.orbit, modelPosition) | ||
var viewMatrix = makeInverse(cameraMatrix) | ||
var modelMatrix = makeTranslation(modelPosition[0], modelPosition[1], modelPosition[2]) | ||
modelMatrix = matrixMultiply(modelMatrix, viewMatrix) | ||
// Vertex positions | ||
gl.bindBuffer(gl.ARRAY_BUFFER, animatedModel.vertexPositionBuffer) | ||
gl.vertexAttribPointer(shaderObject.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0) | ||
// Vertex normals | ||
gl.bindBuffer(gl.ARRAY_BUFFER, animatedModel.vertexNormalBuffer) | ||
gl.vertexAttribPointer(shaderObject.vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0) | ||
// vertex joints | ||
gl.bindBuffer(gl.ARRAY_BUFFER, animatedModel.affectingJointIndexBuffer) | ||
gl.vertexAttribPointer(shaderObject.jointIndexAttribute, 4, gl.FLOAT, false, 0, 0) | ||
// vertex joint weights | ||
gl.bindBuffer(gl.ARRAY_BUFFER, animatedModel.weightBuffer) | ||
gl.vertexAttribPointer(shaderObject.jointWeightAttribute, 4, gl.FLOAT, false, 0, 0) | ||
// lighting | ||
var lightingDirection = [1, -0.5, -1] | ||
var normalizedLD = [] | ||
vec3Normalize(normalizedLD, lightingDirection) | ||
vec3Scale(normalizedLD, normalizedLD, -1) | ||
gl.uniform3f(shaderObject.ambientColorUniform, 0.5, 0.5, 0.5) | ||
gl.uniform3fv(shaderObject.lightingDirectionUniform, normalizedLD) | ||
gl.uniform3f(shaderObject.directionalColorUniform, 1.0, 1.0, 1.0) | ||
// Vertex weight | ||
// TODO: for loop | ||
gl.uniformMatrix4fv(shaderObject.boneMatrix0, false, interpolatedJoints[0]) | ||
gl.uniformMatrix4fv(shaderObject.boneMatrix1, false, interpolatedJoints[1]) | ||
gl.uniformMatrix4fv(shaderObject.boneMatrix2, false, interpolatedJoints[2]) | ||
gl.uniformMatrix4fv(shaderObject.boneMatrix3, false, interpolatedJoints[3]) | ||
gl.uniformMatrix4fv(shaderObject.boneMatrix4, false, interpolatedJoints[4]) | ||
// Normal Matrices | ||
for (var q = 0; q < 5; q++) { | ||
// TODO: better name | ||
var jointNormalMatrix = [] | ||
mat3FromMat4(jointNormalMatrix, interpolatedJoints[q]) | ||
mat3Invert(jointNormalMatrix, jointNormalMatrix) | ||
mat3Transpose(jointNormalMatrix, jointNormalMatrix) | ||
gl.uniformMatrix3fv(shaderObject['normalMatrix' + q], false, jointNormalMatrix) | ||
} | ||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, animatedModel.vertexPositionIndexBuffer) | ||
gl.uniformMatrix4fv(shaderObject.pMatrixUniform, false, pMatrix) | ||
gl.uniformMatrix4fv(shaderObject.mvMatrixUniform, false, modelMatrix) | ||
// Set light uniform | ||
var normalMatrix = [] | ||
mat3FromMat4(normalMatrix, modelMatrix) | ||
mat3Invert(normalMatrix, normalMatrix) | ||
mat3Transpose(normalMatrix, normalMatrix) | ||
gl.uniformMatrix3fv(shaderObject.nMatrixUniform, false, normalMatrix) | ||
gl.drawElements(gl.TRIANGLES, animatedModel.numElements, gl.UNSIGNED_SHORT, 0) | ||
animatedModel.draw({ | ||
interpolatedJoints: interpolatedJoints, | ||
position: modelPosition, | ||
perspectiveMatrix: pMatrix, | ||
viewMatrix: viewMatrix, | ||
numJoints: animatedModel.numJoints | ||
}) | ||
} |
@@ -9,3 +9,5 @@ var fs = require('fs') | ||
// TODO: Add error handling | ||
function InitShaders (gl) { | ||
function InitShaders (gl, opts) { | ||
var numJoints = opts.numJoints | ||
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) | ||
@@ -38,3 +40,3 @@ var vertexShader = gl.createShader(gl.VERTEX_SHADER) | ||
return { | ||
var shaderObj = { | ||
ambientColorUniform: gl.getUniformLocation(shaderProgram, 'uAmbientColor'), | ||
@@ -51,15 +53,11 @@ lightingDirectionUniform: gl.getUniformLocation(shaderProgram, 'uLightingDirection'), | ||
pMatrixUniform: gl.getUniformLocation(shaderProgram, 'uPMatrix'), | ||
mvMatrixUniform: gl.getUniformLocation(shaderProgram, 'uMVMatrix'), | ||
// TODO: For loop | ||
boneMatrix0: gl.getUniformLocation(shaderProgram, 'boneMatrices[0]'), | ||
boneMatrix1: gl.getUniformLocation(shaderProgram, 'boneMatrices[1]'), | ||
boneMatrix2: gl.getUniformLocation(shaderProgram, 'boneMatrices[2]'), | ||
boneMatrix3: gl.getUniformLocation(shaderProgram, 'boneMatrices[3]'), | ||
boneMatrix4: gl.getUniformLocation(shaderProgram, 'boneMatrices[4]'), | ||
normalMatrix0: gl.getUniformLocation(shaderProgram, 'boneNormals[0]'), | ||
normalMatrix1: gl.getUniformLocation(shaderProgram, 'boneNormals[1]'), | ||
normalMatrix2: gl.getUniformLocation(shaderProgram, 'boneNormals[2]'), | ||
normalMatrix3: gl.getUniformLocation(shaderProgram, 'boneNormals[3]'), | ||
normalMatrix4: gl.getUniformLocation(shaderProgram, 'boneNormals[4]') | ||
mvMatrixUniform: gl.getUniformLocation(shaderProgram, 'uMVMatrix') | ||
} | ||
for (var jointNum = 0; jointNum < numJoints; jointNum++) { | ||
shaderObj['boneMatrix' + jointNum] = gl.getUniformLocation(shaderProgram, 'boneMatrices[' + jointNum + ']') | ||
shaderObj['normalMatrix' + jointNum] = gl.getUniformLocation(shaderProgram, 'boneNormals[' + jointNum + ']') | ||
} | ||
return shaderObj | ||
} |
var mount = document.createElement('div') | ||
mount.style.width = '100%' | ||
mount.style.height = '100%' | ||
var incompleteWarning = document.createElement('span') | ||
incompleteWarning.style.position = 'fixed' | ||
incompleteWarning.style.backgroundColor = 'white' | ||
incompleteWarning.style.width = '90%' | ||
incompleteWarning.style.margin = '0 auto' | ||
var sourceLink = document.createElement('a') | ||
@@ -14,3 +21,7 @@ sourceLink.href = 'https://github.com/chinedufn/collada-dae-parser' | ||
document.querySelector('html').style.height = '100%' | ||
document.body.style.height = '100%' | ||
document.body.style.margin = 0 | ||
var app = require('./animated-model/app.js')().element | ||
mount.insertBefore(app, mount.children[0]) |
{ | ||
"name": "collada-dae-parser", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "Parse collada .dae 3d animation files into json", | ||
@@ -49,3 +49,3 @@ "main": "src/parse-collada.js", | ||
"raf-loop": "^1.1.3", | ||
"solid-state": "^0.3.0", | ||
"solid-state": "^1.0.3", | ||
"standard": "^6.0.8", | ||
@@ -52,0 +52,0 @@ "tape": "^4.5.1" |
@@ -6,19 +6,13 @@ collada-dae-parser [![npm version](https://badge.fury.io/js/collada-dae-parser.svg)](http://badge.fury.io/js/collada-dae-parser) [![Build Status](https://travis-ci.org/chinedufn/collada-dae-parser.svg?branch=master)](https://travis-ci.org/chinedufn/collada-dae-parser) | ||
[View live animated model](http://chinedufn.github.io/collada-dae-parser/) | ||
[View live animated model demo](http://chinedufn.github.io/collada-dae-parser/) | ||
![image](http://i.giphy.com/l46Ch6CIolihxVKWk.gif) | ||
[View demo source](/demo) | ||
## Notice | ||
This package is still a work in progress (hence no major bump) | ||
I won't need skeletal animations until around September. Commits will be few and far between until then. | ||
But.. I'm still around. If you have a question, ideas or use cases that aren't covered open an issue! | ||
## What does it do? | ||
`collada-dae-parser` parses a [collada](https://www.khronos.org/collada/) file and outputs JSON. This is useful for displaying [skeletal animations](https://en.wikipedia.org/wiki/Skeletal_animation) in the browser. | ||
`collada-dae-parser` parses a [collada](https://www.khronos.org/collada/) file and outputs JSON. This is useful for displaying [skeletal animations](https://en.wikipedia.org/wiki/Skeletal_animation) in the browser. | ||
`collada-dae-parser` is only concerned with giving you JSON. An animation system is outside of this modules scope. | ||
`collada-dae-parser` is only concerned with giving you JSON. An animation system is outside of this modules scope, but [skeletal-animation-system](https://github.com/chinedufn/skeleta-animation-system) could be a useful start. | ||
@@ -39,7 +33,17 @@ ## To Install | ||
```sh | ||
# Run the demo locally. Changes to the `demo` directory will live reload in your browser | ||
# Run the demo locally. Changes to the `src` and `demo` directories will live reload in your browser | ||
# PRs and issues are welcome! | ||
git clone https://github.com/chinedufn/collada-dae-parser && cd collada-dae-parser && npm install && npm run demo | ||
git clone https://github.com/chinedufn/collada-dae-parser | ||
cd collada-dae-parser | ||
npm install | ||
npm run demo | ||
``` | ||
## Collada Support | ||
`collada-dae-parser` tries to be useful for WebGL games and interactive demos, but does not try to support the entire collada spec. If you're trying to parse a model | ||
that is not supported, `collada-dae-parser` will try to let you know how to tweak it. | ||
![image](https://cloud.githubusercontent.com/assets/2099811/19274200/62e11032-8f9d-11e6-8f99-d0528d2d5d77.png) | ||
## CLI | ||
@@ -73,2 +77,4 @@ | ||
TODO: Document this | ||
```js | ||
@@ -98,3 +104,4 @@ var parseDae = require('collada-dae-parser') | ||
- [x] demo: fix normals in demo lighting | ||
- [ ] src: Remove callback from API | ||
- [x] src: Remove callback from API | ||
- [x] warning: Throw descriptive error message if user attempts to export multiple geometries | ||
- [ ] src / demo: add a textured demo model | ||
@@ -109,2 +116,3 @@ - [ ] src: rounding values. Currently lots of .999999 and 1.000001 | ||
- [ ] doc: Documentation | ||
- [ ] warning: Somehow let the user know if their joints use non rigid transforms - until we actually support this | ||
@@ -125,5 +133,10 @@ - [ ] A separate package that uses collada-dae-parser to implement a stateless skeletal animation system | ||
- [wavefront-obj-parser](https://github.com/chinedufn/wavefront-obj-parser) | ||
- [skeletal-animation-system](https://github.com/chinedufn/skeleta-animation-system) | ||
## Credits | ||
- [Ben Houston](https://clara.io/user/bhouston) for the [3d male figure model](https://clara.io/view/d49ee603-8e6c-4720-bd20-9e3d7b13978a/webgl) | ||
## License | ||
MIT |
@@ -74,5 +74,5 @@ var mat4Multiply = require('gl-mat4/multiply') | ||
// TODO: Refactor. Depth first traversal might make all of this less hacky | ||
function getParentWorldMatrix (jointName, keyframe, jointRelationships, keyframeJointMatrices, accumulator) { | ||
function getParentWorldMatrix (jointName, keyframe, jointRelationships, keyframeJointMatrices) { | ||
// child -> parent -> parent -> ... | ||
var jointMatrixTree = foo(jointName, keyframe, jointRelationships, keyframeJointMatrices, accumulator) | ||
var jointMatrixTree = foo(jointName, keyframe, jointRelationships, keyframeJointMatrices) | ||
// TODO: Revisit this. Thrown in to pass tests. Maybe just return `jointMatrix` | ||
@@ -79,0 +79,0 @@ // when there aren't any parent matrices to factor in |
@@ -1,2 +0,1 @@ | ||
var transpose = require('gl-mat4/transpose') | ||
var mat4Multiply = require('gl-mat4/multiply') | ||
@@ -27,3 +26,6 @@ | ||
for (var i = 0; i < numJointWeightsToRead; i++) { | ||
parsedVertexJointWeights[index][jointsAndWeights.shift()] = weightsArray[jointsAndWeights.shift()] | ||
// The particular joint that we are dealing with, and its weighting on this vertex | ||
var jointNumber = jointsAndWeights.shift() | ||
var jointWeighting = jointsAndWeights.shift() | ||
parsedVertexJointWeights[index][jointNumber] = weightsArray[jointWeighting] | ||
} | ||
@@ -48,4 +50,2 @@ }) | ||
}) | ||
transpose(bindShapeMatrix, bindShapeMatrix) | ||
} | ||
@@ -56,3 +56,2 @@ // TODO: Should we also export the greatest number of joints for a vertex? | ||
return { | ||
bindShapeMatrix: bindShapeMatrix, | ||
jointBindPoses: jointBindPoses, | ||
@@ -59,0 +58,0 @@ vertexJointWeights: parsedVertexJointWeights |
@@ -0,4 +1,12 @@ | ||
var MultipleMeshError = require('./multiple-mesh-error-message.js') | ||
module.exports = ParseLibraryGeometries | ||
function ParseLibraryGeometries (library_geometries) { | ||
// We only support models with 1 geometry. If the model zero or | ||
// multiple meshes we alert the user | ||
if (library_geometries[0].geometry.length !== 1) { | ||
throw new MultipleMeshError(library_geometries[0].geometry.length) | ||
} | ||
var geometryMesh = library_geometries[0].geometry[0].mesh[0] | ||
@@ -5,0 +13,0 @@ var source = geometryMesh.source |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58
1356
137
3169759
6