Newer
Older
reroad-test / 2020-fuga / aframe-master / examples / js / vendor / LegacyJSONLoader.js
@fuga sakurai fuga sakurai on 4 Nov 2020 13 KB a-フレームを追加した
/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 */

THREE.LegacyJSONLoader = ( function () {

  function LegacyJSONLoader( manager ) {

    if ( typeof manager === 'boolean' ) {

      console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
      manager = undefined;

    }

    this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;

    this.withCredentials = false;

  }

  Object.assign( LegacyJSONLoader.prototype, {

    crossOrigin: 'anonymous',

    load: function ( url, onLoad, onProgress, onError ) {

      var scope = this;

      var path = ( this.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path;

      var loader = new THREE.FileLoader( this.manager );
      loader.setPath( this.path );
      loader.setWithCredentials( this.withCredentials );
      loader.load( url, function ( text ) {

        var json = JSON.parse( text );
        var metadata = json.metadata;

        if ( metadata !== undefined ) {

          var type = metadata.type;

          if ( type !== undefined ) {

            if ( type.toLowerCase() === 'object' ) {

              console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
              return;

            }

          }

        }

        var object = scope.parse( json, path );
        onLoad( object.geometry, object.materials );

      }, onProgress, onError );

    },

    setPath: function ( value ) {

      this.path = value;
      return this;

    },

    setResourcePath: function ( value ) {

      this.resourcePath = value;
      return this;

    },

    setCrossOrigin: function ( value ) {

      this.crossOrigin = value;
      return this;

    },

    parse: ( function () {

      function parseModel( json, geometry ) {

        function isBitSet( value, position ) {

          return value & ( 1 << position );

        }

        var i, j, fi,

          offset, zLength,

          colorIndex, normalIndex, uvIndex, materialIndex,

          type,
          isQuad,
          hasMaterial,
          hasFaceVertexUv,
          hasFaceNormal, hasFaceVertexNormal,
          hasFaceColor, hasFaceVertexColor,

          vertex, face, faceA, faceB, hex, normal,

          uvLayer, uv, u, v,

          faces = json.faces,
          vertices = json.vertices,
          normals = json.normals,
          colors = json.colors,

          scale = json.scale,

          nUvLayers = 0;


        if ( json.uvs !== undefined ) {

          // disregard empty arrays

          for ( i = 0; i < json.uvs.length; i ++ ) {

            if ( json.uvs[ i ].length ) nUvLayers ++;

          }

          for ( i = 0; i < nUvLayers; i ++ ) {

            geometry.faceVertexUvs[ i ] = [];

          }

        }

        offset = 0;
        zLength = vertices.length;

        while ( offset < zLength ) {

          vertex = new THREE.Vector3();

          vertex.x = vertices[ offset ++ ] * scale;
          vertex.y = vertices[ offset ++ ] * scale;
          vertex.z = vertices[ offset ++ ] * scale;

          geometry.vertices.push( vertex );

        }

        offset = 0;
        zLength = faces.length;

        while ( offset < zLength ) {

          type = faces[ offset ++ ];

          isQuad = isBitSet( type, 0 );
          hasMaterial = isBitSet( type, 1 );
          hasFaceVertexUv = isBitSet( type, 3 );
          hasFaceNormal = isBitSet( type, 4 );
          hasFaceVertexNormal = isBitSet( type, 5 );
          hasFaceColor = isBitSet( type, 6 );
          hasFaceVertexColor = isBitSet( type, 7 );

          // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);

          if ( isQuad ) {

            faceA = new THREE.Face3();
            faceA.a = faces[ offset ];
            faceA.b = faces[ offset + 1 ];
            faceA.c = faces[ offset + 3 ];

            faceB = new THREE.Face3();
            faceB.a = faces[ offset + 1 ];
            faceB.b = faces[ offset + 2 ];
            faceB.c = faces[ offset + 3 ];

            offset += 4;

            if ( hasMaterial ) {

              materialIndex = faces[ offset ++ ];
              faceA.materialIndex = materialIndex;
              faceB.materialIndex = materialIndex;

            }

            // to get face <=> uv index correspondence

            fi = geometry.faces.length;

            if ( hasFaceVertexUv ) {

              for ( i = 0; i < nUvLayers; i ++ ) {

                uvLayer = json.uvs[ i ];

                geometry.faceVertexUvs[ i ][ fi ] = [];
                geometry.faceVertexUvs[ i ][ fi + 1 ] = [];

                for ( j = 0; j < 4; j ++ ) {

                  uvIndex = faces[ offset ++ ];

                  u = uvLayer[ uvIndex * 2 ];
                  v = uvLayer[ uvIndex * 2 + 1 ];

                  uv = new THREE.Vector2( u, v );

                  if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
                  if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );

                }

              }

            }

            if ( hasFaceNormal ) {

              normalIndex = faces[ offset ++ ] * 3;

              faceA.normal.set(
                normals[ normalIndex ++ ],
                normals[ normalIndex ++ ],
                normals[ normalIndex ]
              );

              faceB.normal.copy( faceA.normal );

            }

            if ( hasFaceVertexNormal ) {

              for ( i = 0; i < 4; i ++ ) {

                normalIndex = faces[ offset ++ ] * 3;

                normal = new THREE.Vector3(
                  normals[ normalIndex ++ ],
                  normals[ normalIndex ++ ],
                  normals[ normalIndex ]
                );


                if ( i !== 2 ) faceA.vertexNormals.push( normal );
                if ( i !== 0 ) faceB.vertexNormals.push( normal );

              }

            }


            if ( hasFaceColor ) {

              colorIndex = faces[ offset ++ ];
              hex = colors[ colorIndex ];

              faceA.color.setHex( hex );
              faceB.color.setHex( hex );

            }


            if ( hasFaceVertexColor ) {

              for ( i = 0; i < 4; i ++ ) {

                colorIndex = faces[ offset ++ ];
                hex = colors[ colorIndex ];

                if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
                if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );

              }

            }

            geometry.faces.push( faceA );
            geometry.faces.push( faceB );

          } else {

            face = new THREE.Face3();
            face.a = faces[ offset ++ ];
            face.b = faces[ offset ++ ];
            face.c = faces[ offset ++ ];

            if ( hasMaterial ) {

              materialIndex = faces[ offset ++ ];
              face.materialIndex = materialIndex;

            }

            // to get face <=> uv index correspondence

            fi = geometry.faces.length;

            if ( hasFaceVertexUv ) {

              for ( i = 0; i < nUvLayers; i ++ ) {

                uvLayer = json.uvs[ i ];

                geometry.faceVertexUvs[ i ][ fi ] = [];

                for ( j = 0; j < 3; j ++ ) {

                  uvIndex = faces[ offset ++ ];

                  u = uvLayer[ uvIndex * 2 ];
                  v = uvLayer[ uvIndex * 2 + 1 ];

                  uv = new THREE.Vector2( u, v );

                  geometry.faceVertexUvs[ i ][ fi ].push( uv );

                }

              }

            }

            if ( hasFaceNormal ) {

              normalIndex = faces[ offset ++ ] * 3;

              face.normal.set(
                normals[ normalIndex ++ ],
                normals[ normalIndex ++ ],
                normals[ normalIndex ]
              );

            }

            if ( hasFaceVertexNormal ) {

              for ( i = 0; i < 3; i ++ ) {

                normalIndex = faces[ offset ++ ] * 3;

                normal = new THREE.Vector3(
                  normals[ normalIndex ++ ],
                  normals[ normalIndex ++ ],
                  normals[ normalIndex ]
                );

                face.vertexNormals.push( normal );

              }

            }


            if ( hasFaceColor ) {

              colorIndex = faces[ offset ++ ];
              face.color.setHex( colors[ colorIndex ] );

            }


            if ( hasFaceVertexColor ) {

              for ( i = 0; i < 3; i ++ ) {

                colorIndex = faces[ offset ++ ];
                face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );

              }

            }

            geometry.faces.push( face );

          }

        }

      }

      function parseSkin( json, geometry ) {

        var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;

        if ( json.skinWeights ) {

          for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {

            var x = json.skinWeights[ i ];
            var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
            var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
            var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;

            geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );

          }

        }

        if ( json.skinIndices ) {

          for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {

            var a = json.skinIndices[ i ];
            var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
            var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
            var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;

            geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );

          }

        }

        geometry.bones = json.bones;

        if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {

          console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
            geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );

        }

      }

      function parseMorphing( json, geometry ) {

        var scale = json.scale;

        if ( json.morphTargets !== undefined ) {

          for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {

            geometry.morphTargets[ i ] = {};
            geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
            geometry.morphTargets[ i ].vertices = [];

            var dstVertices = geometry.morphTargets[ i ].vertices;
            var srcVertices = json.morphTargets[ i ].vertices;

            for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {

              var vertex = new THREE.Vector3();
              vertex.x = srcVertices[ v ] * scale;
              vertex.y = srcVertices[ v + 1 ] * scale;
              vertex.z = srcVertices[ v + 2 ] * scale;

              dstVertices.push( vertex );

            }

          }

        }

        if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {

          console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );

          var faces = geometry.faces;
          var morphColors = json.morphColors[ 0 ].colors;

          for ( var i = 0, l = faces.length; i < l; i ++ ) {

            faces[ i ].color.fromArray( morphColors, i * 3 );

          }

        }

      }

      function parseAnimations( json, geometry ) {

        var outputAnimations = [];

        // parse old style Bone/Hierarchy animations
        var animations = [];

        if ( json.animation !== undefined ) {

          animations.push( json.animation );

        }

        if ( json.animations !== undefined ) {

          if ( json.animations.length ) {

            animations = animations.concat( json.animations );

          } else {

            animations.push( json.animations );

          }

        }

        for ( var i = 0; i < animations.length; i ++ ) {

          var clip = THREE.AnimationClip.parseAnimation( animations[ i ], geometry.bones );
          if ( clip ) outputAnimations.push( clip );

        }

        // parse implicit morph animations
        if ( geometry.morphTargets ) {

          // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
          var morphAnimationClips = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
          outputAnimations = outputAnimations.concat( morphAnimationClips );

        }

        if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;

      }

      return function parse( json, path ) {

        if ( json.data !== undefined ) {

          // Geometry 4.0 spec
          json = json.data;

        }

        if ( json.scale !== undefined ) {

          json.scale = 1.0 / json.scale;

        } else {

          json.scale = 1.0;

        }

        var geometry = new THREE.Geometry();

        parseModel( json, geometry );
        parseSkin( json, geometry );
        parseMorphing( json, geometry );
        parseAnimations( json, geometry );

        geometry.computeFaceNormals();
        geometry.computeBoundingSphere();

        if ( json.materials === undefined || json.materials.length === 0 ) {

          return { geometry: geometry };

        } else {

          var materials = THREE.Loader.prototype.initMaterials( json.materials, this.resourcePath || path, this.crossOrigin );

          return { geometry: geometry, materials: materials };

        }

      };

    } )()

  } );

  return LegacyJSONLoader;

} )();