Tfe

Ongi etorri tfe-ren webgunera...

Old stuff/old_sites/threejs/12_game/js/perso.js

(Deskargatu)
var Perso = function(game)
{
    var self=this;

    self.move_speed= 40;

    self.is_moving=false;
    self.in_rooms=[];

    this.load= function()
    {
        var self=this;

        this.step_sound = new Audio('sounds/step.mp3');
        this.step_sound.loop=true;
        this.step_sound.load();

        return new Promise(function(ok, reject)
        {
            var loader = new THREE.JSONLoader();
            loader.load( "blender/pingu_with_armature.json", function(geometry, mat)
            {
                self.perso_geo = geometry;
                self.perso_mat = mat;
                ok();
            });
        });
    };

    this.build = function(options, game)
    {
        this.game = game;
        this.options=options;

        this.create();
    };

    this.create =function()
    {
        var self=this;
        this.container = new THREE.Object3D();
        this.game.scene.add(this.container);

        // Cube simulating perso, for collision detection
        var cube_material = new THREE.MeshBasicMaterial( { color: 0x0000ff, wireframe:true, transparent:true, opacity: game.opt.debug_level>1 ? 1 : 0  } );
        var cube_geo = new THREE.PlaneGeometry(5 , 5);
        this.container_mesh = new THREE.Mesh(cube_geo, cube_material);
        this.container_mesh.rotation.x = Math.radians(90);
        this.container_mesh.rotation.z = Math.radians(45);
        this.container_mesh.position.y=0;
        this.container.add(this.container_mesh);

        this.container.position.x = this.options.x;
        this.container.position.y = 0;
        this.container.position.z = this.options.z;

        var materials = [];
        var mat1 = new THREE.MeshLambertMaterial({ color: 0xffff00} );
        mat1.skinning=true;
        mat1.morphTargets=true;

        var mat2 = new THREE.MeshLambertMaterial({ color: 0x00ff00} );
        mat2.skinning=true;
        mat2.morphTargets=true;

        var mat3 = new THREE.MeshLambertMaterial({ color: 0xff0000} );
        mat3.skinning=true;
        mat3.morphTargets=true;

        materials.push(mat1);
        materials.push(mat2);
        materials.push(mat3);
        materials.push(mat2);
        materials.push(mat1);


        //material.skinning = true;
        //material.morphTargets = true;


		var materials = self.perso_mat;
		for ( var i = 0; i < materials.length; i ++ ) {
			var m = materials[ i ];
			m.skinning = true;
			m.morphTargets = true;
		}
	
        this.mesh = new THREE.SkinnedMesh( self.perso_geo, new THREE.MultiMaterial(materials));
        this.mesh.scale.x=15;
        this.mesh.scale.y=15;
        this.mesh.scale.z=15;
        this.container.add(this.mesh);
        this.mesh.receiveShadow  = true;
        this.mesh.castShadow  = true;

        this.mesh.position.x = 0;
        this.mesh.position.y = 1;
        this.mesh.position.z = 0;

        this.mixer = new THREE.AnimationMixer( this.mesh );

        this.walkingClip = self.perso_geo.animations[2];
        this.iddlingClip = self.perso_geo.animations[1];

        this.move_action = this.mixer.clipAction(this.walkingClip, null ).setDuration(0.5);
        this.idle_action = this.mixer.clipAction(this.iddlingClip, null ).setDuration(5);

        this.move_action.play();
        this.idle_action.play();
        this.move_action.setEffectiveWeight(0);
        this.idle_action.setEffectiveWeight(1);
    };

    this.getRayPos= function(event)
    {
        var raycaster = new THREE.Raycaster();
        var mouse = new THREE.Vector2();
        mouse.x = ( event.clientX / this.game.renderer.domElement.width ) * 2 - 1;
        mouse.y = - ( event.clientY / this.game.renderer.domElement.height ) * 2 + 1;

        raycaster.setFromCamera( mouse, this.game.camera );

        var intersects = raycaster.intersectObjects( [this.game.click_ground], false );
        if ( intersects.length > 0 ) {
                return intersects[0].point;
        }
        return null;
    }

    this.lookAtEvent= function(event)
    {
        var pos = this.getRayPos(event);
        if(pos)
        {
            this.lookAt(pos);
        }
    }

    this.lookAt= function(pos)
    {
        if(this.container)
        {
            pos.y=0;
            this.container.lookAt(pos);
        }
    }

    this.moveToEvent= function(event)
    {
        var pos = this.getRayPos(event);
        if(pos)
        {
            this.lookAt(pos);
            this.moveTo(pos);
        }
    }

    this.moveTo= function(pos)
    {
        var current_pos = this.container.position;
        // Last part of moving
        if(current_pos.equals(pos))
        {
            return;
        }
        this.is_moving=true;

        // A: bottom right rectangle
        // B: start
        // C: destination
        var distance_ab = Math.abs(current_pos.x - pos.x);
        var distance_ac = Math.abs(current_pos.z - pos.z);
        var total = distance_ab + distance_ac;

        var ratio_x = (total-distance_ac) / total;
        var ratio_z = (total-distance_ab) / total;
        move_step_x = this.delta * this.move_speed * ratio_x;
        move_step_z = this.delta * this.move_speed * ratio_z;

        this.move_step_vector_x = new THREE.Vector2();
        this.move_step_vector_z = new THREE.Vector2();
        this.move_step_vector_x.x = current_pos.x>pos.x ?  (- move_step_x) : move_step_x;
        this.move_step_vector_x.z=0;
        this.move_step_vector_z.x=0;
        this.move_step_vector_z.z = current_pos.z>pos.z ?  (- move_step_z) : move_step_z;

        // Actually moving...
        this.move_destination = pos;
        this.move_weight_destination = 1;
        this.move_idx=0;
    };

    this.move_step= function()
    {
        if(this.is_moving)
        {
            this.step_sound.play();

            this.move_idx++;
            var moving=0;

            // Collision callbacks
            var originPoint_x = this.container.position.clone();
            var obstacles = game.getObstacles();
            var obstacles_with_callbacks = game.getCollisionCallbacks();

            var objects=[];
            for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
            {
                var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
                var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
                var directionVector = globalVertex.sub( this.container_mesh.position );

                var ray = new THREE.Raycaster( originPoint_x, directionVector.clone().normalize() );
                var collisionResults = ray.intersectObjects(obstacles_with_callbacks);
                if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) 
                {
                    objects.push(collisionResults[0].object);
                }
            }
            game.collisionCallbacks(this,objects);

            // Moving X restrictions
            if(Math.abs(this.container.position.x - this.move_destination.x) > this.move_speed*this.delta)
            {
                var originPoint_x = this.container.position.clone();
                originPoint_x.add(this.move_step_vector_x);

                var collision_x=false;

                for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
                {
                    var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
                    var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
                    var directionVector = globalVertex.sub( this.container_mesh.position );

                    var ray = new THREE.Raycaster( originPoint_x, directionVector.clone().normalize() );
                    var collisionResults = ray.intersectObjects(obstacles);
                    if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) 
                    {
                        collision_x=true;
                    }
                }
                if(!collision_x)
                {
                    moving++;
                    this.container.position.add(this.move_step_vector_x);
                }
            }

            // Moving Z restrictions
            if(Math.abs(this.container.position.z - this.move_destination.z) > this.move_speed*this.delta)
            {
                var originPoint_z = this.container.position.clone();
                originPoint_z.add(this.move_step_vector_z);
                var collision_z=false;

                for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
                {       
                    var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
                    var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
                    var directionVector = globalVertex.sub( this.container_mesh.position );

                    var ray = new THREE.Raycaster( originPoint_z, directionVector.clone().normalize() );
                    var collisionResults = ray.intersectObjects(obstacles);
                    if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) 
                    {
                        collision_z=true;
                    }
                }
                if(!collision_z)
                {
                    moving++;
                    this.container.position.add(this.move_step_vector_z);
                }
            }

            if(!moving)
            {
                this.step_sound.pause();
                this.move_weight_destination = 0;
                this.is_moving=false;
                this.move_destination=null;
            }
        }
        else
        {
            //this.move_action.stop();
        }
    };

    this.move_weight  = function()
    {
        if(this.move_weight_destination!==null)
        {
            var c = this.move_action.getEffectiveWeight();
            var dest;
            if(c>this.move_weight_destination)
            {
                var dest = Math.max(0,c-0.1);
                this.move_action.setEffectiveWeight(dest);
                this.idle_action.setEffectiveWeight(1-dest);
            }
            else if(c<this.move_weight_destination)
            {
                var dest = Math.min(1,c+0.1);
                this.move_action.setEffectiveWeight(dest);
                this.idle_action.setEffectiveWeight(1-dest);
            }
            else
            {
                this.move_weight_destination=null;
            }
        }
    };

    this.moveable = function()
    {
        var self=this;
        this.trigger_move=false;
        this.move_event = null;
        document.addEventListener( 'mousemove', function(e) { if(self.trigger_move) { self.move_event=e; self.moveToEvent(e); } }, false );
        document.addEventListener( 'mouseup', function(e) { self.move_event=null;self.trigger_move=false; e.stopPropagation(); return false; }, false);
        document.addEventListener( 'mousedown', function(e) { self.move_event=e; self.trigger_move=true;e.stopPropagation(); self.moveToEvent(e);  return false; }, false);
    };

    this.update= function(delta)
    {
        this.mixer.update(delta);
        this.delta=delta;
        if(this.move_event)
        {
            this.moveToEvent(this.move_event);
        }


        this.move_step();
        this.move_weight();
    };

};