webgl 关键帧动画-运动的小机器人

本文通过WebGL库three.js展示了如何制作关键帧动画,具体是一个运动的小机器人展示。通过阅读源码,读者可以深入了解WebGL动画原理和three.js的应用。

以下是源码,将代码复制到文本文件保存成html文件:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Articulated Animation with key frames</title> 

        <link rel="stylesheet" type="text/css" href="./css/webglbook.css">
        <script src="./libs/Three.js"></script>
        <script type="text/javascript" src="./libs/Tween.js"></script>
        <script type="text/javascript" src="./libs/jquery-1.6.4.js"></script>
        <script type="text/javascript" src="./libs/jquery.mousewheel.js"></script>
        <script type="text/javascript" src="./libs/RequestAnimationFrame.js"></script>
        <script type="text/javascript" src="./sim/sim.js"></script>
        <script type="text/javascript" src="./sim/animation.js"></script>
        <script type="text/javascript" src="./sim/ColladaLoader.js"></script>
        <script type="text/javascript" src="./keyframe-robot.js"></script>
        <script type="text/javascript">
        var renderer = null;
        var scence = null;
        var camera = null;
        var mesh = null;
        $(document).ready(
        	function(){
        		var container = document.getElementById("container");
        		var app = new RobotApp();
        		app.init({container:container});
        		app.run();
        	}
        	)
        </script>
    </head>
    <body style="background-color:#115396;">
    	<center><h1>Articulated Animation with key frames</h1></center>
    	<div id="container" style="width:95%;height:80%;position:absolute"></div>
    	<div id="prompt" style="width:95%;height:6%;bottom: 0;text-align: center;position: absolute"></div>
    </body>
</html>

将代码复制到文本文件保存keyframe-robot.js

/* 
* @Author: omni360
* @Date:   2014-09-01 20:19:30
* @Last Modified by:   omni360
* @Last Modified time: 2014-09-02 21:33:09
*/
//构造函数
RobotApp = function()
{
	Sim.App.call(this);
}

// 继承Sim.app
RobotApp.prototype = new Sim.App();

//我们的自定义初始化函数
RobotApp.prototype.init = function(param){
	//调用父类初始化场景,相机,渲染器等
	Sim.App.prototype.init.call(this,param);

	//创建平行光照亮机器人
	var light = new THREE.DirectionalLight( 0xeeeeff, 1 );
	light.position.set(0,0,1);
	this.scene.add(light);

	this.camera.position.set(0,2.333,8);

	//创建机器人并且添加到我们的sim
	var robot = new Robot();
	robot.init();
	this.addObject(robot);

	//渲染机器人y轴
	this.root.rotation.y = Math.PI / 4;
	this.robot = robot;
	this.animating = false;
	this.robot.subscribe("complete",this,this.onAnimationComplete);
}

RobotApp.prototype.update = function(){
	this.root.rotation.y += 0.005;
	Sim.App.prototype.update.call(this);
}
RobotApp.prototype.handleMouseUp = function(x,y){
	this.animating = !this.animating;
	this.robot.animate(this.animating);
}
RobotApp.prototype.onAnimationComplete = function(){
	this.animating = false;
}
RobotApp.aniamteion_time = 1111;
//robot 类
Robot = function(){
	Sim.Object.call(this);
}
Robot.prototype = new Sim.Object();

Robot.prototype.init = function(){
	//创建装在机器人的群组
	var bodygroup = new THREE.Object3D;
	//把对象反馈给框架
	this.setObject3D(bodygroup);
	var that = this;
	//机器人模型来自-htpp://www.turbosquid.com/fullpreview/index.cfm/47363
	//已获得授权
	var url='./models/robot_cartoon_02/robot_cartoon_02.dae';
	var loader = new Sim.ColladaLoader;
	loader.load(url,function(data){
		that.handleLoaded(data)
	});
}

Robot.prototype.handleLoaded = function(data){
	if(data){
		var model = data.scene;
		//这个模型使用的单位是厘米,而我们工作单位是米,所以要进行转换
		model.scale.set(.01,.01,.01);

		this.object3D.add(model);

		//遍历模型寻找带有名称的各个部分。
		var that = this;
		THREE.SceneUtils.traverseHierarchy(model,function(n){that.traverseCallback(n);});
		this.createAnimation();
	}
}

Robot.prototype.traverseCallback = function(n)
{
	//找到需要发生动画效果的各个部分
	switch (n.name)
	{
		case 'jambe_G' :
			this.left_leg = n;
			break;
		case 'jambe_D' :
			this.right_leg = n;
			break;
		case 'head_container' :
			this.head = n;
			break;
		case 'clef' :
			this.key = n;
			break;
		default :
			break;
	}
}
Robot.prototype.createAnimation = function(){
	this.animator = new Sim.KeyFrameAnimator;
	this.animator.init({
		interps:
		[
			{keys:Robot.bodyRotationKeys,values:Robot.bodyRotationValues,target:this.object3D.rotation},
			    { keys:Robot.headRotationKeys, values:Robot.headRotationValues, target:this.head.rotation }, 
			    { keys:Robot.keyRotationKeys, values:Robot.keyRotationValues, target:this.key.rotation }, 
			    { keys:Robot.leftLegRotationKeys, values:Robot.leftLegRotationValues, target:this.left_leg.rotation }, 
			    { keys:Robot.rightLegRotationKeys, values:Robot.rightLegRotationValues, target:this.right_leg.rotation },
		],
		loop:true,
		duration:RobotApp.aniamteion_time
	});
	this.animator.subscribe("complete",this,this.onAnimationComplete);
	this.addChild(this.animator);
}

Robot.prototype.animate = function(on){
	if(on){
		this.animator.start();
	}
	else{
		this.animator.stop();
	}
}
Robot.prototype.onAnimationComplete = function(){
	this.publish("complete");
}
Robot.headRotationKeys = [0, .25, .5, .75, 1];
Robot.headRotationValues = [ { z: 0 }, 
                                { z: -Math.PI / 96 },
                                { z: 0 },
                                { z: Math.PI / 96 },
                                { z: 0 },
                                ];

Robot.bodyRotationKeys = [0, .25, .5, .75, 1];
Robot.bodyRotationValues = [ { x: 0 }, 
                                { x: -Math.PI / 48 },
                                { x: 0 },
                                { x: Math.PI / 48 },
                                { x: 0 },
                                ];

Robot.keyRotationKeys = [0, .25, .5, .75, 1];
Robot.keyRotationValues = [ { x: 0 }, 
                                { x: Math.PI / 4 },
                                { x: Math.PI / 2 },
                                { x: Math.PI * 3 / 4 },
                                { x: Math.PI },
                                ];

Robot.leftLegRotationKeys = [0, .25, .5, .75, 1];
Robot.leftLegRotationValues = [ { z: 0 }, 
                                { z: Math.PI / 6},
                                { z: 0 },
                                { z: 0 },
                                { z: 0 },
                                ];

Robot.rightLegRotationKeys = [0, .25, .5, .75, 1];
Robot.rightLegRotationValues = [ { z: 0 }, 
                                { z: 0 },
                                { z: 0 },
                                { z: Math.PI / 6},
                                { z: 0 },
                                ];


跟多依赖文件到下面路径下载

收拾收拾

https://github.com/omni360/omni360.github.io/tree/master/webgl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值