Skip to content

Instantly share code, notes, and snippets.

@edom18
Created August 24, 2013 00:25
Show Gist options
  • Save edom18/6325224 to your computer and use it in GitHub Desktop.
Save edom18/6325224 to your computer and use it in GitHub Desktop.
パシフィック・リムのイェーガーモデルを読み込ませてみた
#パシフィック・リムのイェーガーのモデルデータが配布されていたのでThree.jsで読み込ませてみた。
[更新履歴]
* [2013.08.27] 視点を変えてダイナミックに見えるように修正。
* [2013.08.26] Walkアニメーションをちょっとだけ最適化。ビル群モデルを追加。
* [2013.08.24] BlenderのIKを使ってアニメーションをつけてみた。だいぶぎこちないけどw
TrackballControlsを使ってカメラの位置をマウスから操作できるようにした。
@import "compass/reset";
img, canvas {
vertical-align: top;
}
#ctrl {
position: absolute;
left: 0;
top: 0;
}
<script type="x-shader/x-vertex" id="vs">
uniform bool edge;
varying vec3 vNormal;
void main(void) {
vec3 pos = position;
if (edge) {
pos += normal * 0.04;
}
vNormal = normal;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fs">
precision mediump float;
uniform vec3 lightDirection;
uniform sampler2D texture;
uniform vec4 edgeColor;
varying vec3 vNormal;
void main(void) {
if (edgeColor.a > 0.0) {
gl_FragColor = edgeColor;
}
else {
float diffuse = clamp(dot(vNormal, lightDirection), 0.0, 1.0);
vec4 smpColor = texture2D(texture, vec2(diffuse, 0.0));
gl_FragColor = smpColor;
}
}
</script>
(function (win, doc) {
'use strict';
var container, camera, controls, scene,
projector, renderer, model,
globalLight,
clock,
//for skybox.
sceneCube, cameraCube, textureCube, meshCube;
//for model information.
var modelUrl = 'http://resources.edo-m18.me/models/gips-danger/gips-danger_rig.js';
var modelFrames = {
walk: [0, 32, 15, {state: 'stand', action: false}],
run : [0, 72, 30, {state: 'stand', action: false}]
};
var groundTextureUrl = 'http://jsrun.it/assets/h/M/n/q/hMnqT.jpg';
//
function createModel(geometry, materials) {
var facematerial;
var scale = 17;
if (materials) {
for (var i = 0; i < materials.length; i++) {
materials[i].morphTargets = true;
}
facematerial = new THREE.MeshFaceMaterial(materials);
}
else {
facematerial = new THREE.MeshLambertMaterial({color: 0xcccccc});
facematerial.morphTargets = true;
}
model = new THREE.MorphAnimMesh(geometry, facematerial);
model.scale.set(scale, scale, scale);
model.position.set(-70, 0, -400);
model.castShadow = true;
model.receiveShadow = true;
model.setFrameRange(modelFrames.walk[0], modelFrames.walk[1]);
scene.add(model);
animate();
}
/**
* Initialize sky box.
*/
function initSkybox() {
//Skyebox用のシーン、カメラを生成
sceneCube = new THREE.Scene();
cameraCube = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 1, 10000);
cameraCube.position.y = -50;
sceneCube.add(cameraCube);
//p = positive, n = negative
var urls = [
'/assets/k/z/5/Y/kz5YB.jpg',
'/assets/x/P/8/J/xP8JV.jpg',
'/assets/p/S/A/e/pSAes.jpg',
'/assets/4/v/3/x/4v3xz.jpg',
'/assets/g/a/G/S/gaGSG.jpg',
'/assets/x/z/w/I/xzwIo.jpg'
];
//キューブマップ用にテクスチャをロード
textureCube = THREE.ImageUtils.loadTextureCube(urls);
//
var shader, material;
//Skyebox用にデフォルトで準備されているシェーダを読み込み
shader = THREE.ShaderLib.cube;
//キューブマップ用テクスチャを、uniform変数「tCube」にアップロード
shader.uniforms.tCube.value = textureCube;
//上記のシェーダを、ShaderMaterialとしてマテリアルを生成
material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader : shader.vertexShader,
uniforms : shader.uniforms,
depthWrite : false,
side : THREE.BackSide
});
//Skyboxメッシュを生成
meshCube = new THREE.Mesh(new THREE.CubeGeometry(1000, 1000, 1000), material);
//生成したメッシュをSkybox用シーンに追加
sceneCube.add(meshCube);
}
/**
* Initialize ground plane.
*/
function initGround() {
var initColor, initTexture,
groundMaterial, groundTexture,
mesh;
initColor = new THREE.Color(0xaea893);
initTexture = THREE.ImageUtils.generateDataTexture(1, 1, initColor);
groundMaterial = new THREE.MeshPhongMaterial({color: 0xffffff, specular: 0x111111, map: initTexture});
groundTexture = THREE.ImageUtils.loadTexture(groundTextureUrl, undefined, function () { groundMaterial.map = groundTexture; });
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set(500, 500);
groundTexture.anisotropy = 6;
mesh = new THREE.Mesh(new THREE.PlaneGeometry(20000, 20000), groundMaterial);
mesh.rotation.x = -Math.PI / 2;
mesh.receiveShadow = true;
mesh.castShadow = true;
scene.add(mesh);
}
/**
* All of initialize to the WebGL scene.
*/
function init() {
container = doc.createElement('div');
doc.body.appendChild(container);
clock = new THREE.Clock();
camera = new THREE.PerspectiveCamera(50, win.innerWidth / win.innerHeight, 1, 10000);
camera.position.set(0, 30, 100);
camera.target = new THREE.Vector3(0, 200, 0);
camera.lookAt(0, 0, 0);
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 0.8;
controls.zoomSpeed = 0.5;
controls.panSpeed = 0.3;
//それぞれzoomなどをオフにする。デフォルトはfalse.
//controls.noRotate = false;
//controls.noZoom = false;
//controls.noPan = false;
//controls.staticMoving = false;
controls.dynamicDampingFactor = 0.5;
//
//Create a main scene.
scene = new THREE.Scene();
//
var d = 100;
var pos = d;
globalLight = new THREE.DirectionalLight(0xefefff, 2);
globalLight.position.set(-pos, pos, pos);//.normalize();
globalLight.castShadow = true;
globalLight.shadowMapWidth = 2048;
globalLight.shadowMapHeight = 2048;
globalLight.shadowCameraLeft = -d;
globalLight.shadowCameraRight = d;
globalLight.shadowCameraTop = d;
globalLight.shadowCameraBottom = -d;
globalLight.shadowCameraNear = 0.1;
globalLight.shadowCameraFar = 1000;
globalLight.shadowCameraFov = 40;
//globalLight.shadowCameraVisible = true;
globalLight.shadowBias = 0.0001;
globalLight.shadowDarkness = 0.5;
scene.add(globalLight);
var light2 = new THREE.DirectionalLight( 0xffefef, 2 );
light2.position.set(-1, -1, -1).normalize();
scene.add(light2);
//load a gips-danger
var loader = new THREE.JSONLoader();
loader.load(modelUrl, createModel);
//load buildings.
loader.load('http://resources.edo-m18.me/models/gips-danger/building.js', function (geometry, materials) {
var face_material,
s = 100;
if (materials) {
face_material = new THREE.MeshFaceMaterial(materials);
}
else {
face_material = new THREE.MeshLambertMaterial({color: 0xcccccc});
}
var building = new THREE.Mesh(geometry, face_material);
building.scale.set(s, s, s);
building.position.y += 35;
building.castShadow = true;
building.receiveShadow = true;
scene.add(building);
});
//
initGround();
initSkybox();
//
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.sortObjects = false;
renderer.setSize(win.innerWidth, win.innerHeight);
renderer.setClearColor(0x000000, 1);
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFShadowMap;
renderer.autoClear = false;
container.appendChild(renderer.domElement);
//
win.addEventListener('resize', onWindowResize, false);
}
//
function onWindowResize() {
camera.aspect = win.innerWidth / win.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(win.innerWidth, win.innerHeight);
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
//
//var duration = 5000,
// keyframes = 30,
// lastKeyframe = 0,
// currentKeyframe = 0,
// interpolation = duration / keyframes;
function render() {
//camera.lookAt(camera.target);
if (model) {
var delta = clock.getDelta();
model.updateAnimation(500 * delta);
//camera.position.copy(model.position);
//camera.position.z += 50;
var target = new THREE.Vector3(0, 0, 0);
target.copy(model.position);
target.y += 50;
camera.target = target;
//if (model.morphTargetInfluences) {
// // Alternate morph targets
// var time = Date.now() % duration;
// var keyframe = Math.floor(time / interpolation);
// if (keyframe != currentKeyframe) {
// model.morphTargetInfluences[lastKeyframe] = 0;
// model.morphTargetInfluences[currentKeyframe] = 1;
// model.morphTargetInfluences[keyframe] = 0;
// lastKeyframe = currentKeyframe;
// currentKeyframe = keyframe;
// }
// model.morphTargetInfluences[keyframe] = (time % interpolation) / interpolation;
// model.morphTargetInfluences[lastKeyframe] = 1 - model.morphTargetInfluences[keyframe];
//}
}
renderer.clear();
renderer.render(sceneCube, cameraCube);
renderer.render(scene, camera);
controls.update();
}
//A = left, S = back, D = right, W = front
var A = 97, S = 115, D = 100, W = 119;
var vec = new THREE.Vector3();
var xAxis = new THREE.Vector3(1, 0, 0);
var sp = 2;
doc.addEventListener('keypress', function (e) {
if (!/97|115|100|119/.test(e.keyCode)) {
return;
}
var delta = vec.subVectors(camera.target, camera.position).normalize();
var deg = THREE.Math.radToDeg(Math.acos(xAxis.dot(delta)));
var rad, x, z;
switch (e.keyCode) {
case A:
deg += 90;
break;
case S:
deg += 180;
break;
case D:
deg += -90;
break;
case W:
break;
}
rad = THREE.Math.degToRad(deg);
x = Math.cos(rad);
z = Math.sin(rad);
model.position.x += x * sp;
model.position.z -= z * sp;
}, false);
//
doc.addEventListener('DOMContentLoaded', init, false);
}(window, document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment