Blender-exported JSON model shows wrong animations in THREE.js - json

I have a basic walk animation in Blender that I´m trying to export to THREE.js. It looks nice in Blender playback:
Now, after being exported with the THREE.js exporter, it looks like this on the browser:
The geometry is broken, not in all the body parts, but certainly has some problems. I´m not sure what to do now, I tried exporting with several options checked/unchecked, with no luck.
I also read the explanations in this posts, I think I followed all the required steps but still getting this weird animations:
http://unboring.net/workflows/animation.html#preview
https://github.com/mrdoob/three.js/pull/8412#issuecomment-210675561
https://github.com/mrdoob/three.js/issues/6050
The code I´m currently using to load the JSON model/animations is like this:
var loader = new THREE.JSONLoader();
var action = {}, mixer;
loader.load(path + '/dino.json', function (geometry, materials) {
materials.forEach(function (material) {
material.skinning = true;
});
character = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial(materials)
);
scene.add(character);
/* ANIMATION */
mixer = new THREE.AnimationMixer(character);
action.walk = mixer.clipAction(geometry.animations[ 3 ]);
action.walk.setEffectiveWeight(1);
action.walk.enabled = true;
/* Update/render functions */
onUpdateFcts.push(function(delta, now){
mixer.update(delta);
});
action.walk.play();
});
I´m using Blender 2.78c and THREE.js r84, with the Blender exporter tool including in this revision.

I found some interesting links about similar animation problems:
Model with bones animation (blender export) animating incorrectly in three.js
http://dev.mothteeth.com/2012/10/threejs-blender-exporting-skeletal-animations/
Blender exports a three.js animation - bones rotate strangely
After reading all of these advices, I had successfully exported the animated mesh without visual artifacts following this workflow:
Create the armature bone by bone around the mesh. When done and in object mode, select first the mesh, then the armature, press CTRL+P > With automatic weights. This generates an armature modifier on the mesh. Against what I read, the armature modifier doesn´t need to be deleted before exporting.
You must have a default pose like the rest position. This must be the one selected on Blender. Also, the playback frame 0 must be selected in that default pose.
I created keyframes at the start and end of every pose for all the bones involved, this seems important.
You must unselect everything and only select the mesh, not the armature. This must be done in object mode.
My export settings:
Note: I must say that this is the same workflow I was following with no luck. This time the difference was that I first deleted every vertex group, also the armature modifier (not the armature itself) and recreated all the steps from the first one. Now, once exported the animated mesh worked fine enough!

Related

Import Shapes of Custom Library from Draw.io in mxGraph

I'm currently working with the mxGraph library in javascript and I'm trying to create my own shapes in draw.io, to export them, then to reuse them as much as I want in my own program using the mxGraph library.
So far, I have tried to create a custom library, which contains all my shapes. I have exported it in XML which gives me a half-encoded XML file. Then, I'd like to import that mxLibrary in my own app so I can reuse these shapes for creating my own diagrams. I have no idea how to deal with that XML file.
I have also tried taking the XML from Extras -> Edit Diagram and reimport it with the codec, then with mxGraph#addCells but the shapes aren't grouped anymore, and I can't seem to find how to clone them.
My goal would literally to have my list of shapes/cells somewhere, which I can reuse whenever I want.
If this is not possible, how may I do that instead? I have also looked up how to create my own shapes (with redrawPath and the style thing), but it looks really long and boring.
Here's an example of what the XML looks like. The shape is a simple double square.
<mxlibrary>[{"xml":"xVNBbsIwEHyN78EugjOhcOqpLzDJgi05XstZSPJ7trFbiAqCqpV6sLQ7O2N7xrJQZdNvow7mDWtwQr0KVUZESlXTl+CckIWthVoLKQteQm7uTGfjtAg6gqdnBDIJTtodISEJaGlwGThEPIZMg0jQT46q0HuoSO8+6cX3K4zUfP4WsAGKA1M6W5NJjGVWGbAHQ1NMt/keX8qLHy6ypdv21GN7nbEE70FXH33HDyHUylDDO65nXOo2sD1u9rYH3nV1N4lrx/LfHL/8veO9da5Eh5Exjx5+GUIWzJNgmHRXAS1uBLT4eUDcXn7TOJt8tjM=","w":80,"h":80,"aspect":"fixed","title":"custom_shape_1"}]</mxlibrary>
Thank you in advance!
There are 2 ways I know, to do it, depending on your needs.
Embed draw.IO as an iframe in your app, and create a plugin that adds your own palette of icon on the side bar. you can watch the p1 plugin code, and replicate it plugin list in draw.io, look for the p1 plugin
. code example of how to integrate draw.io in your app
hint: if pulgins are not loaded, check the plugin folder link.
If you add the vertices on you own app, create your own style, and reuse it when creating.
updateStyles()
{
var style = new Object();
style[(<any>window).mxConstants.STYLE_SHAPE] =
(<any>window).mxConstants.SHAPE_IMAGE;
style[(<any>window).mxConstants.STYLE_PERIMETER] =
(<any>window).mxPerimeter.RectanglePerimeter;
style[(<any>window).mxConstants.STYLE_IMAGE] =
'../assets/transformer.png';
style[(<any>window).mxConstants.STYLE_FONTCOLOR] = '#000000';
style[(<any>window).mxConstants.STYLE_WHITE_SPACE] = 'wrap';
style[(<any>window).mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
this.graph.getStylesheet().putCellStyle('transformer', style);
}
reuse this style whenever creating a vertex using insertVertex function.
try {
const parent = this.graph.getDefaultParent();
this.graph.getModel().beginUpdate();
const vertex = this.graph.insertVertex(parent, uuid.v4(), node, 40, 40, 80, 40, 'transformer');
} finally {
this.graph.getModel().endUpdate();
}

how to change a CesiumJS viewer's baselayer url

i am using a CesiumJS instance to display a base map of the earth using a imageryProvider from source A.
var viewer = new Cesium.Viewer('cesiumContainer', imageryProvider:providerA);
Now while using the Viewer I would like to be able to change this map to get images from providerB at a certain event.
I tried:
viewer.scene.imageryLayers.get(0).imageryProvider.url = providerB.url
However that does not seem to work and also feels quite like hack anyway.
I could not find anything in Cesium's documentation .
Is this at all possible without restarting / recreating the viewer instance?
I know that there is a Cesium.BaseLayerPicker (https://cesium.com/docs/cesiumjs-ref-doc/BaseLayerPicker.html)
However I do not see what method this picker calls on "select" )
Thanks a lot.
The BaseLayerPicker widget calls this code when the user selects a new layer.
There's a lot of boilerplate widget management in that block of code, but for your sake, only a couple of the lines are critical. First, the old existing active imagery layer is searched for, and removed:
imageryLayers.remove(layer);
Then, a new imagery provider is constructed and added at index 0, the first position, which is the base imagery layer:
imageryLayers.addImageryProvider(newProviders, 0);
You can directly change the URL of the provider but you should also change appropriate parameters("layers" in case of WMS, "layer", "style", "format", "tileMatrixSetID " ... in case of WMTS) depending on the type of provider(WMS or WMTS).

Changing materials in Forge

We are currently making the client retrieve the object states when the page loads (which will cause the 'pending' objects in the model to turn into different colors). Then we poll for changes to update the coloring (Firstly: pending object gets colored when the viewer loads, and then we keep polling to check and change state again, to make Forge render those in a different color and store their old color/material. When the polling received a change that an object should no longer be colored, it tells Forge to use the old color/material again.
The problem:
We've found out what the problem is, but we couldn't find out how to fix it. The problem is that changing materials in Forge doesn't work after startup anymore, it only works in the first ~3 seconds or so (the materials were used to show the colors).
However, setting overlays works even after the first ~3 seconds, (showing overlays instead of materials to show the colors).
This is not what we want to achieve. This looks unoptimized, because overlays will be shown through everything.
The materials, however, seem to be 'locked', as in, they cannot be changed anymore after the first ~3 seconds. It seems like they aren't refreshed or something
In the examples, we found they used viewer.impl.invalidate(true) to refresh the Forge viewer, but that doesn't do anything after ~3 seconds.
We've also tried every combination of viewer.impl.invalidate(true, true, true) as well as setting material.needsUpdate to true, as well as trying to re-render the entire scene.
We also found this: https://github.com/mrdoob/three.js/issues/790, but we couldn't find a good way to do that in Forge, we tried viewer.requestSilentRender() but that didn't do anything either.
Anyway, we've tried everything we could come up with and could find online to make the materials work, but nothing made a difference.
We are looking to find someone that's more experienced with how Forge works that can see what the material code is doing wrong.
As for the content, here is all the code you will need to understand what is happening:
DROPBOX LINK
And here is a small part of the "index.html" file that sets the color:
try
{
viewer.restoreAllColorOverlays(); //for materials instead of overlays: viewer.restoreAllColorMaterials();
$.each(colors, function(color, selectionIds)
{
viewer.setColorOverlay(selectionIds, color); //for materials instead of overlays: viewer.setColorMaterial(selectionIds, color);
});
}
catch(error)
{
console.error(error);
}
I have no idea how you implement your app, so I only tell what I found in your codes. If you want to resolve the issue you addressed, you can consider providing a reproducible case demonstrating that, I will gladly pass it to our dev team. Those following items should be in the reproducible case:
A short exact description of what you are trying to achieve. The behavior you observe versus what you expect, and why this is a problem.
A complete yet minimal sample source model to run a test in.
A complete yet minimal Forge app that can be run and debugged with a simple procedure to analyze its behavior lives in the sample model.
A complete yet minimal pure three.js app that can be run and demonstrated the shader effect you want. Note. Forge Viewer is using r71 three.js.
Detailed step-by-step instructions for reproducing the issue, e.g. which element to pick, what command to launch etc.
If your reproducible case could not be posted here publicly, please send it to the forge.help#autodesk.com and remove sensitive data or information before you send.
=== Something I found in your codes:
I found here are some wrong types and missing actions in your ColorMaterial extension. The color property of an material should the a type of the THREE.Color. Here is my modification:
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color)
{
if( !(color instanceof THREE.Color) ) throw 'Invalid argument: Color';
var material = new THREE.MeshPhongMaterial
({
color: color,
opacity: 0.8,
transparent: true
});
viewer.impl.matman().addMaterial( 'ColorMaterial-' + new Date().getTime(), material, true );
// ...........
};
Its' result is here:
In the ColorOverlay extension, The type of material color property is also wrong, it should be a type of THREE.Color, too. Changing it into THREE.Color should work fine. In addition, overlay is covers on 3D objects, so you should call viewer.hide() with your setColorOverlay() together. Otherwise, it won't look like a transparent object.
Without hidding 3D object of the wall:
hide 3D object of the wall:

THREE.js - morphTargetInfluences on an imported JSON mesh not getting results

I have a basic three.js scene in which I am attempting to get objects exported from Blender (as JSON files with embedded morphs) to function and update their shapes with user input.
Here is a test scene
http://onthez.com/temphosting/three-js-morph-test/morph-test.html
The slab is being resized without morphs by simply scaling a box, which is working just fine.
I must be missing something fundamental with the little monument on top. It has 3 morphs (width, depth, height) that are intended to allow it to resize.
I am using this code to implement the morph based on users dat.gui input.
folder1.add( params, 'width', 12, 100 ).step(1).name("Width").onChange( function () {
updateFoundation();
building.morphTargetInfluences['width'] = params.width/100;
roofL.morphTargetInfluences['width'] = params.width/100;
roofR.morphTargetInfluences['width'] = params.width/100;
building.updateMorphs();
});
The materials for building, roofL, and roofR each have morphTargets set as true.
I've been going over the three.js examples here:
http://threejs.org/examples/?q=morph#webgl_morphtargets_human
as well as #webgl_morphtargets and #webgl_morphtargets_horse
Any thoughts or input would be much appreciated!
I believe I've reached a solution for my question I was under the impression that the JSON loader was preserving the morph target names to be used in place of an index number with morphTargetInfluences
something like morphTargetInfluences['myMorphTargetName']
but, after closer inspection in the console it seems like they should be referred to by number like morphTargetInfluences[0]
Not the most intuitive, but I can work with it.

Away3d 4, creating a flat shaded material

I'm currently trying to create a "flat" shaded ColorMaterial inside of Away3d 4 to use as a mesh on a loaded .obj file.
This is a screenshot of what I'm trying to achieve. The flat shaded model is on the left.
I loaded the same .obj file I’m working with in Away into a program called MeshLab. MeshLab has two settings for Render Mode, flat or smooth.
The Flat render mode is on the left and smooth is on the right. When I load my .obj into Away3D the result looks exactly like MeshLab’s smooth render mode.
In order to get a flat result I’ve tried to set the smooth flag on my ColorMaterial to false but that doesn’t seem to change anything.
http://away3d.com/livedocs/away3d/4.0/away3d/materials/MaterialBase.html
I’m now starting to look into the materials shadowMethod because I was able to find a smooth boolean on ShadingMethodBase although I’m honestly not sure if this is where you would handle this.
http://away3d.com/livedocs/away3d/4.0/away3d/materials/DefaultMaterialBase.html#shadowMethod
http://away3d.com/livedocs/away3d/4.0/away3d/materials/methods/ShadingMethodBase.html
Below is the code for creating my light and light picker,
dL = new DirectionalLight();
dL.diffuse = 20;
dL.ambient=.6;
dL.specular=15
scene.addChild(dL);
lightPicker= new StaticLightPicker([dL]);
dL.direction = new Vector3D(0,1,-2);
And this is my material, I've tried playing around with most of it's properties:
primitiveMaterial = new ColorMaterial(0xcccccc);
primitiveMaterial.smooth = false;
primitiveMaterial.bothSides = false;
//primitiveMaterial.gloss = 800;
//primitiveMaterial.diffuseLightSources = LightSources.LIGHTS;
primitiveMaterial.diffuseMethod.alphaThreshold = .3;
primitiveMaterial.ambient =.2;
primitiveMaterial.lightPicker=lightPicker;
Can anyone help point me in the right direction?
Thanks!
ColorMaterial has no smooth attribute because it hasn't texture and smooth indicates whether or not any used textures should use smoothing. Most likely smooth attribute is inherited from MaterialBase and have no affect.
Your problem is in the normal vectors when surface is flat they are normals, when it is smoothed they are blended so it appears smoother.
Im guessing the problem might be in obj file. If it has no normals Away3d might generate them by it self ass well as MeshLab but Away3d apparently doing it only in smoothed mode by default. Or obj file contain smoothed normals and MeshLab overriding them in flat mode.
Open obj file with text editor and look for normals, try another obj file with flat surface.
But i might be wrong.
Here is smoothed obj
And this one is flat
What you are looking for is probably the Explode class.
Call Explode.apply(<your loaded mesh>) to remove the smoothed normals.