Example #1
0
        Node CreateNodes(Model model, Object data, Node parent, Scene scene, List<AssimpSharp.Mesh> meshArray)
        {
            Debug.Assert(null != model);
            if (null == data)
            {
                return null;
            }

            var olsMeshSize = meshArray.Count;
            var node = new AssimpSharp.Node();
            node.Name = data.ObjName;

            if (parent != null)
            {
                AppendChildToParentNode(parent, node);
            }

            foreach (var meshId in data.Meshes)
            {
                var mesh = CreateTopology(model, data, (int)meshId);
                if (mesh != null && mesh.NumFaces > 0)
                {
                    meshArray.Add(mesh);
                }
            }

            if (data.SubObjects.Count > 0)
            {
                var numChilds = data.SubObjects.Count;

            }

            var meshSizeDiff = meshArray.Count - olsMeshSize;
            if (meshSizeDiff > 0)
            {
                int index = 0;
                for (int i = olsMeshSize; i < meshArray.Count; i++)
                {
                    throw (new NotImplementedException());
                }
            }

            return node;
        }
Example #2
0
        private void ConvertNodes(ulong id, aiNode parent, Matrix parentTransform)
        {
            var conns = Doc.GetConnectionsByDestinationSequenced(id, "Model");
            var nodes = new List<aiNode>(conns.Count);
            var nodesChain = new List<aiNode>();

            foreach (var con in conns)
            {
                // ignore object-property links
                if (con.PropertyName.Length > 0)
                {
                    continue;
                }

                var obj = con.SourceObject;
                if (obj == null)
                {
                    FBXImporter.LogWarn("failed to convert source object for Model link");
                    continue;
                }

                var model = obj as Model;
                if (model != null)
                {
                    nodesChain.Clear();

                    var newAbsTransform = parentTransform;

                    // even though there is only a single input node, the design of
                    // assimp (or rather: the complicated transformation chain that
                    // is employed by fbx) means that we may need multiple aiNode's
                    // to represent a fbx node's transformation.
                    GenerateTransformationNodeChain(model, out nodesChain);

                    Debug.Assert(nodesChain.Count > 0);

                    var originalName = FixNodeName(model.Name);

                    // check if any of the nodes in the chain has the name the fbx node
                    // is supposed to have. If there is none, add another node to
                    // preserve the name - people might have scripts etc. that rely
                    // on specific node names.
                    aiNode nameCarrier = null;
                    foreach (var prenode in nodesChain)
                    {
                        if (prenode.Name != originalName)
                        {
                            nameCarrier = prenode;
                            break;
                        }
                    }

                    if (nameCarrier != null)
                    {
                        nodesChain.Add(new aiNode(originalName));
                        nameCarrier = nodesChain[nodesChain.Count - 1];
                    }

                    //setup metadata on newest node
                    SetupNodeMetadata(model, nodesChain[nodesChain.Count - 1]);

                    // link all nodes in a row
                    var lastParent = parent;
                    foreach (var prenode in nodesChain)
                    {
                        Debug.Assert(prenode != null);
                        if (lastParent != parent)
                        {
                            lastParent.Children.Add(prenode);
                        }
                        prenode.Parent = lastParent;
                        lastParent = prenode;

                        newAbsTransform = prenode.Transformation;
                    }

                    ConvertModel(model, nodesChain[nodesChain.Count - 1], newAbsTransform);

                    ConvertNodes(model.ID, nodesChain[nodesChain.Count - 1], newAbsTransform);

                    if (Doc.Settings.ReadLights)
                    {
                        ConvertLights(model);
                    }

                    if (Doc.Settings.ReadCameras)
                    {
                        ConvertCameras(model);
                    }

                    nodes.Add(nodesChain[0]);
                    nodesChain.Clear();
                }
            }

            if (nodes.Count > 0)
            {
                parent.Children.AddRange(nodes);
            }
        }
Example #3
0
        /// <summary>
        /// Recursively creates scene nodes from the imported hierarchy.
        /// The meshes and materials of the nodes will be extracted on the way.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="parent">The parent node where to create new child nodes</param>
        /// <param name="node">The temporary node to copy.</param>
        /// <returns>The created node</returns>
        protected AssimpSharp.Node CreateNodes(AssimpSharp.Scene scene, AssimpSharp.Node parent, AssimpSharp.XFile.Node node)
        {
            if (node == null)
            {
                return null;
            }

            // crate node
            var result = new AssimpSharp.Node();
            result.Name = node.Name;
            result.Transformation = node.TrafoMatrix;
            result.Parent = parent;

            // convert meshes from the source node
            CreateMeshes(scene, result, node.Meshes);

            // handle childs
            if (node.Children.Count > 0)
            {
                result.Children.Clear();
                foreach(var i in node.Children)
                {
                    result.Children.Add(CreateNodes(scene, result, i));
                }
            }

            return result;
        }
Example #4
0
 private void ConvertNodes(ulong id, aiNode node)
 {
     ConvertNodes(id, node, Matrix.Identity);
 }
Example #5
0
        private void ConvertModel(Model model, aiNode nd, Matrix nodeGlobalTransform)
        {
            var geos = model.Geometry;

            var meshes = new List<int>(geos.Count);
            foreach (var geo in geos)
            {
                var mesh = geo as MeshGeometry;
                if (mesh != null)
                {
                    var indices = ConvertMesh(mesh, model, nodeGlobalTransform);
                    meshes.AddRange(indices);
                }
                else
                {
                    Debug.WriteLine("ignoring unrecognized geometry: " + geo.Name);
                }
            }
            if (meshes.Count > 0)
            {
                nd.Meshes.AddRange(meshes);
            }
        }
Example #6
0
        private void SetupNodeMetadata(Model model, aiNode nd)
        {
            var props = model.Props;
            var unparsedProperties = props.GetUnparsedProperties();

            // create metadata on node
            int numStaticMetaData = 2;
            var data = nd.MetaData;
            data.NumProperties = unparsedProperties.Count + numStaticMetaData;
            data.Keys = new string[data.NumProperties];
            data.Values = new AssimpSharp.MetadataEntry[data.NumProperties];
            int index = 0;

            // find user defined properties (3ds Max)
            data.Set<string>(index++, "UserProperties", PropertyHelper.PropertyGet<string>(props, "UDP3DSMAX", ""));
            unparsedProperties.Remove("UDP3DSMAX");
            data.Set(index++, "IsNull", model.IsNull ? true : false);

            foreach (var prop in unparsedProperties)
            {
                var interpreted = prop.Value.As<TypedProperty<bool>>();
                if (interpreted != null)
                {
                    data.Set(index++, prop.Key, interpreted.Value);
                }

            }
        }
Example #7
0
        /// <remarks>
        /// memory for output_nodes will be managed by the caller
        /// </remarks>
        private void GenerateTransformationNodeChain(Model model, out List<aiNode> outputNodes)
        {
            outputNodes = new List<aiNode>();
            var props = model.Props;
            var rot = model.RotationOrder.Value;
            bool ok;
            var chain = new Matrix[Enum.GetValues(typeof(TransformationComp)).Length];
            for(int i=0; i<chain.Length; i++)
            {
                chain[i] = Matrix.Identity;
            }
            float zeroEpsilon = 1e-6f;
            bool isComplex = false;

            Vector3 preRotation = PropertyHelper.PropertyGet<Vector3>(props, "PreRotation", out ok);
            if (ok && preRotation.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                GetRotationMatrix(rot, preRotation, out chain[(int)TransformationComp.PreRotation]);
            }

            Vector3 postRotation = PropertyHelper.PropertyGet<Vector3>(props, "PostRotation", out ok);
            if (ok && postRotation.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                GetRotationMatrix(rot, postRotation, out chain[(int)TransformationComp.PostRotation]);
            }

            Vector3 RotationPivot = PropertyHelper.PropertyGet<Vector3>(props, "RotationPivot", out ok);
            if (ok && RotationPivot.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                Matrix.Translation(ref RotationPivot, out chain[(int)TransformationComp.RotationPivot]);
                chain[(int)TransformationComp.RotationPivotInverse] = Matrix.Translation(-RotationPivot);
            }

            Vector3 RotationOffset = PropertyHelper.PropertyGet<Vector3>(props, "RotationOffset", out ok);
            if (ok && RotationOffset.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                Matrix.Translation(ref RotationOffset, out chain[(int)TransformationComp.RotationOffset]);
            }

            Vector3 ScalingOffset = PropertyHelper.PropertyGet<Vector3>(props, "ScalingOffset", out ok);
            if (ok && ScalingOffset.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                Matrix.Translation(ref ScalingOffset, out chain[(int)TransformationComp.ScalingOffset]);
            }

            Vector3 ScalingPivot = PropertyHelper.PropertyGet<Vector3>(props, "ScalingPivot", out ok);
            if (ok && ScalingPivot.LengthSquared() > zeroEpsilon)
            {
                isComplex = true;
                chain[(int)TransformationComp.ScalingPivot] = Matrix.Translation(ScalingPivot);
                chain[(int)TransformationComp.ScalingPivotInverse] = Matrix.Translation(-ScalingPivot);
            }

            Vector3 Translation = PropertyHelper.PropertyGet<Vector3>(props, "Lcl Translation", out ok);
            if (ok && Translation.LengthSquared() > zeroEpsilon)
            {
                Matrix.Translation(ref Translation, out chain[(int)TransformationComp.Translation]);
            }

            Vector3 Scaling = PropertyHelper.PropertyGet<Vector3>(props, "Lcl Scaling", out ok);
            if (ok && Math.Abs(Scaling.LengthSquared() - 1.0f) > zeroEpsilon)
            {
                Matrix.Scaling(ref Scaling, out chain[(int)TransformationComp.Scaling]);
            }

            Vector3 Rotation = PropertyHelper.PropertyGet<Vector3>(props, "Lcl Rotation", out ok);
            if (ok && Rotation.LengthSquared() > zeroEpsilon)
            {
                GetRotationMatrix(rot, Rotation, out chain[(int)TransformationComp.Rotation]);
            }

            Vector3 GeometricScaling = PropertyHelper.PropertyGet<Vector3>(props, "GeometricScaling", out ok);
            if (ok && Math.Abs(GeometricScaling.LengthSquared() - 1.0f) > zeroEpsilon)
            {
                Matrix.Scaling(ref GeometricScaling, out chain[(int)TransformationComp.GeometricScaling]);
            }

            Vector3 GeometricRotation = PropertyHelper.PropertyGet<Vector3>(props, "GeometricRotation", out ok);
            if (ok && GeometricRotation.LengthSquared() > zeroEpsilon)
            {
                GetRotationMatrix(rot, GeometricRotation, out chain[(int)TransformationComp.GeometricRotation]);
            }

            Vector3 GeometricTranslation = PropertyHelper.PropertyGet<Vector3>(props, "GeometricTranslation", out ok);
            if (ok && GeometricTranslation.LengthSquared() > zeroEpsilon)
            {
                Matrix.Translation(ref GeometricTranslation, out chain[(int)TransformationComp.GeometricTranslation]);
            }

            // is_complex needs to be consistent with NeedsComplexTransformationChain()
            // or the interplay between this code and the animation converter would
            // not be guaranteed.
            Debug.Assert(NeedsComplexTransformationChain(model) == isComplex);

            string name = FixNodeName(model.Name);

            // now, if we have more than just Translation, Scaling and Rotation,
            // we need to generate a full node chain to accommodate for assimp's
            // lack to express pivots and offsets.
            if (isComplex && this.Doc.Settings.PreservePivots)
            {
                FBXImporter.LogInfo("generating full transformation chain for node: " + name);

                // query the anim_chain_bits dictionary to find out which chain elements
                // have associated node animation channels. These can not be dropped
                // even if they have identity transform in bind pose.
                uint animChainBitmask;
                if (!NodeAnimChainBits.TryGetValue(name, out animChainBitmask))
                {
                    animChainBitmask = 0;
                }

                uint bit = 0x1;
                for (int i = 0; i < Enum.GetValues(typeof(TransformationComp)).Length; ++i, bit <<= 1)
                {
                    TransformationComp comp = (TransformationComp)i;

                    if (chain[i].IsIdentity && (animChainBitmask & bit) == 0)
                    {
                        continue;
                    }

                    aiNode nd = new aiNode();
                    outputNodes.Add(nd);

                    nd.Name = NameTransformationChainNode(name, comp);
                    nd.Transformation = chain[i];
                }
                Debug.Assert(outputNodes.Count > 0);
                return;
            }

            // else, we can just multiply the matrices together
            aiNode nd_ = new aiNode();
            outputNodes.Add(nd_);

            nd_.Name = name;

            nd_.Transformation = Matrix.Identity;
            for (int i = 0; i < Enum.GetValues(typeof(TransformationComp)).Length; ++i)
            {
                nd_.Transformation = nd_.Transformation * chain[i];
            }
        }
Example #8
0
        private void loadBtn_click(object sender, EventArgs e)
        {
            if (fileOpen.ShowDialog() == DialogResult.OK)
            {
                //Get the path of specified file
                FBXfilePath = fileOpen.FileName;
            }


            bool simpleFormat = false;  // flipped if simpleFormat is detected.

            fbx = assimpSharpImporter.ReadFile(FBXfilePath);


            int materialCount = fbx.Materials.Count;
            int textureCount  = 0;

            int mastervertCount = 0;
            int masterfaceCount = 0;

            int surfacevertCount = 0;
            int surfacefaceCount = 0;


            int masterObjectCount = 0;



            AssimpSharp.Node masterNode = fbx.RootNode.FindNode("Course Master Objects");
            if (masterNode == null)
            {
                simpleFormat = true;
            }
            else
            {
                simpleFormat = false;
            }


            AssimpSharp.Node pathNode = fbx.RootNode.FindNode("Course Paths");
            AssimpSharp.Mesh countObj = null;
            int sectionCount          = 0;


            for (int searchSection = 1; ; searchSection++)
            {
                AssimpSharp.Node searchNode = fbx.RootNode.FindNode("Section " + searchSection.ToString());
                if (searchNode != null)
                {
                    sectionCount++;
                }
                else
                {
                    break;
                }
            }


            //
            // Textures
            //



            textureArray = mk.loadTextures(fbx);

            materialCount = textureArray.Length;

            //
            // Course Objects
            // Surface Map
            //

            if (simpleFormat == false)
            {
                masterObjects     = mk.loadMaster(fbx, textureArray);
                masterObjectCount = masterObjects.Length;
                surfaceObjects    = mk.loadCollision(fbx, sectionCount, textureArray, simpleFormat);
                sectionList       = mk.loadSection(fbx, sectionCount, masterObjects);
            }
            else
            {
                masterObjects     = mk.createMaster(fbx, sectionCount, textureArray);
                masterObjectCount = masterObjects.Length;
                surfaceObjects    = mk.loadCollision(fbx, sectionCount, textureArray, simpleFormat);
                sectionList       = mk.automateSection(sectionCount, surfaceObjects, masterObjects, fbx);
            }

            //
            // Section Views
            //



            countBox.Text     = sectionCount.ToString();
            surfcountBox.Text = sectionCount.ToString();



            for (int currentChild = 0; currentChild < masterObjects.Length; currentChild++)
            {
                masterBox.Items.Add(masterObjects[currentChild].objectName);
            }

            for (int currentIndex = 0; currentIndex < surfaceObjects.Length; currentIndex++)
            {
                surfaceobjectBox.Items.Add(surfaceObjects[currentIndex].objectName);
            }
            for (int currentSection = 0; currentSection < sectionCount; currentSection++)
            {
                surfsectionBox.Items.Add("Section " + (currentSection + 1).ToString());
                sectionBox.Items.Add("Section " + (currentSection + 1).ToString());
            }
            for (int surfacematerialIndex = 0; surfacematerialIndex < surfaceType.Length; surfacematerialIndex++)
            {
                surfmaterialBox.Items.Add(surfaceTypeID[surfacematerialIndex].ToString("X") + "- " + surfaceType[surfacematerialIndex]);
            }
            foreach (var viewstring in viewString)
            {
                viewBox.Items.Add(viewstring);
            }



            for (int materialIndex = 0; materialIndex < materialCount; materialIndex++)
            {
                if (textureArray[materialIndex].texturePath != null)
                {
                    if (textureArray[materialIndex].textureClass == -1)
                    {
                        MessageBox.Show("Warning! Texture wrong dimensions -" + textureArray[materialIndex].textureName + "- Height: " + textureArray[materialIndex].textureHeight + "   Width: " + textureArray[materialIndex].textureWidth);
                        textureBox.Items.Add("UNUSABLE " + materialIndex.ToString() + " - " + textureArray[materialIndex].textureName);
                    }
                    else
                    {
                        textureBox.Items.Add("Material " + materialIndex.ToString() + " - " + textureArray[materialIndex].textureName);
                    }
                    textureCount++;
                }
                else
                {
                    MessageBox.Show("Warning! Material " + fbx.Materials[materialIndex].Name + " does not have a diffuse texture and cannot be used.");
                    textureArray[materialIndex].textureName = fbx.Materials[materialIndex].Name;
                    textureBox.Items.Add("UNUSABLE " + materialIndex.ToString() + " - " + textureArray[materialIndex].textureName);
                }
            }

            viewBox.SelectedIndex = 0;

            mcountBox.Text = materialCount.ToString();
            tcountBox.Text = textureCount.ToString();

            textureBox.SelectedIndex = 0;
            lastMaterial             = 0;


            objcountBox.Text = surfaceCount.ToString();

            MessageBox.Show("Finished Loading .FBX");
            loaded = true;
            sectionBox.SelectedIndex = 0;

            compilebtn.Enabled = true;
            mvertBox.Text      = mastervertCount.ToString();
            mfaceBox.Text      = masterfaceCount.ToString();
            mobjectbox.Text    = masterObjectCount.ToString();
        }