Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLTFLoader: Loading fails when same geometry is reused with multiple skeletons. #16475

Closed
3 of 13 tasks
donmccurdy opened this issue May 17, 2019 · 3 comments
Closed
3 of 13 tasks

Comments

@donmccurdy
Copy link
Collaborator

This example contains a mesh, and that mesh is instantiated multiple times in the scene. Different instantiations assign a different skeleton/bones, so it should be treated as multiple SkinnedMesh instances sharing a single geometry:

Screen Shot 2019-05-17 at 9 56 52 AM

InfiniteSkinnedTentacle.glb.zip

Currently loading runs without errors, but nothing is rendered. Reported by @vpenades in donmccurdy/three-gltf-viewer#147.

Three.js version
  • Dev
  • r104
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, ...)
@titansoftime
Copy link
Contributor

Is this related to the issue that SkeletonUtils currently works around?

https://discourse.threejs.org/t/solved-issue-with-gltfloader-and-reusing-geometry/6697

@Mugen87
Copy link
Collaborator

Mugen87 commented May 18, 2019

I've integrated the asset in the webgl_loader_gltf example and everything looks good:

image

The code looks like so:

var container, stats, controls;
var camera, scene, renderer, mixer, clock;

init();
animate();

function init() {

	container = document.createElement( 'div' );
	document.body.appendChild( container );

	camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
	camera.position.set( - 1.8, 0.9, 2.7 );

	scene = new THREE.Scene();

	clock = new THREE.Clock();

	var loader = new THREE.RGBELoader().setPath( 'textures/equirectangular/' );
	loader.load( 'pedestrian_overpass_2k.hdr', function ( texture ) {

		texture.encoding = THREE.RGBEEncoding;
		texture.minFilter = THREE.NearestFilter;
		texture.magFilter = THREE.NearestFilter;
		texture.flipY = true;

		var cubeGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 1024 } );
		cubeGenerator.update( renderer );

		var pmremGenerator = new THREE.PMREMGenerator( cubeGenerator.renderTarget.texture );
		pmremGenerator.update( renderer );

		var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
		pmremCubeUVPacker.update( renderer );

		var envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;

		// model

		var loader = new THREE.GLTFLoader();
		loader.load( 'models/gltf/InfiniteSkinnedTentacle.glb', function ( gltf ) {

			gltf.scene.traverse( function ( child ) {

				if ( child.isMesh ) {

					child.material.envMap = envMap;

				}

			} );

			var animations = gltf.animations;

			mixer = new THREE.AnimationMixer( gltf.scene );
			var action = mixer.clipAction( animations[ 0 ] );
			action.play();

			scene.add( gltf.scene );

		} );

		pmremGenerator.dispose();
		pmremCubeUVPacker.dispose();

		scene.background = cubeGenerator.renderTarget;

	} );

	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.gammaOutput = true;
	container.appendChild( renderer.domElement );

	controls = new THREE.OrbitControls( camera, renderer.domElement );
	controls.target.set( 0, - 0.2, - 0.2 );
	controls.update();

	window.addEventListener( 'resize', onWindowResize, false );

	// stats
	stats = new Stats();
	container.appendChild( stats.dom );

}

function onWindowResize() {

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

	renderer.setSize( window.innerWidth, window.innerHeight );

}

//

function animate() {

	requestAnimationFrame( animate );

	var delta = clock.getDelta();

	if ( mixer ) mixer.update( delta );

	renderer.render( scene, camera );

	stats.update();

}

Interestingly, you can actually see the animated skeletons in glTF viewer.

@donmccurdy
Copy link
Collaborator Author

Nice, thanks! My code for determining the camera position doesn't take skinning into account when computing the bounding box, and I guess that makes a big difference in this case:

Screen Shot 2019-05-18 at 10 14 01 AM

Can consider this a bug in my viewer, then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants