Ver Fonte

FBXLoader: add NurbsCurve support (with example)

Louis Brunner há 8 anos atrás
pai
commit
4bd808433a

+ 88 - 0
examples/js/loaders/FBXLoader.js

@@ -10,6 +10,7 @@
  *  - normal / uv
  *  - material (Multi-Material too)
  *  - textures (Must be in same directory)
+ *  - nurbs
  *
  *  No Support
  *  - morph
@@ -321,6 +322,11 @@
 					//Parse Mesh
 					meshes.push( this.parseMesh( modelNode[ ID ], node ) );
 
+				} else if ( modelNode[ ID ].attrType === 'NurbsCurve' ) {
+
+					//Parse NURBS
+					meshes.push( this.parseNURBS( modelNode[ ID ], node ) );
+
 				}
 
 			}
@@ -329,6 +335,88 @@
 
 		},
 
+		parseFloatList: function ( floatList ) {
+
+			return floatList.split( ',' ).map( function ( number ) {
+
+				return parseFloat( number );
+
+			} );
+
+		},
+
+		parseNURBS: function ( meshNode, FBXNodes ) {
+
+			if ( THREE.NURBSCurve === undefined ) {
+
+				console.error( "THREE.FBXLoader relies on THREE.NURBSCurve" );
+				return;
+
+			}
+
+			var geoNodes = FBXNodes.Objects.subNodes.Geometry;
+
+			var children = FBXNodes.searchConnectionChildren( meshNode.id );
+			var nurbsInfo;
+
+			for ( var i = 0; i < children.length; ++ i ) {
+
+				if ( children[ i ] in geoNodes ) {
+
+					nurbsInfo = geoNodes[ children[ i ] ];
+					break;
+
+				}
+
+			}
+
+			if ( nurbsInfo === undefined ) {
+
+				return;
+
+			}
+
+			var order = parseInt( nurbsInfo.properties.Order );
+
+			if ( isNaN( order ) ) {
+
+				console.error( "Invalid Order: `" + nurbsInfo.properties.Order + "` (should be an integer)" );
+				return;
+
+			}
+
+			var knots = this.parseFloatList( nurbsInfo.subNodes.KnotVector.properties.a );
+
+			var controlPoints = [];
+			var pointsValues = this.parseFloatList( nurbsInfo.subNodes.Points.properties.a );
+
+			for ( var i = 0; i < pointsValues.length; i += 4 ) {
+
+				// NURBSCurve recreates a Vector4, so no need to construct it twice
+				controlPoints.push( { x: pointsValues[ i ], y: pointsValues[ i + 1 ], z: pointsValues[ i + 2 ], w: pointsValues[ i + 3 ] } );
+
+			}
+
+			if ( nurbsInfo.properties.Form == "Closed" ) {
+
+				controlPoints.push( controlPoints[ 0 ] );
+
+			}
+
+			var curve = new THREE.NURBSCurve( order - 1, knots, controlPoints );
+
+			// Pre-generate a geometry
+			var geometry = new THREE.Geometry();
+			geometry.vertices = curve.getPoints( controlPoints.length * 1.5 );
+
+			var mesh = new THREE.Line( geometry );
+			// Store the THREE.NURBSCurve class so the user can recreate a new geometry with a different number of points
+			mesh.userData.curve = curve;
+
+			return mesh;
+
+		},
+
 		parseMesh: function ( meshNode, FBXNodes ) {
 
 			var geoNodes = FBXNodes.Objects.subNodes.Geometry;

+ 205 - 0
examples/models/fbx/nurbs.fbx

@@ -0,0 +1,205 @@
+; FBX 7.2.0 project file
+; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors.
+; All rights reserved.
+; ----------------------------------------------------
+
+FBXHeaderExtension:  {
+	FBXHeaderVersion: 1003
+	FBXVersion: 7200
+}
+
+; Object definitions
+;------------------------------------------------------------------
+
+Definitions:  {
+	Version: 100
+	Count: 51
+	ObjectType: "Model" {
+		Count: 25
+		PropertyTemplate: "KFbxNode" {
+			Properties70:  {
+				P: "QuaternionInterpolate", "enum", "", "",0
+				P: "RotationOffset", "Vector3D", "Vector", "",0,0,0
+				P: "RotationPivot", "Vector3D", "Vector", "",0,0,0
+				P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0
+				P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0
+				P: "TranslationActive", "bool", "", "",0
+				P: "TranslationMin", "Vector3D", "Vector", "",0,0,0
+				P: "TranslationMax", "Vector3D", "Vector", "",0,0,0
+				P: "TranslationMinX", "bool", "", "",0
+				P: "TranslationMinY", "bool", "", "",0
+				P: "TranslationMinZ", "bool", "", "",0
+				P: "TranslationMaxX", "bool", "", "",0
+				P: "TranslationMaxY", "bool", "", "",0
+				P: "TranslationMaxZ", "bool", "", "",0
+				P: "RotationOrder", "enum", "", "",0
+				P: "RotationSpaceForLimitOnly", "bool", "", "",0
+				P: "RotationStiffnessX", "double", "Number", "",0
+				P: "RotationStiffnessY", "double", "Number", "",0
+				P: "RotationStiffnessZ", "double", "Number", "",0
+				P: "AxisLen", "double", "Number", "",10
+				P: "PreRotation", "Vector3D", "Vector", "",0,0,0
+				P: "PostRotation", "Vector3D", "Vector", "",0,0,0
+				P: "RotationActive", "bool", "", "",0
+				P: "RotationMin", "Vector3D", "Vector", "",0,0,0
+				P: "RotationMax", "Vector3D", "Vector", "",0,0,0
+				P: "RotationMinX", "bool", "", "",0
+				P: "RotationMinY", "bool", "", "",0
+				P: "RotationMinZ", "bool", "", "",0
+				P: "RotationMaxX", "bool", "", "",0
+				P: "RotationMaxY", "bool", "", "",0
+				P: "RotationMaxZ", "bool", "", "",0
+				P: "InheritType", "enum", "", "",0
+				P: "ScalingActive", "bool", "", "",0
+				P: "ScalingMin", "Vector3D", "Vector", "",0,0,0
+				P: "ScalingMax", "Vector3D", "Vector", "",1,1,1
+				P: "ScalingMinX", "bool", "", "",0
+				P: "ScalingMinY", "bool", "", "",0
+				P: "ScalingMinZ", "bool", "", "",0
+				P: "ScalingMaxX", "bool", "", "",0
+				P: "ScalingMaxY", "bool", "", "",0
+				P: "ScalingMaxZ", "bool", "", "",0
+				P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0
+				P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0
+				P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1
+				P: "MinDampRangeX", "double", "Number", "",0
+				P: "MinDampRangeY", "double", "Number", "",0
+				P: "MinDampRangeZ", "double", "Number", "",0
+				P: "MaxDampRangeX", "double", "Number", "",0
+				P: "MaxDampRangeY", "double", "Number", "",0
+				P: "MaxDampRangeZ", "double", "Number", "",0
+				P: "MinDampStrengthX", "double", "Number", "",0
+				P: "MinDampStrengthY", "double", "Number", "",0
+				P: "MinDampStrengthZ", "double", "Number", "",0
+				P: "MaxDampStrengthX", "double", "Number", "",0
+				P: "MaxDampStrengthY", "double", "Number", "",0
+				P: "MaxDampStrengthZ", "double", "Number", "",0
+				P: "PreferedAngleX", "double", "Number", "",0
+				P: "PreferedAngleY", "double", "Number", "",0
+				P: "PreferedAngleZ", "double", "Number", "",0
+				P: "LookAtProperty", "object", "", ""
+				P: "UpVectorProperty", "object", "", ""
+				P: "Show", "bool", "", "",1
+				P: "NegativePercentShapeSupport", "bool", "", "",1
+				P: "DefaultAttributeIndex", "int", "Integer", "",-1
+				P: "Freeze", "bool", "", "",0
+				P: "LODBox", "bool", "", "",0
+				P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0
+				P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0
+				P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1
+				P: "Visibility", "Visibility", "", "A",1
+				P: "Visibility Inheritance", "Visibility Inheritance", "", "",1
+			}
+		}
+	}
+	ObjectType: "NodeAttribute" {
+		Count: 2
+		PropertyTemplate: "KFbxNull" {
+			Properties70:  {
+				P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8
+				P: "Size", "double", "Number", "",100
+				P: "Look", "enum", "", "",1
+			}
+		}
+	}
+	ObjectType: "Geometry" {
+		Count: 23
+		PropertyTemplate: "KFbxNurbsCurve" {
+			Properties70:  {
+				P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8
+				P: "BBoxMin", "Vector3D", "Vector", "",0,0,0
+				P: "BBoxMax", "Vector3D", "Vector", "",0,0,0
+			}
+		}
+	}
+}
+
+; Object properties
+;------------------------------------------------------------------
+
+Objects:  {
+	NodeAttribute: 211671216, "NodeAttribute::Default", "Null" {
+		TypeFlags: "Null"
+	}
+	NodeAttribute: 211674096, "NodeAttribute::Layer 01", "Null" {
+		TypeFlags: "Null"
+	}
+	Geometry: 211707024, "Geometry::", "NurbsCurve" {
+		GeometryVersion: 124
+		Type: "NurbsCurve"
+		NurbsCurveVersion: 100
+		Order: 3
+		Dimension: 3
+		Form: "Open"
+		Rational: 1
+		Points: *12 {
+			a: 0,10,-20,1,15,15,0,1,0,0,15,1
+		}
+		KnotVector: *6 {
+			a: -0,-0,-0,1,1,1
+		}
+	}
+	Model: 211686688, "Model::Default", "Null" {
+		Version: 232
+		Properties70:  {
+			P: "ScalingMax", "Vector3D", "Vector", "",0,0,0
+			P: "DefaultAttributeIndex", "int", "Integer", "",0
+		}
+		MultiLayer: 0
+		MultiTake: 1
+		Shading: Y
+		Culling: "CullingOff"
+	}
+	Model: 211700960, "Model::Layer 01", "Null" {
+		Version: 232
+		Properties70:  {
+			P: "ScalingMax", "Vector3D", "Vector", "",0,0,0
+			P: "DefaultAttributeIndex", "int", "Integer", "",0
+		}
+		MultiLayer: 0
+		MultiTake: 1
+		Shading: Y
+		Culling: "CullingOff"
+	}
+	Model: 211707328, "Model::Object_1", "NurbsCurve" {
+		Version: 232
+		Properties70:  {
+			P: "ScalingMax", "Vector3D", "Vector", "",0,0,0
+			P: "DefaultAttributeIndex", "int", "Integer", "",0
+		}
+		MultiLayer: 0
+		MultiTake: 1
+		Shading: Y
+		Culling: "CullingOff"
+	}
+}
+
+; Object connections
+;------------------------------------------------------------------
+
+Connections:  {
+
+	;Model::Default, Model::RootNode
+	C: "OO",211686688,0
+
+	;Model::Layer 01, Model::RootNode
+	C: "OO",211700960,0
+
+	;NodeAttribute::Default, Model::Default
+	C: "OO",211671216,211686688
+
+	;NodeAttribute::Layer 01, Model::Layer 01
+	C: "OO",211674096,211700960
+
+	;Model::Object_1, Model::Layer 01
+	C: "OO",211707328,211700960
+
+	;Geometry::, Model::Object_1
+	C: "OO",211707024,211707328
+}
+;Takes section
+;----------------------------------------------------
+
+Takes:  {
+	Current: ""
+}

+ 22 - 0
examples/webgl_loader_fbx.html

@@ -34,6 +34,8 @@
 
 		<script src="js/controls/OrbitControls.js"></script>
 
+		<script src="js/curves/NURBSCurve.js"></script>
+		<script src="js/curves/NURBSUtils.js"></script>
 		<script src="js/loaders/FBXLoader.js"></script>
 
 		<script src="js/Detector.js"></script>
@@ -124,6 +126,26 @@
 
 				}, onProgress, onError );
 
+				loader.load( 'models/fbx/nurbs.fbx', function( object ) {
+
+					object.traverse( function( child ) {
+
+						if ( child instanceof THREE.Line ) {
+
+							child.material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 5 } );
+							// Generate a more detailed geometry
+							var nurbsGeometry = new THREE.Geometry();
+							nurbsGeometry.vertices = child.userData.curve.getPoints( 100 );
+							child.geometry = nurbsGeometry;
+
+						}
+
+					} );
+
+					scene.add( object );
+
+				}, onProgress, onError );
+
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );