提交 e1f5bb83 编写于 作者: Z zz85

Merge remote-tracking branch 'alteredq/dev'

因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.MD2CharacterComplex = function () {
var scope = this;
this.scale = 1;
// animation parameters
this.animationFPS = 6;
this.transitionFrames = 15;
// movement model parameters
this.maxSpeed = 275;
this.maxReverseSpeed = -275;
this.frontAcceleration = 600;
this.backAcceleration = 600;
this.frontDecceleration = 600;
this.angularSpeed = 2.5;
// rig
this.root = new THREE.Object3D();
this.meshBody = null;
this.meshWeapon = null;
this.controls = null;
// skins
this.skinsBody = [];
this.skinsWeapon = [];
this.weapons = [];
this.currentSkin = undefined;
//
this.onLoadComplete = function () {};
// internals
this.meshes = [];
this.animations = {};
this.loadCounter = 0;
// internal movement control variables
this.speed = 0;
this.bodyOrientation = 0;
this.walkSpeed = this.maxSpeed;
this.crouchSpeed = this.maxSpeed * 0.5;
// internal animation parameters
this.activeAnimation = null;
this.oldAnimation = null;
// API
this.enableShadows = function ( enable ) {
for ( var i = 0; i < this.meshes.length; i ++ ) {
this.meshes[ i ].castShadow = enable;
this.meshes[ i ].receiveShadow = enable;
}
};
this.setVisible = function ( enable ) {
for ( var i = 0; i < this.meshes.length; i ++ ) {
this.meshes[ i ].visible = enable;
this.meshes[ i ].visible = enable;
}
};
this.shareParts = function ( original ) {
this.animations = original.animations;
this.walkSpeed = original.walkSpeed;
this.crouchSpeed = original.crouchSpeed;
this.skinsBody = original.skinsBody;
this.skinsWeapon = original.skinsWeapon;
// BODY
var mesh = createPart( original.meshBody.geometry, this.skinsBody[ 0 ] );
mesh.scale.set( this.scale, this.scale, this.scale );
this.root.position.y = original.root.position.y;
this.root.add( mesh );
this.meshBody = mesh;
this.meshes.push( mesh );
// WEAPONS
for ( var i = 0; i < original.weapons.length; i ++ ) {
var mesh = createPart( original.weapons[ i ].geometry, this.skinsWeapon[ i ] );
mesh.scale.set( this.scale, this.scale, this.scale );
mesh.visible = false;
mesh.name = name;
this.root.add( mesh );
this.weapons[ i ] = mesh;
this.meshWeapon = mesh;
this.meshes.push( mesh );
}
};
this.loadParts = function ( config ) {
this.animations = config.animations;
this.walkSpeed = config.walkSpeed;
this.crouchSpeed = config.crouchSpeed;
this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
var weaponsTextures = []
for ( var i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ];
// SKINS
this.skinsBody = loadTextures( config.baseUrl + "skins/", config.skins );
this.skinsWeapon = loadTextures( config.baseUrl + "skins/", weaponsTextures );
// BODY
var loader = new THREE.JSONLoader();
loader.load( config.baseUrl + config.body, function( geo ) {
geo.computeBoundingBox();
scope.root.position.y = - scope.scale * geo.boundingBox.min.y;
var mesh = createPart( geo, scope.skinsBody[ 0 ] );
mesh.scale.set( scope.scale, scope.scale, scope.scale );
scope.root.add( mesh );
scope.meshBody = mesh;
scope.meshes.push( mesh );
checkLoadingComplete();
} );
// WEAPONS
var generateCallback = function ( index, name ) {
return function( geo ) {
var mesh = createPart( geo, scope.skinsWeapon[ index ] );
mesh.scale.set( scope.scale, scope.scale, scope.scale );
mesh.visible = false;
mesh.name = name;
scope.root.add( mesh );
scope.weapons[ index ] = mesh;
scope.meshWeapon = mesh;
scope.meshes.push( mesh );
checkLoadingComplete();
}
}
for ( var i = 0; i < config.weapons.length; i ++ ) {
loader.load( config.baseUrl + config.weapons[ i ][ 0 ], generateCallback( i, config.weapons[ i ][ 0 ] ) );
}
};
this.setPlaybackRate = function ( rate ) {
if ( this.meshBody ) this.meshBody.duration = this.meshBody.baseDuration / rate;
if ( this.meshWeapon ) this.meshWeapon.duration = this.meshWeapon.baseDuration / rate;
};
this.setWireframe = function ( wireframeEnabled ) {
if ( wireframeEnabled ) {
if ( this.meshBody ) this.meshBody.material = this.meshBody.materialWireframe;
if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialWireframe;
} else {
if ( this.meshBody ) this.meshBody.material = this.meshBody.materialTexture;
if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialTexture;
}
};
this.setSkin = function( index ) {
if ( this.meshBody && this.meshBody.material.wireframe === false ) {
this.meshBody.material.map = this.skinsBody[ index ];
this.currentSkin = index;
}
};
this.setWeapon = function ( index ) {
for ( var i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false;
var activeWeapon = this.weapons[ index ];
if ( activeWeapon ) {
activeWeapon.visible = true;
this.meshWeapon = activeWeapon;
if ( this.activeAnimation ) {
activeWeapon.playAnimation( this.activeAnimation );
this.meshWeapon.setAnimationTime( this.activeAnimation, this.meshBody.getAnimationTime( this.activeAnimation ) );
}
}
};
this.setAnimation = function ( animationName ) {
if ( animationName === this.activeAnimation || !animationName ) return;
if ( this.meshBody ) {
this.meshBody.setAnimationWeight( animationName, 0 );
this.meshBody.playAnimation( animationName );
this.oldAnimation = this.activeAnimation;
this.activeAnimation = animationName;
this.blendCounter = this.transitionFrames;
}
if ( this.meshWeapon ) {
this.meshWeapon.setAnimationWeight( animationName, 0 );
this.meshWeapon.playAnimation( animationName );
}
};
this.update = function ( delta ) {
if ( this.controls ) this.updateMovementModel( delta );
if ( this.animations ) {
this.updateBehaviors( delta );
this.updateAnimations( delta );
}
};
this.updateAnimations = function ( delta ) {
var mix = 1;
if ( this.blendCounter > 0 ) {
mix = ( this.transitionFrames - this.blendCounter ) / this.transitionFrames;
this.blendCounter -= 1;
}
if ( this.meshBody ) {
this.meshBody.update( delta );
this.meshBody.setAnimationWeight( this.activeAnimation, mix );
this.meshBody.setAnimationWeight( this.oldAnimation, 1 - mix );
}
if ( this.meshWeapon ) {
this.meshWeapon.update( delta );
this.meshWeapon.setAnimationWeight( this.activeAnimation, mix );
this.meshWeapon.setAnimationWeight( this.oldAnimation, 1 - mix );
}
};
this.updateBehaviors = function ( delta ) {
var controls = this.controls;
var animations = this.animations;
var moveAnimation, idleAnimation;
// crouch vs stand
if ( controls.crouch ) {
moveAnimation = animations[ "crouchMove" ];
idleAnimation = animations[ "crouchIdle" ];
} else {
moveAnimation = animations[ "move" ];
idleAnimation = animations[ "idle" ];
}
// actions
if ( controls.jump ) {
moveAnimation = animations[ "jump" ];
idleAnimation = animations[ "jump" ];
}
if ( controls.attack ) {
if ( controls.crouch ) {
moveAnimation = animations[ "crouchAttack" ];
idleAnimation = animations[ "crouchAttack" ];
} else {
moveAnimation = animations[ "attack" ];
idleAnimation = animations[ "attack" ];
}
}
// set animations
if ( controls.moveForward || controls.moveBackward || controls.moveLeft || controls.moveRight ) {
if ( this.activeAnimation !== moveAnimation ) {
this.setAnimation( moveAnimation );
}
}
if ( Math.abs( this.speed ) < 0.2 * this.maxSpeed && !( controls.moveLeft || controls.moveRight ) ) {
if ( this.activeAnimation !== idleAnimation ) {
this.setAnimation( idleAnimation );
}
}
// set animation direction
if ( controls.moveForward ) {
if ( this.meshBody ) {
this.meshBody.setAnimationDirectionForward( this.activeAnimation );
this.meshBody.setAnimationDirectionForward( this.oldAnimation );
}
if ( this.meshWeapon ) {
this.meshWeapon.setAnimationDirectionForward( this.activeAnimation );
this.meshWeapon.setAnimationDirectionForward( this.oldAnimation );
}
}
if ( controls.moveBackward ) {
if ( this.meshBody ) {
this.meshBody.setAnimationDirectionBackward( this.activeAnimation );
this.meshBody.setAnimationDirectionBackward( this.oldAnimation );
}
if ( this.meshWeapon ) {
this.meshWeapon.setAnimationDirectionBackward( this.activeAnimation );
this.meshWeapon.setAnimationDirectionBackward( this.oldAnimation );
}
}
};
this.updateMovementModel = function ( delta ) {
var controls = this.controls;
// speed based on controls
if ( controls.crouch ) this.maxSpeed = this.crouchSpeed;
else this.maxSpeed = this.walkSpeed;
this.maxReverseSpeed = -this.maxSpeed;
if ( controls.moveForward ) this.speed = THREE.Math.clamp( this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed );
if ( controls.moveBackward ) this.speed = THREE.Math.clamp( this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed );
// orientation based on controls
// (don't just stand while turning)
var dir = 1;
if ( controls.moveLeft ) {
this.bodyOrientation += delta * this.angularSpeed;
this.speed = THREE.Math.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed );
}
if ( controls.moveRight ) {
this.bodyOrientation -= delta * this.angularSpeed;
this.speed = THREE.Math.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed );
}
// speed decay
if ( ! ( controls.moveForward || controls.moveBackward ) ) {
if ( this.speed > 0 ) {
var k = exponentialEaseOut( this.speed / this.maxSpeed );
this.speed = THREE.Math.clamp( this.speed - k * delta * this.frontDecceleration, 0, this.maxSpeed );
} else {
var k = exponentialEaseOut( this.speed / this.maxReverseSpeed );
this.speed = THREE.Math.clamp( this.speed + k * delta * this.backAcceleration, this.maxReverseSpeed, 0 );
}
}
// displacement
var forwardDelta = this.speed * delta;
this.root.position.x += Math.sin( this.bodyOrientation ) * forwardDelta;
this.root.position.z += Math.cos( this.bodyOrientation ) * forwardDelta;
// steering
this.root.rotation.y = this.bodyOrientation;
};
// internal helpers
function loadTextures( baseUrl, textureUrls ) {
var mapping = new THREE.UVMapping();
var textures = [];
for ( var i = 0; i < textureUrls.length; i ++ ) {
textures[ i ] = THREE.ImageUtils.loadTexture( baseUrl + textureUrls[ i ], mapping, checkLoadingComplete );
textures[ i ].name = textureUrls[ i ];
}
return textures;
};
function createPart( geometry, skinMap ) {
geometry.computeMorphNormals();
var whiteMap = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color( 0xffffff ) );
var materialWireframe = new THREE.MeshPhongMaterial( { color: 0xffaa00, specular: 0x111111, shininess: 50, wireframe: true, shading: THREE.SmoothShading, map: whiteMap, morphTargets: true, morphNormals: true, perPixel: true, metal: true } );
var materialTexture = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 50, wireframe: false, shading: THREE.SmoothShading, map: skinMap, morphTargets: true, morphNormals: true, perPixel: true, metal: true } );
materialTexture.wrapAround = true;
//
var mesh = new THREE.MorphBlendMesh( geometry, materialTexture );
mesh.rotation.y = -Math.PI/2;
//
mesh.materialTexture = materialTexture;
mesh.materialWireframe = materialWireframe;
//
mesh.autoCreateAnimations( scope.animationFPS );
return mesh;
};
function checkLoadingComplete() {
scope.loadCounter -= 1;
if ( scope.loadCounter === 0 ) scope.onLoadComplete();
};
function exponentialEaseOut( k ) { return k === 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1; }
};
......@@ -1410,7 +1410,9 @@ THREE.ShaderExtras = {
"fogNear": { type: "f", value: 5 },
"fogFar": { type: "f", value: 100 },
"fogEnabled": { type: "i", value: 0 },
"aoClamp": { type: "f", value: 0.3 }
"onlyAO": { type: "i", value: 0 },
"aoClamp": { type: "f", value: 0.3 },
"lumInfluence": { type: "f", value: 0.9 }
},
......@@ -1436,10 +1438,13 @@ THREE.ShaderExtras = {
"uniform float fogNear;",
"uniform float fogFar;",
"uniform bool fogEnabled;",
"uniform bool fogEnabled;", // attenuate AO with linear fog
"uniform bool onlyAO;", // use only ambient occlusion pass?
"uniform vec2 size;", // texture width, height
"uniform float aoClamp;", // depth clamp - reduces haloing at screen edges
"uniform vec2 size;", // texture width, height
"uniform float aoClamp;", // depth clamp - reduces haloing at screen edges
"uniform float lumInfluence;", // how much luminance affects occlusion
"uniform sampler2D tDiffuse;",
"uniform sampler2D tDepth;",
......@@ -1465,13 +1470,14 @@ THREE.ShaderExtras = {
"const float radius = 5.0;", // ao radius
"const bool useNoise = false;", // use noise instead of pattern for sample dithering
"const float noiseAmount = 0.0002;", // dithering amount
"const float noiseAmount = 0.0003;", // dithering amount
"const float diffArea = 0.4;", // self-shadowing reduction
"const float gDisplace = 0.4;", // gauss bell center
"const bool onlyAO = false;", // use only ambient occlusion pass?
"const float lumInfluence = 0.3;", // how much luminance affects occlusion
"const vec3 onlyAOColor = vec3( 1.0, 0.7, 0.5 );",
//"const vec3 onlyAOColor = vec3( 1.0, 1.0, 1.0 );",
// RGBA depth
......@@ -1626,7 +1632,7 @@ THREE.ShaderExtras = {
"if ( onlyAO ) {",
"final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only
"final = onlyAOColor * vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only
"}",
......
10/11/98
================================================================
Model Name : Ogro
installation directory : quake2/baseq2/players/ogro
Model Author : Magarnigal
email :mellor@netgazer.net.au
homepage :http://magarn.3dpalette.com
Skins Author : Ogro_Fix
email : ogro_fix@yahoo.com
homepage : http://www.fondation.com/pandemonium
Additional info : Fix has included a cloth and ogrobase skin that people may use as a base for skinning ogro. The
mapping can be a bit confusing, 2d skinners beware.
Additional skin by : Deranged - (Sharokh)
email : deranged@deathsdoor.com
homepage : http://www.gibbed.com/thebin
Ogrific law:
An Ogro is similar to an ogre, but why the O?? In French ogre is pronounced ogrr, not oger, also 'gros' means to be fat/big...so ogre - gros makes Ogro! After all, it's cuter than just ogre :).
The Ogro is smaller than a normal ogre, but just as fat and only slightly less stupid. As opposed to common belief, he is not an evil creature, only killing as is absolutely necessary.
Imagine, if you will, an Ogro in the subway. As he enters the carriage, people become plastered to the walls due to Ogro's size. He's too big! Ahh well, maybe Ogro should just sit on one of these tiny seats...a strange sound can be heard (sproottch). Imagine now, the look of an astonished ogro...huh?!? Standing up, he looks at the seat. OMFO! (oh my fucking ogrod!)! Where a little old grandma had been sitting, now looks more like a pizza! But, I swear, it was a grandma!
This sort of occurrence is common to an Ogro...its in their nature. when you want to talk to an ogro, stay at good distance (better if you call him from behind), as his movements are rather "uncontrolled", and you might cop a smash in the face!
A special diet is required for Ogros. When they're babies (ogrillons), their mum's (ogresses) give them copious amounts of chili con carne, canned beans and the like. The result of this carefully structured diet produces an Ogro capable of immense farting achievements.
The ogro is just full of bad smells. That's not to say he's not clean. An ogro will wash himself often (doesn't fear water as opposed to trolls). The problem lies in his intestinal flora (and fauna). all his orifices (ogrifices?) are used for ogrific spells. (green clouds, etc..). Nothing can be done against this kind of onslaught, except to run or stop breathing.
It's a useful trait to have in the subway. people will often leave the carriage, trying to find the culprit. (Although all that is need it to look at the face of the ogro: he's
happy, he farted well, and it smells really bad).
Ogro's existed long before humans. In fact, one school of thought holds to the theory that humans are a degenerated version of Ogro, more intelligent, but evil.
Hidden Ogro's of today include: Obelix, fat boy slim, any Sumo, Amish (braveheart movie), slamfist (small soldiers movie), bud spencer, etc...
Additional Credits to : id software, Howzer, Rod,
================================================================
* Play Information *
New Sounds : Yes, original sounds from Eric vonRothkirch of 'The Coven', email him
at redchurch@uswest.net
CTF Skins : yes
VWEP Support : yes, standard Id weapons with modified, ogrific skins.
* Construction *
Poly Counts
Tris.md2 : 670
weapon.md2 : 122
Vert Counts
tris.md2 : 358 - anyone actually need this number?
weapon.md2 : 74
Skin Wastage
tris.md2 : 1%
weapon.md2 : 2%
Skin Count : 14
Base : none
A background to some of the skins:
Grok: the standard cyberpunk ogro
freedom: this one is dedicated to braveheart.
gib: this one didn't know how to use the ogrific mixer (used to make mammoth steaks), and jumped into it..the mixer did all the work.
slaanesh: this one is an evil ogro, serving the god of lust.
Khorne: this one is even more evil than slaanesh, serving the god of blood and violence.
Nabogro: it's a dwarf (yeah, well, it was), he's a trollslayer. In french nabot means small/dwarfy, so, nabogro went logically.
darkam: hoo, this one is a troll! (yes, he's green, and ogros hate green), but even if he's green it's the best friend of the original, the true ogro.
Igdosh: played with a nuclear missile, thinking it was a cigar...
Gorash: he's evil too, has been created by the doctor ogrenstein. but this is the prototype, the real ogrenstein is under construction for now.
Arboshak: He felt in love with 3CPO and tried to cyborgize himself. but finally preferred R2D2, but too late
Editors used:-
Modelling/animation : Lightwave 5.5
Converting/clean-up : QME, Q2modeler
Skinning/mapping : NST, Paint shop Pro
Build/Animation time : longer than expected. 5-10 hours per skin.
* How to use this model *
extract to quake2\baseq2\players\ogro run quake2, send us money, frag other players.
* Copyright / Permissions *
QUAKE(R) and QUAKE II(R) are registered trademarks of id Software, Inc.
\ No newline at end of file
此差异已折叠。
此差异已折叠。
......@@ -29,6 +29,8 @@
var camera, scene, renderer, objects;
var particleLight, pointLight;
var materials = [];
init();
animate();
......@@ -68,7 +70,6 @@
var texture = new THREE.Texture( generateTexture() );
texture.needsUpdate = true;
var materials = [];
materials.push( new THREE.MeshLambertMaterial( { map: texture, transparent: true } ) );
materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } ) );
materials.push( new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
......@@ -82,6 +83,10 @@
materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ) );
materials.push( new THREE.MeshDepthMaterial() );
materials.push( new THREE.MeshLambertMaterial( { color: 0x666666, emissive: 0xff0000, ambient: 0x000000, shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0xff0000, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.9, transparent: true } ) );
materials.push( new THREE.MeshBasicMaterial( { map: texture, transparent: true } ) );
// Spheres geometry
......@@ -141,9 +146,9 @@
// Lights
scene.add( new THREE.AmbientLight( 0x202020 ) );
scene.add( new THREE.AmbientLight( 0x111111 ) );
var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
var directionalLight = new THREE.DirectionalLight( /*Math.random() * */ 0xffffff, 0.125 );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
......@@ -158,7 +163,7 @@
//
renderer = new THREE.WebGLRenderer();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
......@@ -231,6 +236,9 @@
}
materials[ materials.length - 3 ].emissive.setHSV( 0.54, 1, 0.7 * ( 0.5 + 0.5 * Math.sin( 35 * timer ) ) );
materials[ materials.length - 4 ].emissive.setHSV( 0.04, 1, 0.7 * ( 0.5 + 0.5 * Math.cos( 35 * timer ) ) );
particleLight.position.x = Math.sin( timer * 7 ) * 300;
particleLight.position.y = Math.cos( timer * 5 ) * 400;
particleLight.position.z = Math.cos( timer * 3 ) * 300;
......
<!doctype html>
<html lang="en">
<head>
<title>three.js webgl - morphtargets - MD2 controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color:#000;
position: relative;
margin: 0 auto -2.1em;
top: 0px;
padding: 5px;
z-index:100;
}
a { color: skyblue; }
</style>
</head>
<body>
<div id="info">
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - morphtargets -
Ogro by <a href="http://planetquake.gamespy.com/View.php?view=Quake2.Detail&id=556">Magarnigal</a> -
converted by <a href="https://twitter.com/#!/oosmoxiecode">@oosmoxiecode</a>'s <a href="http://oos.moxiecode.com/blog/2012/01/md2-to-json-converter/">MD2 converter</a> -
use arrows to control characters, mouse for camera
</div>
<script src="../build/Three.js"></script>
<script src='js/MD2CharacterComplex.js'></script>
<script src='js/Detector.js'></script>
<script src='js/Stats.js'></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var container, camera, scene, renderer;
var characters = [];
var nCharacters = 0;
var cameraControls;
var controls = {
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false
};
var clock = new THREE.Clock();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// SCENE
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 1000, 4000 );
// CAMERA
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 );
camera.position.set( 0, 150, 1300 );
scene.add( camera );
// LIGHTS
scene.add( new THREE.AmbientLight( 0x222222 ) );
var light = new THREE.DirectionalLight( 0xffffff, 2.25 );
light.position.set( 200, 450, 500 );
light.castShadow = true;
light.shadowMapWidth = 1024;
light.shadowMapHeight = 1024;
light.shadowMapDarkness = 0.95;
//light.shadowCameraVisible = true;
light.shadowCascade = true;
light.shadowCascadeCount = 3;
light.shadowCascadeNearZ = [ -1.000, 0.995, 0.998 ];
light.shadowCascadeFarZ = [ 0.995, 0.998, 1.000 ];
light.shadowCascadeWidth = [ 1024, 1024, 1024 ];
light.shadowCascadeHeight = [ 1024, 1024, 1024 ];
scene.add( light );
// GROUND
var gt = THREE.ImageUtils.loadTexture( "textures/terrain/grasslight-big.jpg" );
var gg = new THREE.PlaneGeometry( 16000, 16000 );
var gm = new THREE.MeshPhongMaterial( { color: 0xffffff, map: gt, perPixel: true } );
var ground = new THREE.Mesh( gg, gm );
ground.material.map.repeat.set( 64, 64 );
ground.material.map.wrapS = ground.material.map.wrapT = THREE.RepeatWrapping;
ground.rotation.x = - Math.PI/2;
ground.receiveShadow = true;
scene.add( ground );
// RENDERER
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.setClearColor( scene.fog.color, 1 );
container.appendChild( renderer.domElement );
//
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
//renderer.shadowMapCullFrontFaces = false;
renderer.shadowMapCascade = true;
//renderer.shadowMapDebug = true;
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa";
stats.domElement.children[ 0 ].style.background = "transparent";
stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
// EVENTS
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener( 'keydown', onKeyDown, false );
document.addEventListener( 'keyup', onKeyUp, false );
// CONTROLS
cameraControls = new THREE.TrackballControls( camera, renderer.domElement );
cameraControls.target.set( 0, 50, 0 );
// CHARACTER
var configOgro = {
baseUrl: "models/animated/ogro/",
body: "ogro-light.js",
skins: [ "grok.jpg", "ogrobase.png", "arboshak.png", "ctf_r.png", "ctf_b.png", "darkam.png", "freedom.png",
"gib.png", "gordogh.png", "igdosh.png", "khorne.png", "nabogro.png",
"sharokh.png" ],
weapons: [ [ "weapon-light.js", "weapon.jpg" ] ],
animations: {
move: "run",
idle: "stand",
jump: "jump",
attack: "attack",
crouchMove: "cwalk",
crouchIdle: "cstand",
crouchAttach: "crattack"
},
walkSpeed: 350,
crouchSpeed: 175
};
var nRows = 1;
var nSkins = configOgro.skins.length;
nCharacters = nSkins * nRows;
for ( var i = 0; i < nCharacters; i ++ ) {
var character = new THREE.MD2CharacterComplex();
character.scale = 3;
character.controls = controls;
characters.push( character );
}
var baseCharacter = new THREE.MD2CharacterComplex();
baseCharacter.scale = 3;
baseCharacter.onLoadComplete = function () {
var k = 0;
for ( var j = 0; j < nRows; j ++ ) {
for ( var i = 0; i < nSkins; i ++ ) {
var cloneCharacter = characters[ k ];
cloneCharacter.shareParts( baseCharacter );
cloneCharacter.enableShadows( true );
cloneCharacter.setWeapon( 0 );
cloneCharacter.setSkin( i );
cloneCharacter.root.position.x = ( i - nSkins/2 ) * 150;
cloneCharacter.root.position.z = j * 250;
scene.add( cloneCharacter.root );
k ++;
}
}
var gyro = new THREE.Gyroscope();
gyro.add( camera );
characters[ Math.floor( nSkins/2 ) ].root.add( gyro );
};
baseCharacter.loadParts( configOgro );
}
// EVENT HANDLERS
function onWindowResize( event ) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
camera.aspect = SCREEN_WIDTH/ SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
function onKeyDown ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ controls.moveForward = true; break;
case 40: /*down*/
case 83: /*S*/ controls.moveBackward = true; break;
case 37: /*left*/
case 65: /*A*/ controls.moveLeft = true; break;
case 39: /*right*/
case 68: /*D*/ controls.moveRight = true; break;
//case 67: /*C*/ controls.crouch = true; break;
//case 32: /*space*/ controls.jump = true; break;
//case 17: /*ctrl*/ controls.attack = true; break;
}
};
function onKeyUp ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ controls.moveForward = false; break;
case 40: /*down*/
case 83: /*S*/ controls.moveBackward = false; break;
case 37: /*left*/
case 65: /*A*/ controls.moveLeft = false; break;
case 39: /*right*/
case 68: /*D*/ controls.moveRight = false; break;
//case 67: /*C*/ controls.crouch = false; break;
//case 32: /*space*/ controls.jump = false; break;
//case 17: /*ctrl*/ controls.attack = false; break;
}
};
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
var delta = clock.getDelta();
cameraControls.update( delta );
for ( var i = 0; i < nCharacters; i ++ ) {
characters[ i ].update( delta );
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.MorphBlendMesh = function( geometry, material ) {
THREE.Mesh.call( this, geometry, material );
this.animationsMap = {};
this.animationsList = [];
// prepare default animation
// (all frames played together in 1 second)
var numFrames = this.geometry.morphTargets.length;
var name = "__default";
var startFrame = 0;
var endFrame = numFrames - 1;
var fps = numFrames / 1;
this.createAnimation( name, startFrame, endFrame, fps );
this.setAnimationWeight( name, 1 );
};
THREE.MorphBlendMesh.prototype = new THREE.Mesh();
THREE.MorphBlendMesh.prototype.constructor = THREE.MorphBlendMesh;
THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
var animation = {
startFrame: start,
endFrame: end,
length: end - start + 1,
fps: fps,
duration: ( end - start ) / fps,
lastFrame: 0,
currentFrame: 0,
active: false,
time: 0,
direction: 1,
weight: 1,
directionBackwards: false,
mirroredLoop: false
};
this.animationsMap[ name ] = animation;
this.animationsList.push( animation );
};
THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
var pattern = /([a-z]+)(\d+)/;
var firstAnimation, frameRanges = {};
var geometry = this.geometry;
for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
var morph = geometry.morphTargets[ i ];
var chunks = morph.name.match( pattern );
if ( chunks && chunks.length > 1 ) {
var name = chunks[ 1 ];
var num = chunks[ 2 ];
if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: -Infinity };
var range = frameRanges[ name ];
if ( i < range.start ) range.start = i;
if ( i > range.end ) range.end = i;
if ( ! firstAnimation ) firstAnimation = name;
}
}
for ( var name in frameRanges ) {
var range = frameRanges[ name ];
this.createAnimation( name, range.start, range.end, fps );
}
this.firstAnimation = firstAnimation;
};
THREE.MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.direction = 1;
animation.directionBackwards = false;
}
};
THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.direction = -1;
animation.directionBackwards = true;
}
};
THREE.MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.fps = fps;
animation.duration = ( animation.end - animation.start ) / animation.fps;
}
};
THREE.MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.duration = duration;
animation.fps = ( animation.end - animation.start ) / animation.duration;
}
};
THREE.MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.weight = weight;
}
};
THREE.MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.time = time;
}
};
THREE.MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
var time = 0;
var animation = this.animationsMap[ name ];
if ( animation ) {
time = animation.time;
}
return time;
};
THREE.MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
var duration = -1;
var animation = this.animationsMap[ name ];
if ( animation ) {
duration = animation.duration;
}
return duration;
};
THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.time = 0;
animation.active = true;
} else {
console.warn( "animation[" + name + "] undefined" );
}
};
THREE.MorphBlendMesh.prototype.stopAnimation = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.active = false;
}
};
THREE.MorphBlendMesh.prototype.update = function ( delta ) {
for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
var animation = this.animationsList[ i ];
if ( ! animation.active ) continue;
var frameTime = animation.duration / animation.length;
animation.time += animation.direction * delta;
if ( animation.mirroredLoop ) {
if ( animation.time > animation.duration || animation.time < 0 ) {
animation.direction *= -1;
if ( animation.time > animation.duration ) {
animation.time = animation.duration;
animation.directionBackwards = true;
}
if ( animation.time < 0 ) {
animation.time = 0;
animation.directionBackwards = false;
}
}
} else {
animation.time = animation.time % animation.duration;
if ( animation.time < 0 ) animation.time += animation.duration;
}
var keyframe = animation.startFrame + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
var weight = animation.weight;
if ( keyframe !== animation.currentFrame ) {
this.morphTargetInfluences[ animation.lastFrame ] = 0;
this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
this.morphTargetInfluences[ keyframe ] = 0;
animation.lastFrame = animation.currentFrame;
animation.currentFrame = keyframe;
}
var mix = ( animation.time % frameTime ) / frameTime;
if ( animation.directionBackwards ) mix = 1 - mix;
this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
}
};
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.DepthPassPlugin = function ( ) {
this.enabled = false;
this.renderTarget = null;
var _gl,
_renderer,
_depthMaterial, _depthMaterialMorph,
_frustum = new THREE.Frustum(),
_projScreenMatrix = new THREE.Matrix4();
this.init = function ( renderer ) {
_gl = renderer.context;
_renderer = renderer;
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
_depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
_depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
_depthMaterial._shadowPass = true;
_depthMaterialMorph._shadowPass = true;
};
this.render = function ( scene, camera ) {
if ( ! this.enabled ) return;
this.update( scene, camera );
};
this.update = function ( scene, camera ) {
var i, il, j, jl, n,
program, buffer, material,
webglObject, object, light,
renderList,
fog = null;
// set GL state for depth map
_gl.clearColor( 1, 1, 1, 1 );
_gl.disable( _gl.BLEND );
_renderer.setDepthTest( true );
// render depth map
if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix );
_renderer.setRenderTarget( this.renderTarget );
_renderer.clear();
// set matrices & frustum culling
renderList = scene.__webglObjects;
for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
webglObject = renderList[ j ];
object = webglObject.object;
webglObject.render = false;
if ( object.visible ) {
if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
webglObject.render = true;
}
}
}
// render regular objects
for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
webglObject = renderList[ j ];
if ( webglObject.render ) {
object = webglObject.object;
buffer = webglObject.buffer;
_renderer.setObjectFaces( object );
if ( object.customDepthMaterial ) {
material = object.customDepthMaterial;
} else if ( object.geometry.morphTargets.length ) {
material = _depthMaterialMorph;
} else {
material = _depthMaterial;
}
if ( buffer instanceof THREE.BufferGeometry ) {
_renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object );
} else {
_renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object );
}
}
}
// set matrices and render immediate objects
renderList = scene.__webglObjectsImmediate;
for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
webglObject = renderList[ j ];
object = webglObject.object;
if ( object.visible && object.castShadow ) {
if( object.matrixAutoUpdate ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
}
object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
_renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object );
}
}
// restore GL state
var clearColor = _renderer.getClearColor(),
clearAlpha = _renderer.getClearAlpha();
_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
_gl.enable( _gl.BLEND );
};
};
......@@ -34,6 +34,8 @@ THREE.MeshBasicMaterial = function ( parameters ) {
parameters = parameters || {};
// color property represents emissive for MeshBasicMaterial
this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
this.map = parameters.map !== undefined ? parameters.map : null;
......
......@@ -5,6 +5,7 @@
* parameters = {
* color: <hex>,
* ambient: <hex>,
* emissive: <hex>,
* opacity: <float>,
*
* map: new THREE.Texture( <Image> ),
......@@ -36,8 +37,11 @@ THREE.MeshLambertMaterial = function ( parameters ) {
parameters = parameters || {};
// color property represents diffuse for MeshLambertMaterial
this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
this.wrapAround = parameters.wrapAround !== undefined ? parameters.wrapAround: false;
this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
......
......@@ -5,6 +5,7 @@
* parameters = {
* color: <hex>,
* ambient: <hex>,
* emissive: <hex>,
* specular: <hex>,
* shininess: <float>,
* opacity: <float>,
......@@ -38,8 +39,11 @@ THREE.MeshPhongMaterial = function ( parameters ) {
parameters = parameters || {};
// color property represents diffuse for MeshPhongMaterial
this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
this.specular = parameters.specular !== undefined ? new THREE.Color( parameters.specular ) : new THREE.Color( 0x111111 );
this.shininess = parameters.shininess !== undefined ? parameters.shininess : 30;
......
......@@ -4571,11 +4571,13 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( _this.gammaInput ) {
uniforms.ambient.value.copyGammaToLinear( material.ambient );
uniforms.emissive.value.copyGammaToLinear( material.emissive );
uniforms.specular.value.copyGammaToLinear( material.specular );
} else {
uniforms.ambient.value = material.ambient;
uniforms.emissive.value = material.emissive;
uniforms.specular.value = material.specular;
}
......@@ -4593,10 +4595,12 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( _this.gammaInput ) {
uniforms.ambient.value.copyGammaToLinear( material.ambient );
uniforms.emissive.value.copyGammaToLinear( material.emissive );
} else {
uniforms.ambient.value = material.ambient;
uniforms.emissive.value = material.emissive;
}
......
......@@ -266,6 +266,7 @@ THREE.ShaderChunk = {
"uniform vec3 ambient;",
"uniform vec3 diffuse;",
"uniform vec3 emissive;",
"uniform vec3 ambientLightColor;",
......@@ -404,11 +405,11 @@ THREE.ShaderChunk = {
"#endif",
"vLightFront = vLightFront * diffuse + ambient * ambientLightColor;",
"vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
"#ifdef DOUBLE_SIDED",
"vLightBack = vLightBack * diffuse + ambient * ambientLightColor;",
"vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",
"#endif",
......@@ -663,11 +664,11 @@ THREE.ShaderChunk = {
"#ifdef METAL",
"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );",
"gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",
"#else",
"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
"gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
"#endif"
......@@ -1386,7 +1387,8 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "shadowmap" ],
{
"ambient" : { type: "c", value: new THREE.Color( 0x050505 ) },
"ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
"wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
}
......@@ -1500,7 +1502,8 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "shadowmap" ],
{
"ambient" : { type: "c", value: new THREE.Color( 0x050505 ) },
"ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
"specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
"shininess": { type: "f", value: 30 },
"wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
......@@ -1559,6 +1562,7 @@ THREE.ShaderLib = {
"uniform float opacity;",
"uniform vec3 ambient;",
"uniform vec3 emissive;",
"uniform vec3 specular;",
"uniform float shininess;",
......
......@@ -131,9 +131,11 @@ EXTRAS_FILES = [
'extras/loaders/UTF8Loader.js',
'extras/objects/MarchingCubes.js',
'extras/objects/LensFlare.js',
'extras/objects/MorphBlendMesh.js',
'extras/renderers/plugins/LensFlarePlugin.js',
'extras/renderers/plugins/ShadowMapPlugin.js',
'extras/renderers/plugins/SpritePlugin.js',
'extras/renderers/plugins/DepthPassPlugin.js',
'extras/renderers/AnaglyphWebGLRenderer.js',
'extras/renderers/CrosseyedWebGLRenderer.js',
'extras/shaders/ShaderFlares.js',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册