pailhead / three-instanced-mesh

wrapper around THREE.InstancedBufferGeometry
MIT License
109 stars 14 forks source link

Hot to play gltf.animations? #20

Open hookex opened 5 years ago

hookex commented 5 years ago
import * as THREE from "three";
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
import {getRandomPosition} from "./util";
import {Warehouse} from "./index";

const InstancedMesh = require('three-instanced-mesh')(THREE);
const manCount = 100;

export function initManInstance(group) {
    const gltfLoader = new GLTFLoader();

    gltfLoader.load('/src/models/man/CesiumMan.gltf', (gltf) => {
        gltf.scene.traverse(function (child) {
            if (child.isMesh) {
                if (child.castShadow !== undefined) {
                    child.castShadow = true;
                }
                console.log("mesh", child);
            }
        });

        const root = gltf.scene;
        const man = root.getObjectByName('Cesium_Man');

        if (!man) {
            return;
        }

        const fix = {
            rot: [-Math.PI / 2, -Math.PI / 2, 0],
            scalar: 50,
        };

        man.geometry.rotateX(fix.rot[0]);
        man.geometry.rotateY(fix.rot[1]);
        man.geometry.rotateZ(fix.rot[2]);
        man.geometry.scale(fix.scalar, fix.scalar, fix.scalar);
        const box = new THREE.Box3().setFromObject(man);
        const length = box.getSize().x / 2;
        man.position.set(length / 2, 0, length / 2);

        const cluster = new InstancedMesh(
            man.geometry,
            man.material,
            manCount,
            true,
            false,
            true,
        );

        let v3 = new THREE.Vector3();
        let quaternion = new THREE.Quaternion();

        let subCount = parseInt(Math.sqrt(manCount))

        let index = 0;
        for (let i = 0; i < subCount; i++) {
            for (let j = 0; j < subCount; j++) {
                index++;
                const {x, z} = getRandomPosition(Warehouse.width, Warehouse.length - Warehouse.unit * 8);
                cluster.setQuaternionAt(index, quaternion);
                cluster.setPositionAt(index, v3.set(x + Warehouse.unit / 2, 0, z + Warehouse.unit / 2));
                cluster.setScaleAt(index, v3.set(1, 1, 1));
            }
        }

        // new THREE.AnimationMixer(instance).clipAction(gltf.animations[0]).play();

        Warehouse.manCluster = cluster;
        group.add(cluster);
    });
}
barnabasbartha commented 5 years ago

I guess InstancedMesh copies the given geometry, so to see the animation working you may need to update that in every frame.

hookex commented 5 years ago

I guess InstancedMesh copies the given geometry, so to see the animation working you may need to update that in every frame.

It is difficult to code, and there are challenges in performance.

pailhead commented 5 years ago

I guess InstancedMesh copies the given geometry, so to see the animation working you may need to update that in every frame.

yeah, that is a limitation right now :(. Will look into this. No morphing or anything has been implemented or tested, it's dynamic in a sense that it can move rigid bodies around.

hookex commented 5 years ago

I guess InstancedMesh copies the given geometry, so to see the animation working you may need to update that in every frame.

yeah, that is a limitation right now :(. Will look into this. No morphing or anything has been implemented or tested, it's dynamic in a sense that it can move rigid bodies around.

Do you have any idea? Hope to be shared!😀