For a dataviz project, I have some datas in an array. I need to use these datas to render a wave in ThreeJS like this:
The height of each peak depends on the given size and must be in its circle depending on the year.
I thought about creating a plan and deforming it with a vertex shader based on the data. Unfortunately, it seems that this is not possible. I'm a bit lost and I clearly need advices about how to do this.
The array looks like this:
[
{
"year": 2016,
"dimension": 28.400 // hectares
},
{
"year": 1995,
"dimension": 12.200
}
]
There is a "displacementMap" texture property on the THREE.Materials.. this will displace the vertices vertically based on the brightness of the pixel in the texture.
You can make a plane with a bunch of subdivisions, like new THREE.Mesh(new THREE.PlaneGeometry(10,10, 30,30),new THREE.MeshStandardMaterial({displacementMap:yourDisplacementTexture})
For the displacementMap texture, you can either use an external image, or create a canvas, draw your height data into that, and then create a THREE.Texture( thecanvas ).
Yet another option is to create the subdivided plane using THREE.PlaneGeometry()
then get the geometry.vertices, and modify them by setting the .z value in each vertex.. followed up with geometry.verticesNeedUpdate = true (to tell the renderer to send the modifications to the GPU).
I'm trying to experiment a little with glTF 2.0 models with animation.
Unfortunately, when i try to update the THREE.animationMixer, I get a warning:
THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0.
Here's the setup:
The model:
I'm no 3D artist, so i've made a cube + torus in blender.
Also there are two actions in the Action Editor, moving the torus in two different ways.
You can download the .blend, and .glTF from here.
I think the export worked fine, since the model + animation are working in Don McCurdy's glTF viewer.
The Code:
I've tried using either Don McCurdy animation-mixer, or mixing Three.js into an a-frame component:
AFRAME.registerComponent("foo", {
init: function() {
var el = this.el;
setTimeout(()=>{
var model = el.getObject3D('mesh')
this.mixer = new THREE.AnimationMixer(model);
var clips = model.animations || (model.geometry || {}).animations ||
[];
console.log(this.mixer)
console.log(el)
console.log(clips[0])
const action = this.mixer.clipAction(clips[0], model);
action.setDuration(100).setLoop(THREE.LoopRepeat).play();
console.log(action)
}, 2000)
},
tick: function (t, dt) {
if (this.mixer && !isNaN(dt)) this.mixer.update(dt / 1000);
}
})
This code is basically a ripoff of Don's Loader. The only object that should be moving, the torus, dissapears, with the mentioned error, when I add the mixer.update part. Nothing logs as undefined, so the objects are created properly. Furthermore, the animation-mixer behavior is the same (i guess no surprise, since i just took part of it).
Any ideas what could be causing the problem ? I may be missing something, but i have no clue how to troubleshoot this.
Cubic bezier interpolation is broken in older versions of THREE (pre r87-r88 or so), which A-Frame 0.7.0 still uses. Switching to linear interpolation in Blender would work around this, or using the A-Frame master branch.
You also mention two actions in the Action Editor, which would be merged during export because multiple actions are still in progress for the Khronos glTF Blender exporter.
If that doesn't work, there is also another glTF Blender exporter to try: https://github.com/Kupoman/blendergltf/
I've loaded a Collada .dae model into my A-Frame scene and animated the camera movement around it then use the mouse cursor to orient the camera using universal-controls from the aframe-extras component. About 50% of the time it is fine, but the other times it throws a error:
aframe.js:30870 Uncaught TypeError: Cannot read property '0' of undefined
raycast # aframe.js:30870
intersectObject # aframe.js:16216
intersectObject # aframe.js:16224
from the line:
if ( uvs ) {
var uvs_f = uvs[ f ];
uvA.copy( uvs_f[ 0 ] );// <- that's where this error came from
uvB.copy( uvs_f[ 1 ] );
uvC.copy( uvs_f[ 2 ] );
intersection.uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );
}
It looks very similar to the question here: Three.js drag the object (but it unfortunately does not have an answer)
Looks like there's an issue wherever it's intersection. I think we might have to PR to A-Frame's cursor to catch such errors.
I am using the latest three.js exporter for three.js v71 plugged into Blender 2.75. I have a simple Blender file with a cube, armature and single bone. When I export the file to three.js, the bone and animation data is never exported.
The options that I have highlighted are :
https://www.dropbox.com/s/99wma7fqaw2wur5/blenderoptions.jpg?dl=0
And the output js file, without bones or animation, is :
"data": {
"skinIndices": [],
"vertices": [1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,0.999999,1,0.999999,-1,1,-1,-1,1,-1,1,1],
"animations": [],
"normals": [0.577349,0.577349,-0.577349,0.577349,-0.577349,-0.577349,-0.577349,-0.577349,-0.577349,-0.577349,0.577349,-0.577349,0.577349,0.577349,0.577349,-0.577349,0.577349,0.577349,-0.577349,-0.577349,0.577349,0.577349,-0.577349,0.577349],
"faces": [33,0,1,2,3,0,1,2,3,33,4,7,6,5,4,5,6,7,33,0,4,5,1,0,4,7,1,33,1,5,6,2,1,7,6,2,33,2,6,7,3,2,6,5,3,33,4,0,3,7,4,0,3,5],
"influencesPerVertex": 2,
"metadata": {
"version": 3,
"vertices": 8,
"uvs": 0,
"faces": 6,
"normals": 8,
"bones": 0,
"generator": "io_three"
},
"uvs": [],
"name": "CubeGeometry",
"bones": [],
"skinWeights": []
}
What else do I need to do? I've tried every combination of options, including the Morph animation, but nothing works. I've uploaded my Blender file and the js output to : https://www.dropbox.com/s/yr90088smoa9941/simplecube.zip?dl=0
Wow, Blender really isn't easy, is it?
I eventually set the parent of the mesh to the skeleton by using Ctrl-P and then choosing automatic weights, rather than selecting the parent myself. I had been choosing the parent as Armature->Bone->Bonename. Apparently it has to be just Armature->Object. Ctrl-P sorted this out for me automatically, and when the file is exported (Along with the bones and skinning boxes being ticked) then the animation details are alo placed into the json file.
Further Gotcha : If the file is exported with scene information then Threejs must use the Objloader, otherwise you start getting 'Undefined length' errors when loading the model. If the file is exported without scene information, then use the JsonLoader.
I exported a model(with several animations) from 3ds max and ultimately translated it into JSON. However, all of my animations are smashed into one animation. Is there a way in threejs to only play a certain range of frames , or do I need to do an export from 3ds max for each individual animation?
Thanks,
David
there are two types of animations.
I use mesh morph one when exporting from Blender. My resulting json has this line:
"morphTargets" : [{ "name": "animation_000000", "vertices": [...
then I load it using MorphAnimMesh:
mesh = new THREE.MorphAnimMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
after loading I set idle animation by default:
mesh.duration = 4000; //4 seconds whole animation?
mesh.setFrameRange(1,50);
then on some event i just change animation range like this:
mesh.setFrameRange(51,80);
if you use bones and skins animation, your json model ends up with lines
"animations" : [...
"bones": [...
i havent used that one, so try this tutorial:
http://code.tutsplus.com/tutorials/webgl-with-threejs-models-and-animation--net-35993
also this is similar question:
How do I handle animated models in Three.js?