From 664dd3664bcfa7cde43e83d71383ffb49a232013 Mon Sep 17 00:00:00 2001 From: Louis Brunner Date: Tue, 7 Feb 2017 09:46:58 +0000 Subject: [PATCH] FBXLoader: add Periodic form for NURBS (+test file for Closed and Periodic forms) --- examples/js/curves/NURBSCurve.js | 7 +- examples/js/loaders/FBXLoader.js | 20 ++- examples/js/loaders/FBXLoader2.js | 28 ++-- examples/models/fbx/nurbs.fbx | 256 ++++++++++++------------------ 4 files changed, 138 insertions(+), 173 deletions(-) diff --git a/examples/js/curves/NURBSCurve.js b/examples/js/curves/NURBSCurve.js index ca3d869b45f536..ce8515f3765e6b 100644 --- a/examples/js/curves/NURBSCurve.js +++ b/examples/js/curves/NURBSCurve.js @@ -13,11 +13,14 @@ * NURBS curve **************************************************************/ -THREE.NURBSCurve = function ( degree, knots /* array of reals */, controlPoints /* array of Vector(2|3|4) */ ) { +THREE.NURBSCurve = function ( degree, knots /* array of reals */, controlPoints /* array of Vector(2|3|4) */, startKnot /* index in knots */, endKnot /* index in knots */ ) { this.degree = degree; this.knots = knots; this.controlPoints = []; + // Used by periodic NURBS to remove hidden spans + this.startKnot = startKnot || 0; + this.endKnot = endKnot || ( this.knots.length - 1 ); for ( var i = 0; i < controlPoints.length; ++ i ) { // ensure Vector4 for control points @@ -35,7 +38,7 @@ THREE.NURBSCurve.prototype.constructor = THREE.NURBSCurve; THREE.NURBSCurve.prototype.getPoint = function ( t ) { - var u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] ); // linear mapping t->u + var u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u // following results in (wx, wy, wz, w) homogeneous point var hpoint = THREE.NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u ); diff --git a/examples/js/loaders/FBXLoader.js b/examples/js/loaders/FBXLoader.js index f342e9efe5b489..98785591eb2717 100644 --- a/examples/js/loaders/FBXLoader.js +++ b/examples/js/loaders/FBXLoader.js @@ -10,7 +10,7 @@ * - normal / uv * - material (Multi-Material too) * - textures (Must be in same directory) - * - nurbs + * - nurbs (Open, Closed and Periodic forms) * * No Support * - morph @@ -377,6 +377,7 @@ } + var degree = order - 1; var knots = this.parseFloatList( nurbsInfo.subNodes.KnotVector.properties.a ); var controlPoints = []; @@ -389,17 +390,30 @@ } + var startKnot, endKnot; + if ( nurbsInfo.properties.Form == "Closed" ) { controlPoints.push( controlPoints[ 0 ] ); + } else if ( nurbsInfo.properties.Form === 'Periodic' ) { + + startKnot = degree; + endKnot = knots.length - 1 - startKnot; + + for ( var i = 0; i < degree; ++ i ) { + + controlPoints.push( controlPoints[ i ] ); + + } + } - var curve = new THREE.NURBSCurve( order - 1, knots, controlPoints ); + var curve = new THREE.NURBSCurve( degree, knots, controlPoints, startKnot, endKnot ); // Pre-generate a geometry var geometry = new THREE.Geometry(); - geometry.vertices = curve.getPoints( controlPoints.length * 1.5 ); + geometry.vertices = curve.getPoints( controlPoints.length * 7 ); 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 diff --git a/examples/js/loaders/FBXLoader2.js b/examples/js/loaders/FBXLoader2.js index 0b877cbf955424..370dc72704057e 100644 --- a/examples/js/loaders/FBXLoader2.js +++ b/examples/js/loaders/FBXLoader2.js @@ -12,6 +12,7 @@ * Animation * - Separated Animations based on stacks. * - Skeletal & Non-Skeletal Animations + * NURBS (Open, Closed and Periodic forms) * * Needs Support: * Indexed Buffers @@ -1010,15 +1011,7 @@ } - if ( geometryNode.properties.Form === 'Periodic' ) { - - console.error( "FBXLoader: Currently no support for Periodic Nurbs Curves for geometry ID: " + geometryNode.id + ", using empty geometry buffer." ); - return new THREE.BufferGeometry(); - - //TODO: Support Periodic NURBS curves. - //Info Link: https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2015/ENU/Maya/files/NURBS-overview-Periodic-closed-and-open-geometry-htm.html - - } + var degree = order - 1; var knots = parseFloatArray( geometryNode.subNodes.KnotVector.properties.a ); var controlPoints = []; @@ -1030,14 +1023,27 @@ } + var startKnot, endKnot; + if ( geometryNode.properties.Form === 'Closed' ) { controlPoints.push( controlPoints[ 0 ] ); + } else if ( geometryNode.properties.Form === 'Periodic' ) { + + startKnot = degree; + endKnot = knots.length - 1 - startKnot; + + for ( var i = 0; i < degree; ++ i ) { + + controlPoints.push( controlPoints[ i ] ); + + } + } - var curve = new THREE.NURBSCurve( order - 1, knots, controlPoints ); - var vertices = curve.getPoints( controlPoints.length * 1.5 ); + var curve = new THREE.NURBSCurve( degree, knots, controlPoints, startKnot, endKnot ); + var vertices = curve.getPoints( controlPoints.length * 7 ); var vertexBuffer = []; for ( var verticesIndex = 0, verticesLength = vertices.length; verticesIndex < verticesLength; ++ verticesIndex ) { diff --git a/examples/models/fbx/nurbs.fbx b/examples/models/fbx/nurbs.fbx index da4f2526458047..657b2926e54aa7 100755 --- a/examples/models/fbx/nurbs.fbx +++ b/examples/models/fbx/nurbs.fbx @@ -8,169 +8,103 @@ FBXHeaderExtension: { FBXVersion: 7200 } -; Object definitions +; Object properties ;------------------------------------------------------------------ -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 - } +Objects: { + Geometry: 1000, "Geometry::", "NurbsCurve" { + GeometryVersion: 124 + Type: "NurbsCurve" + NurbsCurveVersion: 100 + Order: 3 + Dimension: 3 + Form: "Open" + Rational: 1 + Points: *32 { + a: 10,20,0,1, 10,20,10,1, 0,20,10,1, -10,20,10,1, -10,20,0,1, -10,20,-10,1, 0,20,-10,1, 10,22,-10,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 - } + KnotVector: *11 { + a: 0,0,0,0.17,0.33,0.5,0.67,0.83,1,1,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 - } + Geometry: 1001, "Geometry::", "NurbsCurve" { + GeometryVersion: 124 + Type: "NurbsCurve" + NurbsCurveVersion: 100 + Order: 3 + Dimension: 3 + Form: "Closed" + Rational: 1 + Points: *32 { + a: 10,15,0,1, 10,15,10,1, 0,15,10,1, -10,15,10,1, -10,15,0,1, -10,15,-10,1, 0,15,-10,1, 10,17,-10,1 + } + KnotVector: *12 { + a: 0,0,0,0.14,0.29,0.43,0.57,0.71,0.86,1,1,1 } } -} - -; Object properties -;------------------------------------------------------------------ - -Objects: { - NodeAttribute: 211671216, "NodeAttribute::Default", "Null" { - TypeFlags: "Null" - } - NodeAttribute: 211674096, "NodeAttribute::Layer 01", "Null" { - TypeFlags: "Null" - } - Geometry: 211707024, "Geometry::", "NurbsCurve" { + Geometry: 1003, "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 + Rational: 0 + Points: *28 { + a: -7.88491751885913,0,-6.3416140214512,1,-7.55614153653084,0,-2.14888095861657,1,-6.89858957187424,0,6.23658516705268,1,6.75015994493138,0,6.91307446273969,1,8.41087276805083,0,-7.08434013027703,1,4.56806678889053,0,-9.8832858634819,1,-2.6353540655343,1.51455220168221,-9.66990979123821,1 } - KnotVector: *6 { - a: -0,-0,-0,1,1,1 + KnotVector: *10 { + a: 0,0,0,1,2,3,4,5,5,5 } } - Model: 211686688, "Model::Default", "Null" { - Version: 232 - Properties70: { - P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 - P: "DefaultAttributeIndex", "int", "Integer", "",0 + Geometry: 1004, "Geometry::", "NurbsCurve" { + GeometryVersion: 124 + Type: "NurbsCurve" + NurbsCurveVersion: 100 + Order: 3 + Dimension: 3 + Form: "Periodic" + Rational: 0 + Points: *28 { + a: -7.98766001333675,-5.56797696184566e-17,-7.65184310358704,1,-7.55614153653083,9.29849790468227e-18,-2.14888095861657,1,-6.89858957187424,-5.31636952823902e-17,6.23658516705267,1,6.75015994493138,0,6.91307446273969,1,8.41087276805082,4.96506830649454e-16,-7.08434013027705,1,4.56806678889055,-2.91370319417538e-16,-9.8832858634819,1,-4.88642308254206,1.9878497647079,-9.60322976866206,1 + } + KnotVector: *12 { + a: -0.625,-0.3125,0,1,2,3,4,5,5.3125,5.625,6.625,7.625 + } + } + Geometry: 1005, "Geometry::", "NurbsCurve" { + GeometryVersion: 124 + Type: "NurbsCurve" + NurbsCurveVersion: 100 + Order: 4 + Dimension: 3 + Form: "Periodic" + Rational: 0 + Points: *32 { + a: 0.783611624891225,4.79823734098847e-17,-0.783611624891224,1,-1.26431706078293e-16,6.78573232311091e-17,-1.10819418755439,1,-0.783611624891224,4.79823734098847e-17,-0.783611624891224,1,-1.10819418755439,1.96633546161879e-32,-3.21126950723723e-16,1,-0.783611624891224,-4.79823734098847e-17,0.783611624891224,1,-3.33920536359052e-16,-6.78573232311091e-17,1.10819418755439,1,0.783611624891224,-4.79823734098847e-17,0.783611624891224,1,1.10819418755439,-3.64463006790479e-32,5.95213259928059e-16,1 + } + KnotVector: *15 { + a: -3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11 } - MultiLayer: 0 - MultiTake: 1 - Shading: Y - Culling: "CullingOff" } - Model: 211700960, "Model::Layer 01", "Null" { - Version: 232 + Model: 10, "Model::Layer 01", "Null" { + } + Model: 100, "Model::Object_1", "NurbsCurve" { + } + Model: 101, "Model::Object_2", "NurbsCurve" { + } + Model: 103, "Model::Object_4", "NurbsCurve" { + } + Model: 104, "Model::Object_5", "NurbsCurve" { Properties70: { - P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 - P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,3.38368368081907,0 } - MultiLayer: 0 - MultiTake: 1 - Shading: Y - Culling: "CullingOff" } - Model: 211707328, "Model::Object_1", "NurbsCurve" { - Version: 232 + Model: 105, "Model::Object_6", "NurbsCurve" { Properties70: { - P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 - P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0.000265865200637982,2.121861293983,0.0232605698569328 + P: "Lcl Scaling", "Lcl Scaling", "", "A",9.95283433152597,1,9.95283433152597 } - MultiLayer: 0 - MultiTake: 1 - Shading: Y - Culling: "CullingOff" } } @@ -178,28 +112,36 @@ Objects: { ;------------------------------------------------------------------ Connections: { + ;Model::Layer 01, Model::RootNode + C: "OO",10,0 - ;Model::Default, Model::RootNode - C: "OO",211686688,0 + ;Model::Object_1, Model::Layer 01 + C: "OO",100,10 - ;Model::Layer 01, Model::RootNode - C: "OO",211700960,0 + ;Geometry::, Model::Object_1 + C: "OO",1000,100 - ;NodeAttribute::Default, Model::Default - C: "OO",211671216,211686688 + ;Model::Object_2, Model::Layer 01 + C: "OO",101,10 - ;NodeAttribute::Layer 01, Model::Layer 01 - C: "OO",211674096,211700960 + ;Geometry::, Model::Object_2 + C: "OO",1001,101 - ;Model::Object_1, Model::Layer 01 - C: "OO",211707328,211700960 + ;Model::Object_4, Model::Layer 01 + C: "OO",103,10 - ;Geometry::, Model::Object_1 - C: "OO",211707024,211707328 -} -;Takes section -;---------------------------------------------------- + ;Geometry::, Model::Object_4 + C: "OO",1003,103 + + ;Model::Object_5, Model::Layer 01 + C: "OO",104,10 + + ;Geometry::, Model::Object_5 + C: "OO",1004,104 + + ;Model::Object_6, Model::Layer 01 + C: "OO",105,10 -Takes: { - Current: "" + ;Geometry::, Model::Object_6 + C: "OO",1005,105 }