Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add gltf-model component and system.
Fixes #2261.
  • Loading branch information
donmccurdy committed Feb 2, 2017
commit c2b54628475879975050701b30adee6872e570c8
Binary file added examples/assets/models/brainstem/BrainStem.bin
Binary file not shown.
5,201 changes: 5,201 additions & 0 deletions examples/assets/models/brainstem/BrainStem.gltf

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions examples/assets/models/brainstem/BrainStem0FS.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
precision highp float;
varying vec3 v_normal;
uniform vec4 u_ambient;
uniform vec4 u_diffuse;
uniform vec4 u_emission;
uniform vec4 u_specular;
void main(void) {
vec3 normal = normalize(v_normal);
vec4 color = vec4(0., 0., 0., 0.);
vec4 diffuse = vec4(0., 0., 0., 1.);
vec4 emission;
vec4 ambient;
vec4 specular;
ambient = u_ambient;
diffuse = u_diffuse;
emission = u_emission;
specular = u_specular;
diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
color.xyz += diffuse.xyz;
color.xyz += emission.xyz;
color = vec4(color.rgb * diffuse.a, diffuse.a);
gl_FragColor = color;
}
19 changes: 19 additions & 0 deletions examples/assets/models/brainstem/BrainStem0VS.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
precision highp float;
attribute vec3 a_position;
attribute vec3 a_normal;
varying vec3 v_normal;
attribute vec4 a_joint;
attribute vec4 a_weight;
uniform mat4 u_jointMat[18];
uniform mat3 u_normalMatrix;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
void main(void) {
mat4 skinMat = a_weight.x * u_jointMat[int(a_joint.x)];
skinMat += a_weight.y * u_jointMat[int(a_joint.y)];
skinMat += a_weight.z * u_jointMat[int(a_joint.z)];
skinMat += a_weight.w * u_jointMat[int(a_joint.w)];
vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);
v_normal = u_normalMatrix * mat3(skinMat)* a_normal;
gl_Position = u_projectionMatrix * pos;
}
3 changes: 3 additions & 0 deletions examples/test/model/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
<a-assets>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be cool to add text labels under each model for the model format. And the scene could use a better background <a-sky color="#FAFAFA">

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also add the different format types in the page title & meta description Models (glTF, COLLADA, OBJ)

Copy link
Member Author

@donmccurdy donmccurdy Feb 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scope creep alert 😉

Added the meta title/description, but I'm getting errors trying to do text.

<a-text value="foo"></a-text>
THREE.WebGLShader: gl.getShaderInfoLog() fragment WARNING: 0:102: '
' : extension directive should occur before any non-preprocessor tokens 
� 1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define GAMMA_FACTOR 2
5: #define NUM_CLIPPING_PLANES 0
6: #define UNION_CLIPPING_PLANES 0
7: uniform mat4 viewMatrix;
...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that on latest? We pushed some text patches switching to raw shader material.

Copy link
Contributor

@machenmusik machenmusik Feb 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the latest and greatest master, that warning has been eliminated by using RawShaderMaterial for the sdf and msdf text shaders. so... maybe needs rebase?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase did the trick. ✅

<a-asset-item id="crate-obj" src="../../assets/models/crate/crate.obj"></a-asset-item>
<a-asset-item id="crate-mtl" src="../../assets/models/crate/crate.mtl"></a-asset-item>
<a-asset-item id="brainstem" src="../../assets/models/brainstem/BrainStem.gltf"></a-asset-item>
<a-asset-item id="monster" src="monster/monster.dae"></a-asset-item>
</a-assets>

<a-entity position="0 0 -12">
<a-entity collada-model="#monster" material="color: green" scale="0.25 0.25 0.25"
position="-10 0 1"></a-entity>

<a-entity gltf-model="#brainstem" position="10 -1 5" scale="3 3 3"></a-entity>

<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 0 5"></a-entity>
<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 2 5"></a-entity>
</a-entity>
Expand Down
37 changes: 37 additions & 0 deletions src/components/gltf-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
var registerComponent = require('../core/component').registerComponent;
var THREE = require('../lib/three');

/**
* glTF model loader.
*/
module.exports.Component = registerComponent('gltf-model', {
schema: {type: 'model'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be multiprop to allow room for future props?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slightly prefer multiprop, but can't actually think of any others we'd need. Maybe crossorigin. I'm expecting animation to be a separate component, but if not that would definitely need some properties. I've used src: {type: 'asset'} in most of my loaders so far i think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, can just leave it as is


init: function () {
this.model = null;
this.loader = new THREE.GLTFLoader();
},

update: function () {
var self = this;
var el = this.el;
var src = this.data;

if (!src) { return; }

this.remove();

this.loader.load(src, function (gltfModel) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's name the anonymous function for easier debugging

self.model = gltfModel.scene;
self.system.addModel(self.model);
el.setObject3D('mesh', self.model);
el.emit('model-loaded', {format: 'gltf', model: self.model});
});
},

remove: function () {
if (!this.model) { return; }
this.el.removeObject3D('mesh');
this.system.removeModel(this.model);
}
});
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require('./camera');
require('./collada-model');
require('./cursor');
require('./geometry');
require('./gltf-model');
require('./hand-controls');
require('./light');
require('./look-controls');
Expand Down
2 changes: 2 additions & 0 deletions src/lib/three.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ if (THREE.Cache) {
}

// TODO: Eventually include these only if they are needed by a component.
require('three/examples/js/loaders/GLTFLoader'); // THREE.GLTFLoader
require('three/examples/js/loaders/OBJLoader'); // THREE.OBJLoader
require('three/examples/js/loaders/MTLLoader'); // THREE.MTLLoader
require('three/examples/js/BlendCharacter'); // THREE.BlendCharacter
Expand All @@ -27,6 +28,7 @@ require('../../vendor/VRControls'); // THREE.VRControls
require('../../vendor/VREffect'); // THREE.VREffect

THREE.ColladaLoader.prototype.crossOrigin = 'anonymous';
THREE.GLTFLoader.prototype.crossOrigin = 'anonymous';
THREE.MTLLoader.prototype.crossOrigin = 'anonymous';
THREE.OBJLoader.prototype.crossOrigin = 'anonymous';

Expand Down
41 changes: 41 additions & 0 deletions src/systems/gltf-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var registerSystem = require('../core/system').registerSystem;
var THREE = require('../lib/three');

/**
* glTF model system.
*/
module.exports.System = registerSystem('gltf-model', {
init: function () {
this.models = [];
},

/**
* Updates shaders for all glTF models in the system.
*/
tick: function () {
var sceneEl = this.sceneEl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could test this code too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (sceneEl.hasLoaded && this.models.length) {
THREE.GLTFLoader.Shaders.update(sceneEl.object3D, sceneEl.camera);
}
},

/**
* Registers a glTF asset.
* @param {object} gltf Asset containing a scene and (optional) animations and cameras.
*/
addModel: function (gltf) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do registerModel/unregisterModel

this.models.push(gltf);
},

/**
* Unregisters a glTF asset.
* @param {object} gltf Asset containing a scene and (optional) animations and cameras.
*/
removeModel: function (gltf) {
var models = this.models;
var index = models.indexOf(gltf);
if (index >= 0) {
models.splice(index, 1);
}
}
});
1 change: 1 addition & 0 deletions src/systems/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require('./camera');
require('./geometry');
require('./gltf-model');
require('./light');
require('./material');
require('./tracked-controls');
Expand Down