/// <summary>
        /// Return the bones to export.
        /// </summary>
        /// <param name="skin">the skin to export</param>
        /// <returns>Array of BabylonBone to export</returns>
        private BabylonBone[] ExportBones(MFnSkinCluster skin)
        {
            int logRank   = 1;
            int skinIndex = GetSkeletonIndex(skin);
            List <BabylonBone>       bones = new List <BabylonBone>();
            Dictionary <string, int> indexByFullPathName = GetIndexByFullPathNameDictionary(skin);
            List <MObject>           revelantNodes       = GetRevelantNodes(skin);

            progressBoneStep = progressSkinStep / revelantNodes.Count;

            foreach (MObject node in revelantNodes)
            {
                MFnDagNode   dagNode = new MFnDagNode(node);
                MFnTransform currentNodeTransform = new MFnTransform(node);
                string       currentFullPathName  = dagNode.fullPathName;
                int          index       = indexByFullPathName[currentFullPathName];
                int          parentIndex = -1;
                string       parentId    = null;
                // find the parent node to get its index
                if (!dagNode.parent(0).hasFn(MFn.Type.kWorld))
                {
                    MFnTransform firstParentTransform = new MFnTransform(dagNode.parent(0));
                    parentId    = firstParentTransform.uuid().asString();
                    parentIndex = indexByFullPathName[firstParentTransform.fullPathName];
                }

                string boneId = currentNodeTransform.uuid().asString();
                // create the bone
                BabylonBone bone = new BabylonBone()
                {
                    id              = (!isBabylonExported)?boneId:boneId + "-bone",// the suffix "-bone" is added in babylon export format to assure the uniqueness of IDs
                    parentNodeId    = parentId,
                    name            = dagNode.name,
                    index           = indexByFullPathName[currentFullPathName],
                    parentBoneIndex = parentIndex,
                    matrix          = GetBabylonMatrix(currentNodeTransform, frameBySkeletonID[skinIndex]).m,
                    animation       = GetAnimationsFrameByFrameMatrix(currentNodeTransform)
                };

                bones.Add(bone);
                RaiseVerbose($"Bone: name={bone.name}, index={bone.index}, parentBoneIndex={bone.parentBoneIndex}, matrix={string.Join(" ", bone.matrix)}", logRank + 1);

                // Progress bar
                progressSkin += progressBoneStep;
                ReportProgressChanged(progressSkin);
                CheckCancelled();
            }

            // sort
            List <BabylonBone> sorted = new List <BabylonBone>();

            sorted = bones.OrderBy(bone => bone.index).ToList();
            bones  = sorted;

            RaiseMessage($"{bones.Count} bone(s) exported", logRank + 1);

            return(bones.ToArray());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Return the bones to export.
        /// </summary>
        /// <param name="skin">the skin to export</param>
        /// <returns>Array of BabylonBone to export</returns>
        private BabylonBone[] ExportBones(MFnSkinCluster skin)
        {
            int logRank   = 1;
            int skinIndex = GetSkeletonIndex(skin);
            List <BabylonBone>       bones = new List <BabylonBone>();
            Dictionary <string, int> indexByFullPathName = GetIndexByFullPathNameDictionary(skin);
            List <MObject>           revelantNodes       = GetRevelantNodes(skin);

            progressBoneStep = progressSkinStep / revelantNodes.Count;

            foreach (MObject node in revelantNodes)
            {
                MFnDagNode   dagNode = new MFnDagNode(node);
                MFnTransform currentNodeTransform = new MFnTransform(node);
                string       currentFullPathName  = dagNode.fullPathName;
                int          index       = indexByFullPathName[currentFullPathName];
                int          parentIndex = -1;

                // find the parent node to get its index
                if (!dagNode.parent(0).hasFn(MFn.Type.kWorld))
                {
                    MFnTransform firstParentTransform = new MFnTransform(dagNode.parent(0));
                    parentIndex = indexByFullPathName[firstParentTransform.fullPathName];
                }

                // create the bone
                BabylonBone bone = new BabylonBone()
                {
                    name            = currentFullPathName,
                    index           = indexByFullPathName[currentFullPathName],
                    parentBoneIndex = parentIndex,
                    matrix          = ConvertMayaToBabylonMatrix(currentNodeTransform.transformationMatrix).m.ToArray(),
                    animation       = GetAnimationsFrameByFrameMatrix(currentNodeTransform)
                };

                bones.Add(bone);
                RaiseMessage($"Bone: name={bone.name}, index={bone.index}, parentBoneIndex={bone.parentBoneIndex}, matrix={string.Join(" ", bone.matrix)}", logRank + 1);

                // Progress bar
                progressSkin += progressBoneStep;
                ReportProgressChanged(progressSkin);
                CheckCancelled();
            }

            // sort
            List <BabylonBone> sorted = new List <BabylonBone>();

            sorted = bones.OrderBy(bone => bone.index).ToList();
            bones  = sorted;

            RaiseMessage($"{bones.Count} bone(s) exported", logRank + 1);

            return(bones.ToArray());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Find a bone in the skin cluster connections.
        /// From this bone travel the Dag up to the root node.
        /// </summary>
        /// <param name="skin">The skin cluster</param>
        /// <returns>
        /// The root node of the skeleton.
        /// </returns>
        private MObject GetRootNode(MFnSkinCluster skin)
        {
            MObject rootJoint = null;

            if (rootBySkin.ContainsKey(skin))
            {
                return(rootBySkin[skin]);
            }

            // Get a joint of the skin
            rootJoint = GetInfluentNodes(skin)[0];

            // Check the joint parent until it's a kWorld
            MFnDagNode        mFnDagNode  = new MFnDagNode(rootJoint);
            MObject           firstParent = mFnDagNode.parent(0);
            MFnDependencyNode node        = new MFnDependencyNode(firstParent);

            while (!firstParent.apiType.Equals(MFn.Type.kWorld))
            {
                rootJoint   = firstParent;
                mFnDagNode  = new MFnDagNode(rootJoint);
                firstParent = mFnDagNode.parent(0);
                node        = new MFnDependencyNode(firstParent);
            }

            rootBySkin.Add(skin, rootJoint);
            return(rootJoint);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Init the two list influentNodesBySkin and revelantNodesBySkin of a skin cluster.
        /// By getting the parents of the influent nodes.
        /// </summary>
        /// <param name="skin">the skin cluster</param>
        /// <returns>
        /// The list of nodes that form the skeleton
        /// </returns>
        private List <MObject> GetRevelantNodes(MFnSkinCluster skin)
        {
            if (revelantNodesBySkin.ContainsKey(skin))
            {
                return(revelantNodesBySkin[skin]);
            }

            List <MObject> influentNodes = GetInfluentNodes(skin);
            List <MObject> revelantNodes = new List <MObject>();


            // Add parents until it's a kWorld
            foreach (MObject node in influentNodes)
            {
                MObject currentNode = node;
                //MObject parent = findValidParent(node);   // A node can have several parents. Which one is the right one ? It seems that the first one is most likely a transform

                while (!currentNode.apiType.Equals(MFn.Type.kWorld))
                {
                    MFnDagNode dagNode = new MFnDagNode(currentNode);

                    if (revelantNodes.Count(revelantNode => Equals(revelantNode, currentNode)) == 0)
                    {
                        revelantNodes.Add(currentNode);
                    }

                    // iter
                    MObject firstParent = dagNode.parent(0);
                    currentNode = firstParent;
                }
            }
            revelantNodesBySkin.Add(skin, revelantNodes);

            return(revelantNodes);
        }
Exemplo n.º 5
0
        private void buildMeshNodes()
        {
            MItDependencyNodes it = new MItDependencyNodes(MFn.Type.kMesh);

            while (!it.isDone)
            {
                // Get the dag node of the mesh.
                MFnDagNode dagNode = new MFnDagNode(it.thisNode);
                // Create a new mesh.
                MayaMesh meshNode = new MayaMesh();
                // Add the mesh to the all meshes list.
                allMeshes.Add(meshNode);
                // Configure the mesh node
                meshNode.name = dagNode.fullPathName;
                dagNode.getPath(meshNode.mayaObjectPath);
                meshNode.id = allMeshes.Count - 1;
                // The first parent of a mesh is the source transform, even with instances.
                meshNode.sourceXForm = pathXformMap[(new MFnDagNode(dagNode.parent(0))).fullPathName];
                // Set the source Xform to know it's a source for an instance (its mesh).
                meshNode.sourceXForm.isSourceXform = true;
                // If the mesh has more than one parent, it has been instanced.  We need to know this for computing local positions.
                meshNode.isInstanced = dagNode.isInstanced();
                // Add the map to the dictionary to search by name.
                pathMeshMap[meshNode.name] = meshNode;
                it.next();
            }
        }
Exemplo n.º 6
0
        private void ExportNode(BabylonAbstractMesh babylonAbstractMesh, MFnDagNode mFnDagNode, BabylonScene babylonScene)
        {
            if (mFnDagNode.parentCount != 0)
            {
                MObject    parentMObject    = mFnDagNode.parent(0);
                MFnDagNode mFnDagNodeParent = new MFnDagNode(parentMObject);

                // Position / rotation / scaling
                ExportTransform(babylonAbstractMesh, mFnDagNodeParent);

                // TODO - Hierarchy
                //babylonAbstractMesh.parentId = mFnDagNodeParent.uuid().asString();
            }
        }
Exemplo n.º 7
0
		//
		// If a DAG node is instanced (i.e. has multiple parents), this method
		// will put it under its remaining parents.  It will already have been put
		// under its first parent when it was created.
		//
		protected void writeInstances(FileStream f)
		{
			uint numInstancedNodes = fInstanceChildren.length;
			int i;

			for (i = 0; i < numInstancedNodes; i++)
			{
                MFnDagNode nodeFn = new MFnDagNode(fInstanceChildren[i]);

                uint numParents = nodeFn.parentCount;
                uint p;

                for (p = 0; p < numParents; p++)
                {
                    //
                    // We don't want to issue a 'parent' command for the node's
                    // existing parent.
                    //
                    try
                    {
                        if (nodeFn.parent((uint)i).notEqual(fInstanceParents[i].node))
                        {
                            MObject parent = nodeFn.parent((uint)i);
                            MFnDagNode parentFn = new MFnDagNode(parent);

                            if (!parentFn.isFromReferencedFile)
                            {
                                //
                                // Get the first path to the parent node.
                                //
                                MDagPath parentPath = new MDagPath();

                                MDagPath.getAPathTo(parentFn.objectProperty, parentPath);

                                writeParent(f, parentPath, fInstanceChildren[i], true);
                            }
                        }
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
            }

			//
			// We don't need this any more, so free up the space.
			//
			fInstanceChildren.clear();
			fInstanceParents.clear();
		}
Exemplo n.º 8
0
		protected void writeDagNodes(FileStream f)
		{
			fParentingRequired.clear();

			MItDag	dagIter = new MItDag();

			dagIter.traverseUnderWorld(true);

			MDagPath worldPath = new MDagPath();

			dagIter.getPath(worldPath);

			//
			// We step over the world node before starting the loop, because it
			// doesn't get written out.
			//
			for (dagIter.next(); !dagIter.isDone; dagIter.next())
			{
				MDagPath	path = new MDagPath();
				dagIter.getPath(path);

				//
				// If the node has already been written, then all of its descendants
				// must have been written, or at least checked, as well, so prune
				// this branch of the tree from the iteration.
				//
				MFnDagNode	dagNodeFn = new MFnDagNode(path);

				if (dagNodeFn.isFlagSet(fCreateFlag))
				{
					dagIter.prune();
					continue;
				}

				//
				// If this is a default node, it will be written out later, so skip
				// it.
				//
				if (dagNodeFn.isDefaultNode) continue;

				//
				// If this node is not writable, and is not a shared node, then mark
				// it as having been written, and skip it.
				//
				if (!dagNodeFn.canBeWritten && !dagNodeFn.isShared)
				{
					dagNodeFn.setFlag(fCreateFlag, true);
					continue;
				}

				uint numParents = dagNodeFn.parentCount;

				if (dagNodeFn.isFromReferencedFile)
				{
					//
					// We don't issue 'creatNode' commands for nodes from referenced
					// files, but if the node has any parents which are not from
					// referenced files, other than the world, then make a note that
					// we'll need to issue extra 'parent' commands for it later on.
					//
					uint i;

					for (i = 0; i < numParents; i++)
					{
						MObject		altParent = dagNodeFn.parent(i);
						MFnDagNode	altParentFn = new MFnDagNode(altParent);

						if (!altParentFn.isFromReferencedFile
						&&	(altParentFn.objectProperty.notEqual(worldPath.node)))
						{
							fParentingRequired.append(path);
							break;
						}
					}
				}
				else
				{
					//
					// Find the node's parent.
					//
					MDagPath parentPath = new MDagPath(worldPath);

					if (path.length > 1)
					{
						//
						// Get the parent's path.
						//
						parentPath.assign(path);
						parentPath.pop();

						//
						// If the parent is in the underworld, then find the closest
						// ancestor which is not.
						//
						if (parentPath.pathCount > 1)
						{
							//
							// The first segment of the path contains whatever
							// portion of the path exists in the world.  So the closest
							// worldly ancestor is simply the one at the end of that
							// first path segment.
							//
							path.getPath(parentPath, 0);
						}
					}

					MFnDagNode	parentNodeFn = new MFnDagNode(parentPath);

					if (parentNodeFn.isFromReferencedFile)
					{
						//
						// We prefer to parent to a non-referenced node.  So if this
						// node has any other parents, which are not from referenced
						// files and have not already been processed, then we'll
						// skip this instance and wait for an instance through one
						// of those parents.
						//
						uint i;

						for (i = 0; i < numParents; i++)
						{
							if (dagNodeFn.parent(i).notEqual(parentNodeFn.objectProperty))
							{
								MObject		altParent = dagNodeFn.parent(i);
								MFnDagNode	altParentFn = new MFnDagNode(altParent);

								if (!altParentFn.isFromReferencedFile
								&&	!altParentFn.isFlagSet(fCreateFlag))
								{
									break;
								}
							}
						}

						if (i < numParents) continue;

						//
						// This node only has parents within referenced files, so
						// create it without a parent and note that we need to issue
						// 'parent' commands for it later on.
						//
						writeCreateNode(f, path, worldPath);

						fParentingRequired.append(path);
					}
					else
					{
						writeCreateNode(f, path, parentPath);

						//
						// Let's see if this node has any parents from referenced
						// files, or any parents other than this one which are not
						// from referenced files.
						//
						uint i;
						bool hasRefParents = false;
						bool hasOtherNonRefParents = false;

						for (i = 0; i < numParents; i++)
						{
							if (dagNodeFn.parent(i).notEqual(parentNodeFn.objectProperty))
							{
								MObject		altParent = dagNodeFn.parent(i);
								MFnDagNode	altParentFn = new MFnDagNode(altParent);

								if (altParentFn.isFromReferencedFile)
									hasRefParents = true;
								else
									hasOtherNonRefParents = true;

								//
								// If we've already got positives for both tests,
								// then there's no need in continuing.
								//
								if (hasRefParents && hasOtherNonRefParents) break;
							}
						}

						//
						// If this node has parents from referenced files, then
						// make note that we will have to issue 'parent' commands
						// later on.
						//
						if (hasRefParents) fParentingRequired.append(path);

						//
						// If this node has parents other than this one which are
						// not from referenced files, then make note that the
						// parenting for the other instances still has to be done.
						//
						if (hasOtherNonRefParents)
						{
							fInstanceChildren.append(path);
							fInstanceParents.append(parentPath);
						}
					}

					//
					// Write out the node's 'addAttr', 'setAttr' and 'lockNode'
					// commands.
					//
					writeNodeAttrs(f, path.node, true);
					writeLockNode(f, path.node);
				}

				//
				// Mark the node as having been written.
				//
				dagNodeFn.setFlag(fCreateFlag, true);
			}

			//
			// Write out the parenting for instances.
			//
			writeInstances(f);
		}
Exemplo n.º 9
0
		//
		// Deal with nodes whose parenting is between referenced and non-referenced
		// nodes.
		//
		protected void writeRefNodeParenting(FileStream f)
		{
			uint numNodes = fParentingRequired.length;
			int i;

			for (i = 0; i < numNodes; i++)
			{
				MFnDagNode	nodeFn = new MFnDagNode(fParentingRequired[i]);

				//
				// Find out if this node has any parents from referenced or
				// non-referenced files.
				//
				bool hasRefParents = false;
				bool hasNonRefParents = false;
				uint numParents = nodeFn.parentCount;
				uint p;

				for (p = 0; p < numParents; p++)
				{
					MObject		parent = nodeFn.parent(p);
					MFnDagNode	parentFn = new MFnDagNode(parent);

					if (parentFn.isFromReferencedFile)
						hasRefParents = true;
					else
						hasNonRefParents = true;

					if (hasRefParents && hasNonRefParents) break;
				}

				//
				// If this node is from a referenced file and it has parents which
				// are also from a referenced file, then it already has its first
				// parent and all others are added instances.
				//
				// Similarly if the node is not from a referenced file and has
				// parents which are also not from referenced files.
				//
				bool	alreadyHasFirstParent =
					(nodeFn.isFromReferencedFile ? hasRefParents : hasNonRefParents);

				//
				// Now run through the parents again and output any parenting
				// which involves a non-referenced node, either as parent or child.
				//
				for (p = 0; p < numParents; p++)
				{
					MObject		parent = nodeFn.parent(p);
					MFnDagNode	parentFn = new MFnDagNode(parent);

					if (parentFn.isFromReferencedFile != nodeFn.isFromReferencedFile)
					{
						//
						// Get the first path to the parent.
						//
						MDagPath	parentPath = new MDagPath();
						MDagPath.getAPathTo(parentFn.objectProperty, parentPath);

						writeParent(
							f, parentPath, fParentingRequired[i], alreadyHasFirstParent
						);

						//
						// If it didn't have its first parent before, it does now.
						//
						alreadyHasFirstParent = true;
					}
				}
			}
		}
Exemplo n.º 10
0
 private void buildMeshNodes()
 {
     MItDependencyNodes it = new MItDependencyNodes(MFn.Type.kMesh);
     while( !it.isDone )
     {
         // Get the dag node of the mesh.
         MFnDagNode dagNode = new MFnDagNode(it.thisNode);
         // Create a new mesh.
         MayaMesh meshNode = new MayaMesh();
         // Add the mesh to the all meshes list.
         allMeshes.Add(meshNode);
         // Configure the mesh node
         meshNode.name = dagNode.fullPathName;
         dagNode.getPath(meshNode.mayaObjectPath);
         meshNode.id = allMeshes.Count - 1;
         // The first parent of a mesh is the source transform, even with instances.
         meshNode.sourceXForm = pathXformMap[(new MFnDagNode(dagNode.parent(0))).fullPathName];
         // Set the source Xform to know it's a source for an instance (its mesh).
         meshNode.sourceXForm.isSourceXform = true;
         // If the mesh has more than one parent, it has been instanced.  We need to know this for computing local positions.
         meshNode.isInstanced = dagNode.isInstanced();
         // Add the map to the dictionary to search by name.
         pathMeshMap[meshNode.name] = meshNode;
         it.next();
     }
 }
Exemplo n.º 11
0
        private void buildLightNodes()
        {
            MItDependencyNodes it = new MItDependencyNodes(MFn.Type.kLight);
            while( !it.isDone )
            {
                MObject mayaObj = it.thisNode;
                if( shouldPruneLight(mayaObj) )
                {
                    it.next();
                    continue;
                }

                // Create a new light and add it to the all lights list.
                MayaLight light = new MayaLight();
                allLights.Add(light);
                light.id = allLights.Count - 1;
                // Get the dag node of the light for its name and parent.
                MFnDagNode dagNode = new MFnDagNode(mayaObj);
                dagNode.getPath(light.mayaObjectPath);
                light.name = dagNode.fullPathName;
                // First parent is the source transform node.
                light.sourceXform = pathXformMap[(new MFnDagNode(dagNode.parent(0))).fullPathName];
                // Add the light to the dictionary to search by name.
                pathLightMap[light.name] = light;

                //
                // NOTE: Parent transforms of light sources in Maya can NOT be frozen,
                //       so accessing them is guaranteed to not be frozen.
                //

                if( mayaObj.hasFn(MFn.Type.kAmbientLight) )
                {
                    MFnAmbientLight mayaLight = new MFnAmbientLight(mayaObj);
                    light.type = MayaLight.Type.kAmbient;
                    light.color = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                }
                else if( mayaObj.hasFn(MFn.Type.kDirectionalLight) )
                {
                    MFnDirectionalLight mayaLight = new MFnDirectionalLight(mayaObj);
                    light.type = MayaLight.Type.kDirectional;
                    light.color = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                }
                else if( mayaObj.hasFn(MFn.Type.kPointLight) )
                {
                    MFnPointLight mayaLight = new MFnPointLight(mayaObj);
                    light.type = MayaLight.Type.kPoint;
                    light.color = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                    light.range = (float)mayaLight.centerOfIllumination;
                }
                else if( mayaObj.hasFn(MFn.Type.kSpotLight) )
                {
                    MFnSpotLight mayaLight = new MFnSpotLight(mayaObj);
                    light.type = MayaLight.Type.kSpot;
                    light.color = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                    light.range = (float)mayaLight.centerOfIllumination;
                    float mayaConeAngle = (float)(mayaLight.coneAngle * 0.5);
                    light.coneInnerAngle = 57.29578f * mayaConeAngle;
                    light.coneOuterAngle = 57.29578f * (mayaConeAngle + Math.Abs((float)mayaLight.penumbraAngle));
                }

                it.next();
            }
        }
Exemplo n.º 12
0
        private void buildLightNodes()
        {
            MItDependencyNodes it = new MItDependencyNodes(MFn.Type.kLight);

            while (!it.isDone)
            {
                MObject mayaObj = it.thisNode;
                if (shouldPruneLight(mayaObj))
                {
                    it.next();
                    continue;
                }

                // Create a new light and add it to the all lights list.
                MayaLight light = new MayaLight();
                allLights.Add(light);
                light.id = allLights.Count - 1;
                // Get the dag node of the light for its name and parent.
                MFnDagNode dagNode = new MFnDagNode(mayaObj);
                dagNode.getPath(light.mayaObjectPath);
                light.name = dagNode.fullPathName;
                // First parent is the source transform node.
                light.sourceXform = pathXformMap[(new MFnDagNode(dagNode.parent(0))).fullPathName];
                // Add the light to the dictionary to search by name.
                pathLightMap[light.name] = light;

                //
                // NOTE: Parent transforms of light sources in Maya can NOT be frozen,
                //       so accessing them is guaranteed to not be frozen.
                //

                if (mayaObj.hasFn(MFn.Type.kAmbientLight))
                {
                    MFnAmbientLight mayaLight = new MFnAmbientLight(mayaObj);
                    light.type      = MayaLight.Type.kAmbient;
                    light.color     = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                }
                else if (mayaObj.hasFn(MFn.Type.kDirectionalLight))
                {
                    MFnDirectionalLight mayaLight = new MFnDirectionalLight(mayaObj);
                    light.type      = MayaLight.Type.kDirectional;
                    light.color     = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                }
                else if (mayaObj.hasFn(MFn.Type.kPointLight))
                {
                    MFnPointLight mayaLight = new MFnPointLight(mayaObj);
                    light.type      = MayaLight.Type.kPoint;
                    light.color     = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                    light.range     = (float)mayaLight.centerOfIllumination;
                }
                else if (mayaObj.hasFn(MFn.Type.kSpotLight))
                {
                    MFnSpotLight mayaLight = new MFnSpotLight(mayaObj);
                    light.type      = MayaLight.Type.kSpot;
                    light.color     = new Color(mayaLight.color.r, mayaLight.color.g, mayaLight.color.b, mayaLight.color.a);
                    light.intensity = mayaLight.intensity;
                    light.range     = (float)mayaLight.centerOfIllumination;
                    float mayaConeAngle = (float)(mayaLight.coneAngle * 0.5);
                    light.coneInnerAngle = 57.29578f * mayaConeAngle;
                    light.coneOuterAngle = 57.29578f * (mayaConeAngle + Math.Abs((float)mayaLight.penumbraAngle));
                }

                it.next();
            }
        }