Преглед изворни кода

add split to long animation function

adrs2002 пре 8 година
родитељ
комит
2986638703
2 измењених фајлова са 142 додато и 47 уклоњено
  1. 17 13
      examples/js/loaders/XfileLoader.js
  2. 125 34
      examples/webgl_loader_xfile.html

+ 17 - 13
examples/js/loaders/XfileLoader.js

@@ -2,7 +2,7 @@
 /**
 /**
  * @author Jey-en  https://github.com/adrs2002
  * @author Jey-en  https://github.com/adrs2002
  * 
  * 
- * this loader repo  https://github.com/adrs2002/threeXfileLoader
+ * this loader repo -> https://github.com/adrs2002/threeXfileLoader
  * 
  * 
  * This loader is load model (and animation) from .X file format. (for old DirectX).
  * This loader is load model (and animation) from .X file format. (for old DirectX).
  *  ! this version are load from TEXT format .X only ! not a Binary.
  *  ! this version are load from TEXT format .X only ! not a Binary.
@@ -22,7 +22,7 @@
  */
  */
 
 
 
 
-// テキスト情報の読み込みモード
+//テキスト情報の読み込みモード
 // text file Reading Mode
 // text file Reading Mode
 var XfileLoadMode$1 = XfileLoadMode = {
 var XfileLoadMode$1 = XfileLoadMode = {
     none: -1,
     none: -1,
@@ -107,7 +107,7 @@ var XAnimationObj = function () {
         key: 'make',
         key: 'make',
         value: function make(XAnimationInfoArray, mesh) {
         value: function make(XAnimationInfoArray, mesh) {
             var keys = Object.keys(XAnimationInfoArray);
             var keys = Object.keys(XAnimationInfoArray);
-            this.hierarchy_tmp = [];
+            var hierarchy_tmp = [];
             for (var i = 0; i < keys.length; i++) {
             for (var i = 0; i < keys.length; i++) {
                 var bone = null;
                 var bone = null;
                 var parent = -1;
                 var parent = -1;
@@ -121,12 +121,12 @@ var XAnimationObj = function () {
                         break;
                         break;
                     }
                     }
                 }
                 }
-                this.hierarchy_tmp[baseIndex] = this.makeBonekeys(XAnimationInfoArray[keys[i]], bone, parent);
+                hierarchy_tmp[baseIndex] = this.makeBonekeys(XAnimationInfoArray[keys[i]], bone, parent);
             }
             }
             //Xfileの仕様で、「ボーンの順番どおりにアニメーションが出てる」との保証がないため、ボーンヒエラルキーは再定義
             //Xfileの仕様で、「ボーンの順番どおりにアニメーションが出てる」との保証がないため、ボーンヒエラルキーは再定義
-            var keys2 = Object.keys(this.hierarchy_tmp);
+            var keys2 = Object.keys(hierarchy_tmp);
             for (var _i = 0; _i < keys2.length; _i++) {
             for (var _i = 0; _i < keys2.length; _i++) {
-                this.hierarchy.push(this.hierarchy_tmp[_i]);
+                this.hierarchy.push(hierarchy_tmp[_i]);
                 //こんどは、自分より先に「親」がいるはず。
                 //こんどは、自分より先に「親」がいるはず。
                 var parentId = -1;
                 var parentId = -1;
                 for (var _m = 0; _m < this.hierarchy.length; _m++) {
                 for (var _m = 0; _m < this.hierarchy.length; _m++) {
@@ -152,7 +152,7 @@ var XAnimationObj = function () {
                 var keyframe = new Object();
                 var keyframe = new Object();
                 keyframe.time = XAnimationInfo.KeyFrames[i].time * this.fps;
                 keyframe.time = XAnimationInfo.KeyFrames[i].time * this.fps;
                 keyframe.matrix = XAnimationInfo.KeyFrames[i].matrix;
                 keyframe.matrix = XAnimationInfo.KeyFrames[i].matrix;
-                // matrixを再分解。めんどくさっ
+                // matrixを再分解。
                 keyframe.pos = new THREE.Vector3().setFromMatrixPosition(keyframe.matrix);
                 keyframe.pos = new THREE.Vector3().setFromMatrixPosition(keyframe.matrix);
                 keyframe.rot = new THREE.Quaternion().setFromRotationMatrix(keyframe.matrix);
                 keyframe.rot = new THREE.Quaternion().setFromRotationMatrix(keyframe.matrix);
                 keyframe.scl = new THREE.Vector3().setFromMatrixScale(keyframe.matrix);
                 keyframe.scl = new THREE.Vector3().setFromMatrixScale(keyframe.matrix);
@@ -419,7 +419,7 @@ THREE.XFileLoader = function () {
 
 
             var EndFlg = false;
             var EndFlg = false;
 
 
-            //フリーズ現象を防ぐため、1000行ずつの制御にしている(1行ずつだと遅かった)
+            //フリーズ現象を防ぐため、100行ずつの制御にしている(1行ずつだと遅かった)
             for (var i = 0; i < 100; i++) {
             for (var i = 0; i < 100; i++) {
                 this.LineRead(this.lines[this.endLineCount].trim());
                 this.LineRead(this.lines[this.endLineCount].trim());
                 this.endLineCount++;
                 this.endLineCount++;
@@ -429,7 +429,7 @@ THREE.XFileLoader = function () {
                     this.readFinalize();
                     this.readFinalize();
                     setTimeout(function () {
                     setTimeout(function () {
                         _this2.animationFinalize();
                         _this2.animationFinalize();
-                    }, 0);
+                    }, 1);
                     //this.onLoad(this.LoadingXdata);
                     //this.onLoad(this.LoadingXdata);
                     break;
                     break;
                 }
                 }
@@ -438,7 +438,7 @@ THREE.XFileLoader = function () {
             if (!EndFlg) {
             if (!EndFlg) {
                 setTimeout(function () {
                 setTimeout(function () {
                     _this2.mainloop();
                     _this2.mainloop();
-                }, 0);
+                }, 1);
             }
             }
         }
         }
 
 
@@ -877,7 +877,7 @@ THREE.XFileLoader = function () {
         value: function readUv(line) {
         value: function readUv(line) {
             var data = line.split(";");
             var data = line.split(";");
             //これは宣言された頂点の順に入っていく
             //これは宣言された頂点の順に入っていく
-            if (XfileLoader_IsUvYReverse) {
+            if (THREE.XFileLoader.IsUvYReverse) {
                 this.tmpUvArray.push(new THREE.Vector2(parseFloat(data[0]), 1 - parseFloat(data[1])));
                 this.tmpUvArray.push(new THREE.Vector2(parseFloat(data[0]), 1 - parseFloat(data[1])));
             } else {
             } else {
                 this.tmpUvArray.push(new THREE.Vector2(parseFloat(data[0]), parseFloat(data[1])));
                 this.tmpUvArray.push(new THREE.Vector2(parseFloat(data[0]), parseFloat(data[1])));
@@ -1354,7 +1354,7 @@ THREE.XFileLoader = function () {
                 this.LoadingXdata.XAnimationObj[i].name = this.animeKeyNames[i];
                 this.LoadingXdata.XAnimationObj[i].name = this.animeKeyNames[i];
                 this.LoadingXdata.XAnimationObj[i].make(this.LoadingXdata.AnimationSetInfo[this.animeKeyNames[i]], tgtModel);
                 this.LoadingXdata.XAnimationObj[i].make(this.LoadingXdata.AnimationSetInfo[this.animeKeyNames[i]], tgtModel);
 
 
-                tgtModel.geometry.animations = THREE.AnimationClip.parseAnimation(this.LoadingXdata.XAnimationObj[i], tgtModel.skeleton.bones);
+                // tgtModel.geometry.animations = THREE.AnimationClip.parseAnimation(this.LoadingXdata.XAnimationObj[i],tgtModel.skeleton.bones);            
             }
             }
             this.nowReaded++;
             this.nowReaded++;
             if (this.nowReaded >= this.animeKeyNames.length) {
             if (this.nowReaded >= this.animeKeyNames.length) {
@@ -1371,8 +1371,12 @@ THREE.XFileLoader = function () {
 
 
             setTimeout(function () {
             setTimeout(function () {
                 _this3.onLoad(_this3.LoadingXdata);
                 _this3.onLoad(_this3.LoadingXdata);
-            }, 0);
+            }, 1);
         }
         }
     }]);
     }]);
     return XFileLoader;
     return XFileLoader;
 }();
 }();
+
+
+
+THREE.XFileLoader.IsUvYReverse = true;

+ 125 - 34
examples/webgl_loader_xfile.html

@@ -14,7 +14,7 @@
             margin: 0px;
             margin: 0px;
             overflow: hidden;
             overflow: hidden;
         }
         }
-        
+
         #info {
         #info {
             color: #fff;
             color: #fff;
             position: absolute;
             position: absolute;
@@ -38,10 +38,10 @@
 <body>
 <body>
 
 
     <div id="canvase3d"></div>
     <div id="canvase3d"></div>
-    <!-- 描画領域のためのdiv要素を配置 -->
-	<div id="info">
-		<a href="http://threejs.org" target="_blank">three.js</a> - X-File Loader test<br />
-		</div>
+
+    <div id="info">
+        <a href="http://threejs.org" target="_blank">three.js</a> - X-File Loader test<br />
+    </div>
     <div id="dialog_tree" style="width:90%; height:90%;display:block;">
     <div id="dialog_tree" style="width:90%; height:90%;display:block;">
         <ul id="bonetree" class="treeview"></ul>
         <ul id="bonetree" class="treeview"></ul>
     </div>
     </div>
@@ -50,13 +50,12 @@
     <script src="../build/three.js"></script>
     <script src="../build/three.js"></script>
     <script src="js/controls/OrbitControls.js"></script>
     <script src="js/controls/OrbitControls.js"></script>
 
 
-	<script src="js/loaders/XfileLoader.js"></script>
-
-	<script src="js/Detector.js"></script>
-	<script src="js/libs/stats.min.js"></script>
+    <script src="js/loaders/XfileLoader.js"></script>
 
 
+    <script src="js/Detector.js"></script>
+    <script src="js/libs/stats.min.js"></script>
+    <script src='js/libs/dat.gui.min.js'></script>
     <script>
     <script>
-
         var StringBuffer = function (string) {
         var StringBuffer = function (string) {
             this.buffer = [];
             this.buffer = [];
             this.append = function (string) { this.buffer.push(string); return this; };
             this.append = function (string) { this.buffer.push(string); return this; };
@@ -68,6 +67,7 @@
         var container, stats, controls;
         var container, stats, controls;
         var camera, scene, renderer;
         var camera, scene, renderer;
         var clock = new THREE.Clock();
         var clock = new THREE.Clock();
+        var gui = new dat.GUI();
         var mixers = [];
         var mixers = [];
         var manager = null;
         var manager = null;
         var Texloader = null;
         var Texloader = null;
@@ -85,18 +85,14 @@
         var d = new Date();
         var d = new Date();
         var LastDateTime = null;
         var LastDateTime = null;
 
 
-        init();
-
         var animates = [];
         var animates = [];
+        var actions = [];
+        init();
 
 
         function init() {
         function init() {
 
 
-            XfileLoader_IsUvYReverse = true;
-
             LastDateTime = Date.now();
             LastDateTime = Date.now();
 
 
-            XfileLoader_IsPosZReverse = true;
-
             container = document.createElement('canvase3d');
             container = document.createElement('canvase3d');
             document.body.appendChild(container);
             document.body.appendChild(container);
             camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
             camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
@@ -126,34 +122,92 @@
             Texloader = new THREE.TextureLoader();
             Texloader = new THREE.TextureLoader();
             var loader = new THREE.XFileLoader(manager, Texloader);
             var loader = new THREE.XFileLoader(manager, Texloader);
 
 
-            //モデルを読み込む
+            // ! If Texture was reversed Y axis, enable the following 
+            // THREE.XFileLoader.IsUvYReverse = false;
+
             // read (download) model file
             // read (download) model file
             loader.load(['models/xfile/SSR06_Born2.x', true, true], function (object) {
             loader.load(['models/xfile/SSR06_Born2.x', true, true], function (object) {
                 for (var i = 0; i < object.FrameInfo.length; i++) {
                 for (var i = 0; i < object.FrameInfo.length; i++) {
                     Models.push(object.FrameInfo[i]);
                     Models.push(object.FrameInfo[i]);
                     scene.add(Models[i]);
                     scene.add(Models[i]);
 
 
-                    //アニメーションコントローラーをセット&作成する
-                    // create Animation Mixer
                     if (Models[i] instanceof THREE.SkinnedMesh) {
                     if (Models[i] instanceof THREE.SkinnedMesh) {
                         skeletonHelper = new THREE.SkeletonHelper(Models[i]);
                         skeletonHelper = new THREE.SkeletonHelper(Models[i]);
-                        scene.add( skeletonHelper );
-                        if (Models[i].geometry.animations !== undefined) {
-
-                            Models[i].mixer = new THREE.AnimationMixer(Models[i]);
-                            animates.push(Models[i].mixer);
-
-                            var action = Models[i].mixer.clipAction(Models[i].geometry.animations);
-                            action.play();
+                        scene.add(skeletonHelper);
+
+                        if (object.XAnimationObj !== undefined && object.XAnimationObj.length !== 0) {
+                            Models[i].geometry.animations = [];
+
+                            /* 
+                            *  ↓ that is BASIC animation data code.
+                            *  Usually, please use this.
+                            *  Because of the data I have, I use a different code
+                            * 
+                           for (var a = 0; a < object.XAnimationObj.length; a++) {
+                               Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(object.XAnimationObj[a], Models[i].skeleton.bones));
+                           } 
+                           Models[i].mixer = new THREE.AnimationMixer(Models[i]);
+                           animates.push(Models[i].mixer);
+
+                           var action = Models[i].mixer.clipAction(Models[i].geometry.animations[0]);
+                           action.play();
+                           */
+
+                            // ↓ that is a code for [ All animation-keyframes are connected data ]. output from 'LightWave3D' 
+                            {
+                                Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(splitAnimation(object.XAnimationObj[0], 'stand', 10 * object.XAnimationObj[0].fps, 11 * object.XAnimationObj[0].fps), Models[i].skeleton.bones));
+                                Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(splitAnimation(object.XAnimationObj[0], 'walk', 50 * object.XAnimationObj[0].fps, 80 * object.XAnimationObj[0].fps), Models[i].skeleton.bones));
+                                Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(splitAnimation(object.XAnimationObj[0], 'dash', 140 * object.XAnimationObj[0].fps, 160 * object.XAnimationObj[0].fps), Models[i].skeleton.bones));
+                                Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(splitAnimation(object.XAnimationObj[0], 'dashing', 160 * object.XAnimationObj[0].fps, 165 * object.XAnimationObj[0].fps), Models[i].skeleton.bones));
+                                Models[i].geometry.animations.push(THREE.AnimationClip.parseAnimation(splitAnimation(object.XAnimationObj[0], 'damage', 500 * object.XAnimationObj[0].fps, 530 * object.XAnimationObj[0].fps), Models[i].skeleton.bones));
+
+                                Models[i].mixer = new THREE.AnimationMixer(Models[i]);
+                                animates.push(Models[i].mixer);
+
+                                var stand = Models[i].mixer.clipAction('stand');
+                                // stand.play();
+                                stand.setLoop(THREE.LoopRepeat);
+                                actions['stand'] = stand;
+
+                                var walk = Models[i].mixer.clipAction('walk');
+                                walk.setLoop(THREE.LoopRepeat);
+                                walk.play();
+                                actions['walk'] = walk;
+
+                                var dash = Models[i].mixer.clipAction('dash');
+                                dash.setLoop(THREE.LoopOnce);
+                                //dash.play();
+                                actions['dash'] = dash;
+
+                                var dashing = Models[i].mixer.clipAction('dashing');
+                                dashing.setLoop(THREE.LoopPingPong);
+                                // dashing.play();
+                                actions['dashing'] = dashing;
+
+                                var damage = Models[i].mixer.clipAction('damage');
+                                damage.setLoop(THREE.LoopRepeat);
+                                //damage.play();
+                                actions['damage'] = damage;
+
+                                var ActionKeys = Object.keys(actions);
+                                var dmy = {};
+                                dmy.gui = "";
+                                dmy.action = "";
+                                gui.add(dmy, 'gui');
+                                gui.add(dmy, 'action', ActionKeys).onChange(function (v) {
+                                    animates[0].stopAllAction();
+                                    actions[v].play();
+                                });
+                            }
+                            ///////////
                         }
                         }
-
                     }
                     }
                 }
                 }
 
 
                 object = null;
                 object = null;
             }, onProgress, onError);
             }, onProgress, onError);
 
 
-            // ↓アニメーションとは関係ない、three.jsお約束的コード
+
             renderer = new THREE.WebGLRenderer();
             renderer = new THREE.WebGLRenderer();
             renderer.setPixelRatio(window.devicePixelRatio);
             renderer.setPixelRatio(window.devicePixelRatio);
             renderer.setSize(window.innerWidth, window.innerHeight);
             renderer.setSize(window.innerWidth, window.innerHeight);
@@ -183,8 +237,7 @@
             camera.updateProjectionMatrix();
             camera.updateProjectionMatrix();
             renderer.setSize(window.innerWidth, window.innerHeight);
             renderer.setSize(window.innerWidth, window.innerHeight);
         }
         }
-
-        //update frame
+        //
         function animate() {
         function animate() {
 
 
             requestAnimationFrame(animate);
             requestAnimationFrame(animate);
@@ -192,23 +245,61 @@
             var dulTime = nowTime - LastDateTime;
             var dulTime = nowTime - LastDateTime;
             LastDateTime = nowTime;
             LastDateTime = nowTime;
 
 
-            if (animates != null && animates.length > 0 ) {
+            if (animates != null && animates.length > 0) {
                 for (var i = 0; i < animates.length; i++) {
                 for (var i = 0; i < animates.length; i++) {
                     animates[i].update(dulTime);
                     animates[i].update(dulTime);
                 }
                 }
             }
             }
 
 
-            if (Models != null && Models.length > 0)  {
+            if (Models != null && Models.length > 0) {
                 if (skeletonHelper != null) { skeletonHelper.update(); }
                 if (skeletonHelper != null) { skeletonHelper.update(); }
-            
+
             }
             }
 
 
             stats.update();
             stats.update();
             render();
             render();
         }
         }
         function render() {
         function render() {
+            //renderer.setFaceCulling(THREE.CullFaceFront, THREE.FrontFaceDirectionCW);
             renderer.render(scene, camera);
             renderer.render(scene, camera);
         }
         }
+
+        /////////////////
+        /// this is not must mount codes.
+
+        // split  One and Long Animation, for time
+        function splitAnimation(_baseAnime, _name, _beginTime, _endTime) {
+            var Animation = {};
+            Animation.fps = _baseAnime.fps;
+            Animation.name = _name;
+            Animation.length = _endTime - _beginTime;
+            Animation.hierarchy = [];
+            for (var i = 0; i < _baseAnime.hierarchy.length; i++) {
+                var firstKey = -1;
+                var lastKey = -1;
+                var frame = {};
+                frame.name = _baseAnime.hierarchy[i].name;
+                frame.parent = _baseAnime.hierarchy[i].parent;
+                frame.keys = [];
+                for (var m = 1; m < _baseAnime.hierarchy[i].keys.length; m++) {
+                    if (_baseAnime.hierarchy[i].keys[m].time > _beginTime) {
+                        if (firstKey === -1) {
+                            firstKey = m - 1;
+                            frame.keys.push(_baseAnime.hierarchy[i].keys[m - 1]);
+                        }
+                        frame.keys.push(_baseAnime.hierarchy[i].keys[m]);
+                    }
+                    if (_endTime <= _baseAnime.hierarchy[i].keys[m].time || m >= _baseAnime.hierarchy[i].keys.length - 1) {
+                        break;
+                    }
+                }
+                for (var m = 0; m < frame.keys.length; m++) {
+                    frame.keys[m].time -= _beginTime;
+                }
+                Animation.hierarchy.push(frame);
+            }
+            return Animation;
+        }
     </script>
     </script>
 
 
 </body>
 </body>