コード例 #1
0
        public override void doIt(MArgList args)
        {
            string fileName;

            MArgDatabase argData = new MArgDatabase(syntax, args);

            if (argData.isFlagSet(kFileNameFlag))
            {
                fileName = argData.flagArgumentString(kFileNameFlag, 0);

                if (fileName != null)
                {
                    string currFile = MFileIO.fileCurrentlyLoading;

                    MStringArray pathDirectories = new MStringArray(currFile.Split('/'));

                    if (pathDirectories.length > 0)
                    {
                        string expandedFileName = "";

                        for (int i = 0; i < pathDirectories.length - 1; i++)
                        {
                            expandedFileName += pathDirectories[i];
                            expandedFileName += "/";
                        }

                        expandedFileName += fileName;

                        MGlobal.sourceFile(expandedFileName);
                    }
                }
            }

            return;
        }
コード例 #2
0
        // --- Utilities ---

        /// <summary>
        /// Retreive meshes having specified material id
        /// Meshes are split into 2 categories: Opaque or Transparent
        /// </summary>
        /// <param name="babylonScene"></param>
        /// <param name="materialId"></param>
        /// <param name="meshesOpaque"></param>
        /// <param name="meshesTransparent"></param>
        private void getMeshesByMaterialId(BabylonScene babylonScene, string materialId, List <BabylonMesh> meshesOpaque, List <BabylonMesh> meshesTransparent)
        {
            babylonScene.MeshesList.ForEach(mesh =>
            {
                if (mesh.materialId == materialId)
                {
                    // Get mesh full path name (unique)
                    MStringArray meshFullPathName = new MStringArray();
                    // Surround uuid with quotes like so: ls "18D0785F-4E8E-1621-01E1-84AD39F92289";
                    // ls command output must be an array
                    MGlobal.executeCommand($@"ls ""{mesh.id}"";", meshFullPathName);

                    int meshOpaqueInt;
                    MGlobal.executeCommand($@"getAttr {meshFullPathName[0]}.aiOpaque;", out meshOpaqueInt);
                    if (meshOpaqueInt == 1)
                    {
                        meshesOpaque.Add(mesh);
                    }
                    else
                    {
                        meshesTransparent.Add(mesh);
                    }
                }
            });
        }
コード例 #3
0
        protected override void processWriteOptions(string optionsString)
        {
            includedNodeTypesArray = new MStringArray();
            excludedNodeTypesArray = new MStringArray();
            sourcedFilesArray      = new MStringArray();
            excludedNamesArray     = new MStringArray();

            outputRequirements = true;
            outputReferences   = true;

            MStringArray optionsArray = new MStringArray(optionsString.Split(';'));

            for (int i = 0; i < optionsArray.length; i++)
            {
                string       option      = optionsArray[i];
                MStringArray optionArray = new MStringArray(option.Split(' '));

                if (optionArray[0] == "includeNodeType" && optionArray.length > 1)
                {
                    includedNodeTypesArray.append(optionArray[1]);
                }
                else if (optionArray[0] == "excludeNodeType" && optionArray.length > 1)
                {
                    excludedNodeTypesArray.append(optionArray[1]);
                }
                else if (optionArray[0] == "sourceFile" && optionArray.length > 1)
                {
                    sourcedFilesArray.append(optionArray[1]);
                }
            }

            return;
        }
コード例 #4
0
        public static List <Curve> getSmothMeshEdges(MFnMesh mayaMesh, bool createInMaya = false)
        {
            //MCommandResult result = new MCommandResult();
            int          ne           = mayaMesh.numEdges;
            MFnTransform group        = new MFnTransform();
            List <Curve> curveObjects = new List <Curve>(ne);
            MStringArray resultStr    = new MStringArray();

            var    fullName      = mayaMesh.fullPathName.Split('|');
            string transformName = fullName[fullName.Length - 2];


            if (createInMaya)
            {
                for (int i = 0; i < ne; i++)
                {
                    using (MCommandResult result = new MCommandResult())
                    {
                        MGlobal.executeCommand(
                            $"polyToCurve -name {transformName}Curves -form 2 -degree 3 -conformToSmoothMeshPreview 1 {transformName}.e[{i}]",
                            result);
                        result.getResult(resultStr);
                        curveObjects.Add(
                            DMCurve.CurveFromMfnNurbsCurveFromName(resultStr[0],
                                                                   MSpace.Space.kPostTransform.ToString()));
                    }
                }
            }
            else
            {
                //Parallel.For(0, ne, i => {
                for (int i = 0; i < ne; i++)
                {
                    using (MCommandResult result = new MCommandResult())
                    {
                        MGlobal.executeCommand(
                            $"polyToCurve -name deleteMe11232204332AA -form 2 -degree 3 -conformToSmoothMeshPreview 1 {transformName}.e[{i}]",
                            result);
                        result.getResult(resultStr);
                        curveObjects.Add(
                            DMCurve.CurveFromMfnNurbsCurveFromName(resultStr[0],
                                                                   MSpace.Space.kPostTransform.ToString()));
                        try
                        {
                            MGlobal.deleteNode(DMInterop.getDependNode(resultStr[0]));
                        }
                        catch
                        {
                            MGlobal.displayWarning("getSmothMeshEdges: unable to delete temp object");
                        }
                    }
                }

                // });
            }


            return(curveObjects);
        }
コード例 #5
0
        public static List <List <Curve> > getSmothMeshEdgesPerFace(MFnMesh mayaMesh, bool createInMaya = false)
        {
            MCommandResult ptcResult = new MCommandResult();
            MCommandResult teResult  = new MCommandResult();

            int numPoly = mayaMesh.numPolygons;

            List <List <Curve> > curveObjects    = new  List <List <Curve> >(numPoly);
            MStringArray         ptcResultStr    = new MStringArray();
            MStringArray         teResultStr     = new MStringArray();
            MStringArray         teResultStrFlat = new MStringArray();

            List <Curve> tempCurveArray = null;

            if (createInMaya)
            {
            }
            else
            {
                for (int i = 0; i < numPoly; i++)
                {
                    MGlobal.executeCommand($"polyListComponentConversion -te {mayaMesh.name}.f[{i}]", teResult);
                    teResult.getResult(teResultStr);
                    MGlobal.clearSelectionList();

                    foreach (var ters in teResultStr)
                    {
                        MGlobal.selectByName(ters, MGlobal.ListAdjustment.kAddToList);
                    }
                    MGlobal.executeCommand($"ls -sl -fl", teResult);
                    teResult.getResult(teResultStrFlat);

                    tempCurveArray = new List <Curve>((int)teResultStrFlat.length);

                    foreach (var e in teResultStrFlat)
                    {
                        MGlobal.executeCommand($"polyToCurve -name deleteMe11232204332AA -form 2 -degree 3 -conformToSmoothMeshPreview 1 {e}", ptcResult);
                        ptcResult.getResult(ptcResultStr);
                        tempCurveArray.Add(DMCurve.CurveFromMfnNurbsCurveFromName(ptcResultStr[0], MSpace.Space.kPostTransform.ToString()));
                        try
                        {
                            MGlobal.deleteNode(DMInterop.getDependNode(ptcResultStr[0]));
                        }
                        catch
                        {
                            MGlobal.displayWarning("getSmothMeshEdges: unable to delete temp object");
                        }
                    }

                    curveObjects.Add(tempCurveArray);
                }
            }


            return(curveObjects);
        }
コード例 #6
0
        private static void postPluginUnloadCallback(object sender, MStringArrayFunctionArgs args)
        {
            MStringArray str = args.strs;

            MGlobal.displayInfo("POST plugin unload callback with " + str.length + " items:");
            for (int i = 0; i < str.length; i++)
            {
                MGlobal.displayInfo("\tCallback item " + i + " is : " + str[i]);
            }
        }
コード例 #7
0
ファイル: DMLocator.cs プロジェクト: cerver/DynaMayaV2
        internal static bool createLocator(double x, double y, double z, double rx, double ry, double rz, string name)
        {
            MStringArray moveResult   = new MStringArray();
            MStringArray rotateResult = new MStringArray();

            MGlobal.executeCommand(string.Format("spaceLocator -a -p {0} {1} {2} -n {3}", x, y, z, name), moveResult);
            MGlobal.executeCommand(string.Format("rotate {0} {1} {2} {3}", rx, ry, rz, name), rotateResult);

            return(true);
        }
コード例 #8
0
        private void computeMeshData()
        {
            foreach (MayaMesh mesh in allMeshes)
            {
                // Get the Maya mesh
                MFnMesh mayaMesh = new MFnMesh(mesh.mayaObjectPath);

                // Does the maya mesh have UVs?
                MStringArray uvSetNames = new MStringArray();
                mayaMesh.getUVSetNames(uvSetNames);
                bool hasUvs = (uvSetNames.length > 0) && (mayaMesh.numUVs(uvSetNames[0]) > 0);

                // Iterate through all of the vertices and build the data.
                MItMeshFaceVertex it = new MItMeshFaceVertex(mesh.mayaObjectPath);
                while (!it.isDone)
                {
                    // Create a new vertex and populate its data.
                    Vertex vert = new Vertex();

                    // Get the local position relative to the world origin.
                    MPoint mayaPos = it.position(MSpace.Space.kObject);
                    vert.position = new Vector3((float)mayaPos.x, (float)mayaPos.y, (float)mayaPos.z);
                    //vert.position = new Vector3((float)mayaPos.x - mesh.sourceXForm.mayaWorldPosition.x,
                    //(float)mayaPos.y - mesh.sourceXForm.mayaWorldPosition.y,
                    //(float)mayaPos.z - mesh.sourceXForm.mayaWorldPosition.z);

                    // Get the normal.
                    MVector mayaNrm = new MVector();
                    it.getNormal(mayaNrm, MSpace.Space.kObject);
                    vert.normal = new Vector3((float)mayaNrm.x, (float)mayaNrm.y, (float)mayaNrm.z);

                    // Texcoords.
                    if (hasUvs && it.hasUVsProperty)
                    {
                        float[] mayaUvs = new float[2];
                        it.getUV(mayaUvs, uvSetNames[0]);
                        vert.texcoord = new Vector2(mayaUvs[0], mayaUvs[1]);
                    }

                    // Append the vertex.
                    mesh.vertices.Add(vert);
                    it.next();
                }

                // Get all index data.
                MIntArray mia1 = new MIntArray();
                MIntArray mia2 = new MIntArray();
                mayaMesh.getTriangleOffsets(mia1, mia2);
                foreach (int idx in mia2)
                {
                    mesh.indices.Add((uint)idx);
                }
            }
        }
コード例 #9
0
        public static List <object> MelCommand(string MelCommand)
        {
            MStringArray   stringResults = new MStringArray();
            MIntArray      intResults    = new MIntArray();
            MDoubleArray   doubleResults = new MDoubleArray();
            MVectorArray   vectorResults = new MVectorArray();
            List <object>  results       = new List <object>();
            MCommandResult mcr           = new MCommandResult();


            MDagPath dag = new MDagPath();

            try
            {
                MGlobal.executeCommand(MelCommand, mcr);
                //   MGlobal.executeCommand(MelCommand, stringResults);
            }
            catch (MemberAccessException e)
            {
                MGlobal.displayWarning(e.Message);
            }

            switch (mcr.resultType)
            {
            case MCommandResult.Type.kStringArray:
                mcr.getResult(stringResults);
                results.AddRange(stringResults);
                break;

            case MCommandResult.Type.kIntArray:
                mcr.getResult(intResults);
                results.AddRange(intResults.Cast <object>());
                break;

            case MCommandResult.Type.kDoubleArray:
                mcr.getResult(doubleResults);
                results.AddRange(doubleResults.Cast <object>());
                break;

            case MCommandResult.Type.kVectorArray:
                mcr.getResult(vectorResults);
                results.AddRange(vectorResults.Cast <object>());
                break;

            default:
                mcr.getResult(stringResults);
                results.AddRange(stringResults);
                break;
            }
            mcr.Dispose();
            return(results);
        }
コード例 #10
0
        internal static bool GetBoolProperty(string property, bool defaultValue = false)
        {
            bool           value  = defaultValue;
            MCommandResult result = new MCommandResult();

            MGlobal.executeCommand($"fileInfo -q \"{property}\"", result);
            if (result.resultType == MCommandResult.Type.kStringArray)
            {
                MStringArray stringArray = new MStringArray();
                result.getResult(stringArray);
                value = string.Join("", stringArray.ToArray()).Equals(true.ToString());
            }

            return(value);
        }
コード例 #11
0
        /// <summary>
        /// The MEL command only return name and not fullPathName. Unfortunatly you need the full path name to differentiate two nodes with the same names.
        ///
        /// </summary>
        /// <param name="skin">The skin cluster</param>
        /// <param name="transform">The transform above the mesh</param>
        /// <returns>
        /// The array with the node full path names.
        /// </returns>
        private MStringArray GetBoneFullPathName(MFnSkinCluster skin, MFnTransform transform)
        {
            int logRank = 3;

            // Get the bone names that influence the mesh
            // We need to keep this order as we will use an other mel command to get the weight influence
            MStringArray mayaInfluenceNames = new MStringArray();

            MGlobal.executeCommand($"skinCluster -q -influence {transform.name}", mayaInfluenceNames);

            List <string> boneFullPathNames = new List <string>();
            MPlugArray    connections       = new MPlugArray();

            // Get the bone full path names of the skin cluster
            foreach (MObject node in GetInfluentNodes(skin))
            {
                boneFullPathNames.Add((new MFnDagNode(node)).fullPathName);
            }

            // Change the name to the fullPathName. And check that they all share the same root node.
            string rootName = "";

            for (int index = 0; index < mayaInfluenceNames.Count; index++)
            {
                string name              = mayaInfluenceNames[index];
                string name_substring    = "|" + name;
                int    indexFullPathName = boneFullPathNames.FindIndex(fullPathName => fullPathName.EndsWith(name_substring));
                mayaInfluenceNames[index] = boneFullPathNames[indexFullPathName];

                if (index == 0)
                {
                    rootName = mayaInfluenceNames[index].Split('|')[1];
                    RaiseVerbose($"rootName: {rootName}", logRank + 1);
                }
                RaiseVerbose($"{index}: {name} => {mayaInfluenceNames[index]}", logRank + 1);

                if (!mayaInfluenceNames[index].StartsWith($"|{rootName}|") && !mayaInfluenceNames[index].Equals($"|{rootName}"))
                {
                    RaiseError($"Bones don't share the same root node. {rootName} != {mayaInfluenceNames[index].Split('|')[1]}", logRank);
                    return(null);
                }
            }

            return(mayaInfluenceNames);
        }
コード例 #12
0
        internal static bool GetUserPropString(string property, ref string value)
        {
            MCommandResult result = new MCommandResult();

            MGlobal.executeCommand($"fileInfo -q \"{property}\"", result);
            if (result.resultType == MCommandResult.Type.kStringArray)
            {
                MStringArray stringArray = new MStringArray();
                result.getResult(stringArray);
                value = string.Join("", stringArray.ToArray());
            }
            else
            {
                value = null;
            }

            return(!string.IsNullOrEmpty(value));
        }
コード例 #13
0
        //! Ensure that valid geometry is selected
        bool validGeometrySelected()
        {
            MSelectionList list = new MSelectionList();

            MGlobal.getActiveSelectionList(list);
            MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

            for (; !iter.isDone; iter.next())
            {
                MObject dependNode = new MObject();
                iter.getDependNode(dependNode);
                if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kTransform))
                {
                    MGlobal.displayWarning("Object in selection list is not right type of node");
                    return(false);
                }

                MFnDependencyNode dependNodeFn   = new MFnDependencyNode(dependNode);
                MStringArray      attributeNames = new MStringArray();
                attributeNames.append("scaleX");
                attributeNames.append("translateX");

                int i;
                for (i = 0; i < attributeNames.length; i++)
                {
                    MPlug plug = dependNodeFn.findPlug(attributeNames[i]);
                    if (plug.isNull)
                    {
                        MGlobal.displayWarning("Object cannot be manipulated: " +
                                               dependNodeFn.name);
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #14
0
ファイル: MayaPlugin.cs プロジェクト: YangYangSaSa6/Exporters
        /// <summary>
        /// Write "GenerateExportersParameter" in a Maya MEL script to get the default export parameters
        /// </summary>
        /// <param name="argl"></param>
        ///
        public override void doIt(MArgList args)
        {
            ScriptExportParameters = new ExportParameters();

            MStringArray result = new MStringArray();

            result.append("");
            result.append("babylon");
            result.append("");
            result.append(ScriptExportParameters.scaleFactor.ToString());
            result.append(ScriptExportParameters.writeTextures.ToString());
            result.append(ScriptExportParameters.overwriteTextures.ToString());
            result.append(ScriptExportParameters.exportHiddenObjects.ToString());
            result.append(ScriptExportParameters.exportMaterials.ToString());
            result.append(ScriptExportParameters.exportOnlySelected.ToString());
            result.append(ScriptExportParameters.bakeAnimationFrames.ToString());
            result.append(ScriptExportParameters.optimizeAnimations.ToString());
            result.append(ScriptExportParameters.optimizeVertices.ToString());
            result.append(ScriptExportParameters.animgroupExportNonAnimated.ToString());
            result.append(ScriptExportParameters.generateManifest.ToString());
            result.append(ScriptExportParameters.autoSaveSceneFile.ToString());
            result.append(ScriptExportParameters.exportTangents.ToString());
            result.append(ScriptExportParameters.exportMorphTangents.ToString());
            result.append(ScriptExportParameters.exportMorphNormals.ToString());
            result.append(ScriptExportParameters.txtQuality.ToString());
            result.append(ScriptExportParameters.mergeAOwithMR.ToString());
            result.append(ScriptExportParameters.dracoCompression.ToString());
            result.append(ScriptExportParameters.enableKHRLightsPunctual.ToString());
            result.append(ScriptExportParameters.enableKHRTextureTransform.ToString());
            result.append(ScriptExportParameters.enableKHRMaterialsUnlit.ToString());
            result.append(ScriptExportParameters.pbrFull.ToString());
            result.append(ScriptExportParameters.pbrNoLight.ToString());
            result.append(ScriptExportParameters.createDefaultSkybox.ToString());
            result.append("");
            setResult(result);
        }
コード例 #15
0
        public conditionTest()
        {
            // Initialize the static members at the first time the command is used.
            if (conditionNames == null)
            {
                conditionNames = new MStringArray();
                MConditionMessage.getConditionNames(conditionNames);

                uint conditionCount = conditionNames.length;
                MGlobal.displayInfo("netConditionTest: " + conditionCount + " conditions are defined.");

                conditionStates    = new bool[conditionCount];
                conditionCallbacks = new bool[conditionCount];
                for (uint i = 0; i < conditionCount; i++)
                {
                    conditionStates[i]    = false;
                    conditionCallbacks[i] = false;
                }
            }

            addMessage = false;
            delMessage = false;
            conditions.clear();
        }
コード例 #16
0
ファイル: conditionTest.cs プロジェクト: meshdgp/MeshDGP
		public conditionTest()
		{
			// Initialize the static members at the first time the command is used.
			if (conditionNames == null)
			{
				conditionNames = new MStringArray();
				MConditionMessage.getConditionNames(conditionNames);

				uint conditionCount = conditionNames.length;
				MGlobal.displayInfo("netConditionTest: " + conditionCount + " conditions are defined.");

				conditionStates = new bool[conditionCount];
				conditionCallbacks = new bool[conditionCount];
				for (uint i = 0; i < conditionCount; i++)
				{
					conditionStates[i] = false;
					conditionCallbacks[i] = false;
				}
			}

			addMessage = false;
			delMessage = false;
			conditions.clear();
		}
コード例 #17
0
ファイル: filteredAsciiFile.cs プロジェクト: meshdgp/MeshDGP
        public override void doIt(MArgList args)
        {
            string fileName;

            MArgDatabase argData = new MArgDatabase(syntax, args);
          
            if (argData.isFlagSet(kFileNameFlag))
            {
	            fileName = argData.flagArgumentString(kFileNameFlag, 0);

	            if (fileName != null)
	            {
		            string currFile = MFileIO.fileCurrentlyLoading;

		            MStringArray pathDirectories = new MStringArray(currFile.Split('/'));

		            if (pathDirectories.length > 0)
		            {
			            string expandedFileName = "";

			            for (int i = 0; i < pathDirectories.length-1; i++)
			            {
				            expandedFileName += pathDirectories[i];
				            expandedFileName += "/";
			            }

			            expandedFileName += fileName;

			            MGlobal.sourceFile(expandedFileName);
		            }
	            }
            }	

            return;
        }
コード例 #18
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		//
		// Write out the 'addAttr' and 'setAttr' commands for a node.
		//
		protected void writeNodeAttrs(FileStream f, MObject node, bool isSelected)
		{
			MFnDependencyNode	nodeFn = new MFnDependencyNode(node);

			if (nodeFn.canBeWritten)
			{
				MStringArray	addAttrCmds = new MStringArray();
				MStringArray	setAttrCmds = new MStringArray();

				getAddAttrCmds(node, addAttrCmds);
				getSetAttrCmds(node, setAttrCmds);

				uint numAddAttrCmds = addAttrCmds.length;
				uint numSetAttrCmds = setAttrCmds.length;

				if (numAddAttrCmds + numSetAttrCmds > 0)
				{
					//
					// If the node is not already selected, then issue a command to
					// select it.
					//
					if (!isSelected) writeSelectNode(f, node);

					int i;
					string result = "";
					for (i = 0; i < numAddAttrCmds; i++)
						result += (addAttrCmds[i] + "\n");

					for (i = 0; i < numSetAttrCmds; i++)
						result += (setAttrCmds[i] + "\n");

					writeString(f, result);
				}
			}
		}
コード例 #19
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		//
		// Write out the "file" commands which specify the reference files used by
		// the scene.
		//
		protected void writeReferences(FileStream f)
		{
			MStringArray files = new MStringArray();

			MFileIO.getReferences(files);

			uint numRefs = files.length;
			int i;

			for (i = 0; i < numRefs; i++)
			{
				string	refCmd = "file -r";
				string	fileName = files[i];
				string	nsName = "";

				//
				// For simplicity, we assume that namespaces are always used when
				// referencing.
				//
				string tempCmd = "file -q -ns \"";
				tempCmd += fileName + "\"";

				try
				{
					MGlobal.executeCommand(tempCmd, out nsName);
					refCmd += " -ns \"";
					refCmd += nsName + "\"";
				}
				catch (Exception)
				{
					MGlobal.displayWarning("Could not get namespace name.");
				}
				//
				// Is this a deferred reference?
				//
				tempCmd = "file -q -dr \"";
				tempCmd += fileName + "\"";

				int	isDeferred;

				try
				{
					MGlobal.executeCommand(tempCmd, out isDeferred);
					if (Convert.ToBoolean(isDeferred)) refCmd += " -dr 1";
				}
				catch (Exception)
				{
					MGlobal.displayWarning("Could not get deferred reference info.");
				}
				//
				// Get the file's reference node, if it has one.
				//
				tempCmd = "file -q -rfn \"";
				tempCmd += fileName + "\"";

				string refNode;

				try
				{
					MGlobal.executeCommand(tempCmd, out refNode);
					if (refNode.Length > 0)
					{
						refCmd += " -rfn \"";
						refCmd += refNode + "\"";
					}
				}
				catch (Exception)
				{
					MGlobal.displayInfo("Could not query reference node name.");
				}
				//
				// Write out the reference command.
				//
				string result = "";
				result += (refCmd + "\"" + fileName + "\";");

				writeString(f, result);
			}
		}
コード例 #20
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		protected void getSetAttrCmds(MObject node, MStringArray cmds)
		{
			//
			// Get rid of any garbage already in the array.
			//
			cmds.clear();

			//
			// Run through the node's attributes.
			//
			MFnDependencyNode	nodeFn = new MFnDependencyNode(node);
			uint numAttrs = nodeFn.attributeCount;
			uint i;

			for (i = 0; i < numAttrs; i++)
			{
				//
				// Use the attribute ordering which Maya uses when doing I/O.
				//
				MObject			attr = nodeFn.reorderedAttribute(i);
				MFnAttribute	attrFn = new MFnAttribute(attr);
                bool            isChild;
				attrFn.parent(out isChild);
				
				//
				// We don't want attributes which are children of other attributes
				// because they will be processed when we process the parent.
				//
				// And we only want storable attributes which accept inputs.
				//
				if (!isChild && attrFn.isStorable && attrFn.isWritable)
				{
					//
					// Get a plug for the attribute.
					//
					MPlug	plug = new MPlug(node, attr);

					//
					// Get setAttr commands for this attribute, and any of its
					// children, which have had their values changed by the scene.
					//
					MStringArray	newCmds = new MStringArray();

					plug.getSetAttrCmds(newCmds, MPlug.MValueSelector.kChanged, false);

					uint numCommands = newCmds.length;
					int c;

					for (c = 0; c < numCommands; c++)
					{
						if (newCmds[c] != "")
							cmds.append(newCmds[c]);
					}
				}
			}
		}
コード例 #21
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		//
		// Maya calls this method to find out if this translator is capable of
		// handling the given file.
		//
		public override MPxFileTranslator.MFileKind identifyFile(MFileObject file, string buffer, short bufferLen)
		{
			string tagStr = comment(fTranslatorName);
			int	tagLen = tagStr.Length;

			//
			// If the buffer contains enough info to positively identify the file,
			// then use it.  Otherwise we'll base the identification on the file
			// extension.
			//
			if (bufferLen >= tagLen)
			{
				string initialContents = buffer.Substring(0,bufferLen);
				MStringArray initialLines = new MStringArray(initialContents.Split('\n'));

				//initialLines = initialContents.Split('\n');

				if (initialLines.length > 0)
				{
					if (((int)initialLines[0].Length >= tagLen)
					&&	(initialLines[0].Substring(0, tagLen-1) == tagStr))
					{
						return MPxFileTranslator.MFileKind.kIsMyFileType;
					}
				}
			}
			else
			{
				string fileName = file.name;
				int	fileNameLen = fileName.Length;
				int	startOfExtension = fileName.IndexOf('.') + 1;

				if ((startOfExtension > 0)
				&&	(startOfExtension < fileNameLen)
				&&	(fileName.Substring(startOfExtension, fileNameLen) == fExtension))
				{
					return MPxFileTranslator.MFileKind.kIsMyFileType;
				}
			}

			return MPxFileTranslator.MFileKind.kNotMyFileType;
		}
コード例 #22
0
 public override bool getSourceStreams(MObject objPath, MStringArray sourceStreams)
 {
     // No source stream needed
     return false;
 }
コード例 #23
0
        /// <summary>
        /// Get TRS and visiblity animations of the transform
        /// </summary>
        /// <param name="transform">Transform above mesh/camera/light</param>
        /// <returns></returns>
        private List <BabylonAnimation> GetAnimation(MFnTransform transform)
        {
            // Animations
            MPlugArray   connections  = new MPlugArray();
            MStringArray animCurvList = new MStringArray();
            MIntArray    keysTime     = new MIntArray();
            MDoubleArray keysValue    = new MDoubleArray();

            MFloatArray translateValues  = new MFloatArray();
            MFloatArray rotateValues     = new MFloatArray();
            MFloatArray scaleValues      = new MFloatArray();
            MFloatArray visibilityValues = new MFloatArray();
            MFloatArray keyTimes         = new MFloatArray();

            List <BabylonAnimationKey> keys             = new List <BabylonAnimationKey>();
            List <BabylonAnimation>    animationsObject = new List <BabylonAnimation>();

            //Get the animCurve
            MGlobal.executeCommand("listConnections -type \"animCurve\" " + transform.fullPathName + ";", animCurvList);

            List <AnimCurvData> animCurvesData = new List <AnimCurvData>();

            foreach (String animCurv in animCurvList)
            {
                AnimCurvData animCurvData = new AnimCurvData();
                animCurvesData.Add(animCurvData);

                animCurvData.animCurv = animCurv;

                //Get the key time for each curves
                MGlobal.executeCommand("keyframe -q " + animCurv + ";", keysTime);

                //Get the value for each curves
                MGlobal.executeCommand("keyframe - q -vc -absolute " + animCurv + ";", keysValue);

                if (animCurv.EndsWith("translateZ") || animCurv.EndsWith("rotateX") || animCurv.EndsWith("rotateY"))
                {
                    for (int index = 0; index < keysTime.Count; index++)
                    {
                        // Switch coordinate system at object level
                        animCurvData.valuePerFrame.Add(keysTime[index], (float)keysValue[index] * -1.0f);
                    }
                }
                else
                {
                    for (int index = 0; index < keysTime.Count; index++)
                    {
                        animCurvData.valuePerFrame.Add(keysTime[index], (float)keysValue[index]);
                    }
                }
            }

            string[] mayaAnimationProperties    = new string[] { "translate", "rotate", "scale" };
            string[] babylonAnimationProperties = new string[] { "position", "rotationQuaternion", "scaling" };
            string[] axis = new string[] { "X", "Y", "Z" };

            // Init TRS default values
            Dictionary <string, float> defaultValues = new Dictionary <string, float>();

            float[] position           = null;
            float[] rotationQuaternion = null;
            float[] rotation           = null;
            float[] scaling            = null;
            GetTransform(transform, ref position, ref rotationQuaternion, ref rotation, ref scaling); // coordinate system already switched
            defaultValues.Add("translateX", position[0]);
            defaultValues.Add("translateY", position[1]);
            defaultValues.Add("translateZ", position[2]);
            defaultValues.Add("rotateX", rotation[0]);
            defaultValues.Add("rotateY", rotation[1]);
            defaultValues.Add("rotateZ", rotation[2]);
            defaultValues.Add("scaleX", scaling[0]);
            defaultValues.Add("scaleY", scaling[1]);
            defaultValues.Add("scaleZ", scaling[2]);

            for (int indexAnimationProperty = 0; indexAnimationProperty < mayaAnimationProperties.Length; indexAnimationProperty++)
            {
                string mayaAnimationProperty = mayaAnimationProperties[indexAnimationProperty];

                // Retreive animation curves data for current animation property
                // Ex: all "translate" data are "translateX", "translateY", "translateZ"
                List <AnimCurvData> animDataProperty = animCurvesData.Where(data => data.animCurv.Contains(mayaAnimationProperty)).ToList();

                if (animDataProperty.Count == 0)
                {
                    // Property is not animated
                    continue;
                }

                // Get all frames for this property
                List <int> framesProperty = new List <int>();
                foreach (var animData in animDataProperty)
                {
                    framesProperty.AddRange(animData.valuePerFrame.Keys);
                }
                framesProperty = framesProperty.Distinct().ToList();
                framesProperty.Sort();

                // Get default values for this property
                BabylonAnimationKey lastBabylonAnimationKey = new BabylonAnimationKey();
                lastBabylonAnimationKey.frame  = 0;
                lastBabylonAnimationKey.values = new float[] { defaultValues[mayaAnimationProperty + "X"], defaultValues[mayaAnimationProperty + "Y"], defaultValues[mayaAnimationProperty + "Z"] };

                // Compute all values for this property
                List <BabylonAnimationKey> babylonAnimationKeys = new List <BabylonAnimationKey>();
                foreach (var frameProperty in framesProperty)
                {
                    BabylonAnimationKey babylonAnimationKey = new BabylonAnimationKey();
                    babylonAnimationKeys.Add(babylonAnimationKey);

                    // Frame
                    babylonAnimationKey.frame = frameProperty;

                    // Values
                    float[] valuesProperty = new float[3];
                    for (int indexAxis = 0; indexAxis < axis.Length; indexAxis++)
                    {
                        AnimCurvData animCurvDataAxis = animDataProperty.Find(data => data.animCurv.EndsWith(axis[indexAxis]));

                        float value;
                        if (animCurvDataAxis != null && animCurvDataAxis.valuePerFrame.ContainsKey(frameProperty))
                        {
                            value = animCurvDataAxis.valuePerFrame[frameProperty];
                        }
                        else
                        {
                            value = lastBabylonAnimationKey.values[indexAxis];
                        }
                        valuesProperty[indexAxis] = value;
                    }
                    babylonAnimationKey.values = valuesProperty.ToArray();

                    // Update last known values
                    lastBabylonAnimationKey = babylonAnimationKey;
                }

                // Convert euler to quaternion angles
                if (indexAnimationProperty == 1) // Rotation
                {
                    foreach (var babylonAnimationKey in babylonAnimationKeys)
                    {
                        BabylonVector3    eulerAngles      = BabylonVector3.FromArray(babylonAnimationKey.values);
                        BabylonQuaternion quaternionAngles = eulerAngles.toQuaternion();
                        babylonAnimationKey.values = quaternionAngles.ToArray();
                    }
                }

                var keysFull = new List <BabylonAnimationKey>(babylonAnimationKeys);

                // Optimization
                OptimizeAnimations(babylonAnimationKeys, true);

                // Ensure animation has at least 2 frames
                if (IsAnimationKeysRelevant(keys))
                {
                    // Create BabylonAnimation
                    string babylonAnimationProperty = babylonAnimationProperties[indexAnimationProperty];
                    animationsObject.Add(new BabylonAnimation()
                    {
                        dataType       = indexAnimationProperty == 1 ? (int)BabylonAnimation.DataType.Quaternion : (int)BabylonAnimation.DataType.Vector3,
                        name           = babylonAnimationProperty + " animation",
                        framePerSecond = 30,
                        loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                        property       = babylonAnimationProperty,
                        keys           = babylonAnimationKeys.ToArray(),
                        keysFull       = keysFull
                    });
                }
            }

            return(animationsObject);
        }
コード例 #24
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mDagPath">DAG path to the transform above mesh</param>
        /// <param name="babylonScene"></param>
        /// <returns></returns>
        private BabylonNode ExportMesh(MDagPath mDagPath, BabylonScene babylonScene)
        {
            RaiseMessage(mDagPath.partialPathName, 1);

            // Transform above mesh
            mFnTransform = new MFnTransform(mDagPath);

            // Mesh direct child of the transform
            // TODO get the original one rather than the modified?
            MFnMesh mFnMesh = null;

            for (uint i = 0; i < mFnTransform.childCount; i++)
            {
                MObject childObject = mFnTransform.child(i);
                if (childObject.apiType == MFn.Type.kMesh)
                {
                    var _mFnMesh = new MFnMesh(childObject);
                    if (!_mFnMesh.isIntermediateObject)
                    {
                        mFnMesh = _mFnMesh;
                    }
                }
            }
            if (mFnMesh == null)
            {
                RaiseError("No mesh found has child of " + mDagPath.fullPathName);
                return(null);
            }

            RaiseMessage("mFnMesh.fullPathName=" + mFnMesh.fullPathName, 2);

            // --- prints ---
            #region prints

            Action <MFnDagNode> printMFnDagNode = (MFnDagNode mFnDagNode) =>
            {
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.name=" + mFnDagNode.name, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.absoluteName=" + mFnDagNode.absoluteName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.fullPathName=" + mFnDagNode.fullPathName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.partialPathName=" + mFnDagNode.partialPathName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.activeColor=" + mFnDagNode.activeColor.toString(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.attributeCount=" + mFnDagNode.attributeCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.childCount=" + mFnDagNode.childCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.dormantColor=" + mFnDagNode.dormantColor, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.hasUniqueName=" + mFnDagNode.hasUniqueName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.inUnderWorld=" + mFnDagNode.inUnderWorld, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isDefaultNode=" + mFnDagNode.isDefaultNode, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanceable=" + mFnDagNode.isInstanceable, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced(true)=" + mFnDagNode.isInstanced(true), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced(false)=" + mFnDagNode.isInstanced(false), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced()=" + mFnDagNode.isInstanced(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.instanceCount(true)=" + mFnDagNode.instanceCount(true), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.instanceCount(false)=" + mFnDagNode.instanceCount(false), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isIntermediateObject=" + mFnDagNode.isIntermediateObject, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isShared=" + mFnDagNode.isShared, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.objectColor=" + mFnDagNode.objectColor, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.parentCount=" + mFnDagNode.parentCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.parentNamespace=" + mFnDagNode.parentNamespace, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.uuid().asString()=" + mFnDagNode.uuid().asString(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.dagRoot().apiType=" + mFnDagNode.dagRoot().apiType, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.model.equalEqual(mFnDagNode.objectProperty)=" + mFnDagNode.model.equalEqual(mFnDagNode.objectProperty), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.transformationMatrix.toString()=" + mFnDagNode.transformationMatrix.toString(), 3);
            };

            Action <MFnMesh> printMFnMesh = (MFnMesh _mFnMesh) =>
            {
                printMFnDagNode(mFnMesh);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numVertices=" + _mFnMesh.numVertices, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numEdges=" + _mFnMesh.numEdges, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numPolygons=" + _mFnMesh.numPolygons, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numFaceVertices=" + _mFnMesh.numFaceVertices, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numNormals=" + _mFnMesh.numNormals, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numUVSets=" + _mFnMesh.numUVSets, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numUVsProperty=" + _mFnMesh.numUVsProperty, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.displayColors=" + _mFnMesh.displayColors, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numColorSets=" + _mFnMesh.numColorSets, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numColorsProperty=" + _mFnMesh.numColorsProperty, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.currentUVSetName()=" + _mFnMesh.currentUVSetName(), 3);

                var _uvSetNames = new MStringArray();
                mFnMesh.getUVSetNames(_uvSetNames);
                foreach (var uvSetName in _uvSetNames)
                {
                    RaiseVerbose("BabylonExporter.Mesh | uvSetName=" + uvSetName, 3);
                    RaiseVerbose("BabylonExporter.Mesh | mFnMesh.numUVs(uvSetName)=" + mFnMesh.numUVs(uvSetName), 4);
                    MFloatArray us = new MFloatArray();
                    MFloatArray vs = new MFloatArray();
                    mFnMesh.getUVs(us, vs, uvSetName);
                    RaiseVerbose("BabylonExporter.Mesh | us.Count=" + us.Count, 4);
                }
            };

            Action <MFnTransform> printMFnTransform = (MFnTransform _mFnMesh) =>
            {
                printMFnDagNode(mFnMesh);
            };

            RaiseVerbose("BabylonExporter.Mesh | mFnMesh data", 2);
            printMFnMesh(mFnMesh);

            RaiseVerbose("BabylonExporter.Mesh | mFnTransform data", 2);
            printMFnTransform(mFnTransform);

            Print(mFnTransform, 2, "Print ExportMesh mFnTransform");

            Print(mFnMesh, 2, "Print ExportMesh mFnMesh");

            //// Geometry
            //MIntArray triangleCounts = new MIntArray();
            //MIntArray trianglesVertices = new MIntArray();
            //mFnMesh.getTriangles(triangleCounts, trianglesVertices);
            //RaiseVerbose("BabylonExporter.Mesh | triangleCounts.ToArray()=" + triangleCounts.ToArray().toString(), 3);
            //RaiseVerbose("BabylonExporter.Mesh | trianglesVertices.ToArray()=" + trianglesVertices.ToArray().toString(), 3);
            //int[] polygonsVertexCount = new int[mFnMesh.numPolygons];
            //for (int polygonId = 0; polygonId < mFnMesh.numPolygons; polygonId++)
            //{
            //    polygonsVertexCount[polygonId] = mFnMesh.polygonVertexCount(polygonId);
            //}
            //RaiseVerbose("BabylonExporter.Mesh | polygonsVertexCount=" + polygonsVertexCount.toString(), 3);

            ////MFloatPointArray points = new MFloatPointArray();
            ////mFnMesh.getPoints(points);
            ////RaiseVerbose("BabylonExporter.Mesh | points.ToArray()=" + points.ToArray().Select(mFloatPoint => mFloatPoint.toString()), 3);

            ////MFloatVectorArray normals = new MFloatVectorArray();
            ////mFnMesh.getNormals(normals);
            ////RaiseVerbose("BabylonExporter.Mesh | normals.ToArray()=" + normals.ToArray().Select(mFloatPoint => mFloatPoint.toString()), 3);

            //for (int polygonId = 0; polygonId < mFnMesh.numPolygons; polygonId++)
            //{
            //    MIntArray verticesId = new MIntArray();
            //    RaiseVerbose("BabylonExporter.Mesh | polygonId=" + polygonId, 3);

            //    int nbTriangles = triangleCounts[polygonId];
            //    RaiseVerbose("BabylonExporter.Mesh | nbTriangles=" + nbTriangles, 3);

            //    for (int triangleIndex = 0; triangleIndex < triangleCounts[polygonId]; triangleIndex++)
            //    {
            //        RaiseVerbose("BabylonExporter.Mesh | triangleIndex=" + triangleIndex, 3);
            //        int[] triangleVertices = new int[3];
            //        mFnMesh.getPolygonTriangleVertices(polygonId, triangleIndex, triangleVertices);
            //        RaiseVerbose("BabylonExporter.Mesh | triangleVertices=" + triangleVertices.toString(), 3);

            //        foreach (int vertexId in triangleVertices)
            //        {
            //            RaiseVerbose("BabylonExporter.Mesh | vertexId=" + vertexId, 3);
            //            MPoint point = new MPoint();
            //            mFnMesh.getPoint(vertexId, point);
            //            RaiseVerbose("BabylonExporter.Mesh | point=" + point.toString(), 3);

            //            MVector normal = new MVector();
            //            mFnMesh.getFaceVertexNormal(polygonId, vertexId, normal);
            //            RaiseVerbose("BabylonExporter.Mesh | normal=" + normal.toString(), 3);
            //        }
            //    }
            //}

            #endregion

            if (IsMeshExportable(mFnMesh, mDagPath) == false)
            {
                return(null);
            }

            var babylonMesh = new BabylonMesh {
                name       = mFnTransform.name,
                id         = mFnTransform.uuid().asString(),
                visibility = Loader.GetVisibility(mFnTransform.fullPathName)
            };

            // Instance
            // For a mesh with instances, we distinguish between master and instance meshes:
            //      - a master mesh stores all the info of the mesh (transform, hierarchy, animations + vertices, indices, materials, bones...)
            //      - an instance mesh only stores the info of the node (transform, hierarchy, animations)

            // Check if this mesh has already been exported as a master mesh
            BabylonMesh babylonMasterMesh = GetMasterMesh(mFnMesh, babylonMesh);
            if (babylonMasterMesh != null)
            {
                RaiseMessage($"The master mesh {babylonMasterMesh.name} was already exported. This one will be exported as an instance.", 2);

                // Export this node as instance
                var babylonInstanceMesh = new BabylonAbstractMesh {
                    name = mFnTransform.name, id = mFnTransform.uuid().asString()
                };

                //// Add instance to master mesh
                List <BabylonAbstractMesh> instances = babylonMasterMesh.instances != null?babylonMasterMesh.instances.ToList() : new List <BabylonAbstractMesh>();

                instances.Add(babylonInstanceMesh);
                babylonMasterMesh.instances = instances.ToArray();

                // Export transform / hierarchy / animations
                ExportNode(babylonInstanceMesh, mFnTransform, babylonScene);

                // Animations
                ExportNodeAnimation(babylonInstanceMesh, mFnTransform);

                return(babylonInstanceMesh);
            }

            // Position / rotation / scaling / hierarchy
            ExportNode(babylonMesh, mFnTransform, babylonScene);

            // Misc.
            // TODO - Retreive from Maya
            //babylonMesh.receiveShadows = meshNode.MaxNode.RcvShadows == 1;
            //babylonMesh.applyFog = meshNode.MaxNode.ApplyAtmospherics == 1;

            if (mFnMesh.numPolygons < 1)
            {
                RaiseError($"Mesh {babylonMesh.name} has no face", 2);
            }

            if (mFnMesh.numVertices < 3)
            {
                RaiseError($"Mesh {babylonMesh.name} has not enough vertices", 2);
            }

            if (mFnMesh.numVertices >= 65536)
            {
                RaiseWarning($"Mesh {babylonMesh.name} has more than 65536 vertices which means that it will require specific WebGL extension to be rendered. This may impact portability of your scene on low end devices.", 2);
            }

            // Animations
            ExportNodeAnimation(babylonMesh, mFnTransform);

            // Material
            MObjectArray shaders = new MObjectArray();
            mFnMesh.getConnectedShaders(0, shaders, new MIntArray());
            if (shaders.Count > 0)
            {
                List <MFnDependencyNode> materials = new List <MFnDependencyNode>();
                foreach (MObject shader in shaders)
                {
                    // Retreive material
                    MFnDependencyNode shadingEngine      = new MFnDependencyNode(shader);
                    MPlug             mPlugSurfaceShader = shadingEngine.findPlug("surfaceShader");
                    MObject           materialObject     = mPlugSurfaceShader.source.node;
                    MFnDependencyNode material           = new MFnDependencyNode(materialObject);

                    materials.Add(material);
                }

                if (shaders.Count == 1)
                {
                    MFnDependencyNode material = materials[0];

                    // Material is referenced by id
                    babylonMesh.materialId = material.uuid().asString();

                    // Register material for export if not already done
                    if (!referencedMaterials.Contains(material, new MFnDependencyNodeEqualityComparer()))
                    {
                        referencedMaterials.Add(material);
                    }
                }
                else
                {
                    // Create a new id for the group of sub materials
                    string uuidMultiMaterial = GetMultimaterialUUID(materials);

                    // Multi material is referenced by id
                    babylonMesh.materialId = uuidMultiMaterial;

                    // Register multi material for export if not already done
                    if (!multiMaterials.ContainsKey(uuidMultiMaterial))
                    {
                        multiMaterials.Add(uuidMultiMaterial, materials);
                    }
                }
            }

            var vertices = new List <GlobalVertex>();
            var indices  = new List <int>();

            var uvSetNames = new MStringArray();
            mFnMesh.getUVSetNames(uvSetNames);
            bool[] isUVExportSuccess = new bool[Math.Min(uvSetNames.Count, 2)];
            for (int indexUVSet = 0; indexUVSet < isUVExportSuccess.Length; indexUVSet++)
            {
                isUVExportSuccess[indexUVSet] = true;
            }

            // skin
            if (_exportSkin)
            {
                mFnSkinCluster = getMFnSkinCluster(mFnMesh);
            }
            int maxNbBones = 0;
            if (mFnSkinCluster != null)
            {
                RaiseMessage($"mFnSkinCluster.name | {mFnSkinCluster.name}", 2);
                Print(mFnSkinCluster, 3, $"Print {mFnSkinCluster.name}");

                // Get the bones dictionary<name, index> => it represents all the bones in the skeleton
                indexByNodeName = GetIndexByFullPathNameDictionary(mFnSkinCluster);

                // Get the joint names that influence this mesh
                allMayaInfluenceNames = GetBoneFullPathName(mFnSkinCluster, mFnTransform);

                // Get the max number of joints acting on a vertex
                int maxNumInfluences = GetMaxInfluence(mFnSkinCluster, mFnTransform, mFnMesh);

                RaiseMessage($"Max influences : {maxNumInfluences}", 2);
                if (maxNumInfluences > 8)
                {
                    RaiseWarning($"Too many bones influences per vertex: {maxNumInfluences}. Babylon.js only support up to 8 bones influences per vertex.", 2);
                    RaiseWarning("The result may not be as expected.", 2);
                }
                maxNbBones = Math.Min(maxNumInfluences, 8);

                if (indexByNodeName != null && allMayaInfluenceNames != null)
                {
                    babylonMesh.skeletonId = GetSkeletonIndex(mFnSkinCluster);
                }
                else
                {
                    mFnSkinCluster = null;
                }
            }
            // Export tangents if option is checked and mesh have tangents
            bool isTangentExportSuccess = _exportTangents;

            // TODO - color, alpha
            //var hasColor = unskinnedMesh.NumberOfColorVerts > 0;
            //var hasAlpha = unskinnedMesh.GetNumberOfMapVerts(-2) > 0;

            // TODO - Add custom properties
            //var optimizeVertices = false; // meshNode.MaxNode.GetBoolProperty("babylonjs_optimizevertices");
            var optimizeVertices = _optimizeVertices; // global option

            // Compute normals
            var subMeshes = new List <BabylonSubMesh>();
            ExtractGeometry(mFnMesh, vertices, indices, subMeshes, uvSetNames, ref isUVExportSuccess, ref isTangentExportSuccess, optimizeVertices);

            if (vertices.Count >= 65536)
            {
                RaiseWarning($"Mesh {babylonMesh.name} has {vertices.Count} vertices. This may prevent your scene to work on low end devices where 32 bits indice are not supported", 2);

                if (!optimizeVertices)
                {
                    RaiseError("You can try to optimize your object using [Try to optimize vertices] option", 2);
                }
            }

            for (int indexUVSet = 0; indexUVSet < isUVExportSuccess.Length; indexUVSet++)
            {
                string uvSetName = uvSetNames[indexUVSet];
                // If at least one vertex is mapped to an UV coordinate but some have failed to be exported
                if (isUVExportSuccess[indexUVSet] == false && mFnMesh.numUVs(uvSetName) > 0)
                {
                    RaiseWarning($"Failed to export UV set named {uvSetName}. Ensure all vertices are mapped to a UV coordinate.", 2);
                }
            }

            RaiseMessage($"{vertices.Count} vertices, {indices.Count / 3} faces", 2);

            // Buffers
            babylonMesh.positions = vertices.SelectMany(v => v.Position).ToArray();
            babylonMesh.normals   = vertices.SelectMany(v => v.Normal).ToArray();

            // export the skin
            if (mFnSkinCluster != null)
            {
                babylonMesh.matricesWeights = vertices.SelectMany(v => v.Weights.ToArray()).ToArray();
                babylonMesh.matricesIndices = vertices.Select(v => v.BonesIndices).ToArray();

                babylonMesh.numBoneInfluencers = maxNbBones;
                if (maxNbBones > 4)
                {
                    babylonMesh.matricesWeightsExtra = vertices.SelectMany(v => v.WeightsExtra != null ? v.WeightsExtra.ToArray() : new[] { 0.0f, 0.0f, 0.0f, 0.0f }).ToArray();
                    babylonMesh.matricesIndicesExtra = vertices.Select(v => v.BonesIndicesExtra).ToArray();
                }
            }

            // Tangent
            if (isTangentExportSuccess)
            {
                babylonMesh.tangents = vertices.SelectMany(v => v.Tangent).ToArray();
            }
            // Color
            string colorSetName;
            mFnMesh.getCurrentColorSetName(out colorSetName);
            if (mFnMesh.numColors(colorSetName) > 0)
            {
                babylonMesh.colors = vertices.SelectMany(v => v.Color).ToArray();
            }
            // UVs
            if (uvSetNames.Count > 0 && isUVExportSuccess[0])
            {
                babylonMesh.uvs = vertices.SelectMany(v => v.UV).ToArray();
            }
            if (uvSetNames.Count > 1 && isUVExportSuccess[1])
            {
                babylonMesh.uvs2 = vertices.SelectMany(v => v.UV2).ToArray();
            }

            babylonMesh.subMeshes = subMeshes.ToArray();

            // Buffers - Indices
            babylonMesh.indices = indices.ToArray();


            babylonScene.MeshesList.Add(babylonMesh);
            RaiseMessage("BabylonExporter.Mesh | done", 2);

            return(babylonMesh);
        }
コード例 #25
0
        /// <summary>
        /// Faces and vertices UVs, positions and normals.
        /// </summary>
        private static void ExtractMeshGeometry(MayaM2Mesh mesh, MDagPath meshPath, Dictionary <string, MayaM2Bone> jointMap, List <MayaM2Vertex> globalVertexList)
        {
            // ***Data Tables***
            // UV Sets
            var uvsets        = new MStringArray();
            var meshFunctions = new MFnMesh(meshPath);

            meshFunctions.getUVSetNames(uvsets);

            //Bone Weights
            var vertexWeights    = new List <MDoubleArray>();
            var influenceObjects = new MDagPathArray();

            GetMeshWeightData(vertexWeights, influenceObjects, meshPath);

            //Positions
            var positions = new MFloatPointArray();

            meshFunctions.getPoints(positions, MSpace.Space.kWorld);

            //Normals
            var normals = new MFloatVectorArray();

            meshFunctions.getVertexNormals(false, normals, MSpace.Space.kWorld);

            var polygonIter = new MItMeshPolygon(meshPath);

            while (!polygonIter.isDone)
            {
                //Divide face into triangles
                var polyMeshRelative = new MIntArray();
                polygonIter.getVertices(polyMeshRelative);
                int numTriangles;
                polygonIter.numTriangles(out numTriangles);
                for (var i = 0; i < numTriangles; i++)
                {
                    var triangle             = new MayaM2Triangle();
                    var triangleMeshRelative = new MIntArray();
                    polygonIter.getTriangle(i, new MPointArray(), triangleMeshRelative);
                    var triangleFaceRelative = GetLocalTriangle(polyMeshRelative, triangleMeshRelative);
                    for (var v = 0; v < 3; v++)
                    {
                        var meshIndex = triangleMeshRelative[v];
                        var faceIndex = triangleFaceRelative[v];

                        //Bone weights
                        var weights = new List <Tuple <MayaM2Bone, double> >();
                        for (var b = 0; b < influenceObjects.length; b++) //for each joint
                        {
                            var kJointPath = influenceObjects[b];
                            if (!kJointPath.hasFn(MFn.Type.kJoint))
                            {
                                continue;
                            }
                            Debug.Assert(b < vertexWeights[meshIndex].Count,
                                         "vertexWeights size : " + vertexWeights.Count + " " +
                                         "\njointWeights for this vertex : " + vertexWeights[meshIndex].Count);
                            //Here are a joint&weight for this vertex
                            if (vertexWeights[meshIndex][b] > Epsilon)
                            {
                                weights.Add(new Tuple <MayaM2Bone, double>(jointMap[kJointPath.fullPathName],
                                                                           vertexWeights[meshIndex][b]));
                            }
                        }

                        //Position & normals
                        var position = positions[(int)polygonIter.vertexIndex(faceIndex)];
                        var normal   = normals[(int)polygonIter.normalIndex(faceIndex)];

                        //UV coordinates
                        var uvCoordinates = new List <Tuple <float, float> >();
                        if (uvsets.length > 0 && meshFunctions.numUVs(uvsets[0]) > 0)
                        {
                            foreach (var uvset in uvsets)
                            {
                                var uvCoords = new float[2];
                                polygonIter.getUV(faceIndex, uvCoords, uvset);
                                uvCoordinates.Add(new Tuple <float, float>(uvCoords[0], uvCoords[1]));
                            }
                        }
                        var vert = VertexFactory.Create(position, normal, uvCoordinates, weights, globalVertexList);
                        triangle.Vertices.Add(vert);
                    }
                    mesh.Faces.Add(triangle);
                }
                polygonIter.next();
            }
        }
コード例 #26
0
        private static List <MayaM2Sequence> ExtractSequences()
        {
            // Sequences
            List <MayaM2Sequence> seqList = new List <MayaM2Sequence>();
            var editorNames = new MStringArray();

            MGlobal.executeCommand("ls -type m2Editor", editorNames);
            var editorName = editorNames[0];

            MGlobal.displayInfo("Searching editor node... Result : " + editorName);
            if (!string.IsNullOrEmpty(editorName))
            {
                MGlobal.displayInfo("Editor data found.");
                int numberOfClips;
                MGlobal.executeCommand("getAttr -size " + editorName + ".animClips", out numberOfClips);
                MGlobal.displayInfo("\tExtracting " + numberOfClips + " clips.");
                for (var i = 0; i < numberOfClips; i++)
                {
                    int    start;
                    int    end;
                    int    type;
                    bool   looping;
                    bool   lowPriority;
                    int    repMin;
                    int    repMax;
                    bool   blending;
                    int    blendTimeStart;
                    int    blendTimeEnd;
                    double rarity;
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipStart", out start);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipEnd", out end);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipType", out type);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipLooping", out looping);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipLowPriority", out lowPriority);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipRepMin", out repMin);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipRepMax", out repMax);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipBlending", out blending);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipBlendTimeStart", out blendTimeStart);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipBlendTimeEnd", out blendTimeEnd);
                    M2EditorNode.GetClipAttribute(editorName, i, "animClipRarity", out rarity);
                    var mayaSeq = new MayaM2Sequence
                    {
                        Start              = start,
                        End                = end,
                        Type               = type,
                        IsLoop             = looping,
                        IsLowPriority      = lowPriority,
                        MinimumRepetitions = repMin,
                        MaximumRepetitions = repMax,
                        IsBlending         = blending,
                        BlendTimeStart     = blendTimeStart,
                        BlendTimeEnd       = blendTimeEnd,
                        Probability        = (short)(rarity * short.MaxValue)
                    };
                    seqList.Add(mayaSeq);
                }
            }

            //Default when no animation clip, tries to get slider range.
            if (seqList.Count != 0)
            {
                var mayaSeq = new MayaM2Sequence
                {
                    Start = (int)MAnimControl.minTime.asUnits(MTime.Unit.kMilliseconds),
                    End   = (int)MAnimControl.maxTime.asUnits(MTime.Unit.kMilliseconds),
                };
                if (mayaSeq.Start != mayaSeq.End)
                {
                    mayaSeq.IsLoop = true;
                }
                seqList.Add(mayaSeq);
            }
            return(seqList);
        }
コード例 #27
0
        public static void draw(MDrawContext context, MUserData userData)
        {
            // This function is called by maya internal, .Net SDK has transfered MUserData to the derived one
            // Users don't need do the MUserData.getData(oldData) by themselves
            FootPrintData footData = MUserData.getData(userData) as FootPrintData;

            if (footData == null)
            {
                return;
            }

            MDAGDrawOverrideInfo objectOverrideInfo = footData.fDrawOV;

            if (objectOverrideInfo.fOverrideEnabled && !objectOverrideInfo.fEnableVisible)
            {
                return;
            }

            uint displayStyle = context.getDisplayStyle();

            bool drawAsBoundingBox = (displayStyle & (uint)MFrameContext.DisplayStyle.kBoundingBox) != 0 ||
                                     (footData.fDrawOV.fLOD == MDAGDrawOverrideInfo.DrawOverrideLOD.kLODBoundingBox);

            if (drawAsBoundingBox && !footData.fCustomBoxDraw)
            {
                return;
            }

            // get renderer
            Autodesk.Maya.OpenMayaRender.MHWRender.MRenderer theRenderer = Autodesk.Maya.OpenMayaRender.MHWRender.MRenderer.theRenderer();
            if (theRenderer == null)
            {
                return;
            }

            // get state data
            MMatrix transform =
                context.getMatrix(MDrawContext.MatrixType.kWorldViewMtx);

            MMatrix projection =
                context.getMatrix(MDrawContext.MatrixType.kProjectionMtx);

            // Check to see if we are drawing in a shadow pass.
            // If so then we keep the shading simple which in this
            // example means to disable any extra blending state changes
            //
            MPassContext passCtx        = context.passContext;
            MStringArray passSem        = passCtx.passSemantics;
            bool         castingShadows = false;

            for (int i = 0; i < passSem.length; i++)
            {
                if (passSem[i] == MPassContext.kShadowPassSemantic)
                {
                    castingShadows = true;
                }
            }
            bool debugPassInformation = false;

            if (debugPassInformation)
            {
                string passId = passCtx.passIdentifier;
                MGlobal.displayInfo("footprint node drawing in pass[" + passId + "], semantic[");
                for (int i = 0; i < passSem.length; i++)
                {
                    MGlobal.displayInfo(passSem[i]);
                }
                MGlobal.displayInfo("\n");
            }

            // get cached data
            float multiplier = footData.fMultiplier;

            float[] color = new float[4] {
                footData.fColor[0],
                footData.fColor[1],
                footData.fColor[2],
                1.0f
            };

            bool requireBlending = false;

            // If we're not casting shadows then do extra work
            // for display styles
            if (!castingShadows)
            {
                // Use some monotone version of color to show "default material mode"
                //
                if ((displayStyle & (uint)MFrameContext.DisplayStyle.kDefaultMaterial) != 0)
                {
                    color[0] = color[1] = color[2] = (color[0] + color[1] + color[2]) / 3.0f;
                }
                // Do some alpha blending if in x-ray mode
                //
                else if ((displayStyle & (uint)MFrameContext.DisplayStyle.kXray) != 0)
                {
                    requireBlending = true;
                    color[3]        = 0.3f;
                }
            }

            // Set blend and raster state
            //
            MStateManager    stateMgr            = context.stateManager;
            MBlendState      pOldBlendState      = null;
            MRasterizerState pOldRasterState     = null;
            bool             rasterStateModified = false;

            if ((stateMgr != null) && ((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0))
            {
                // draw filled, and with blending if required
                if (requireBlending)
                {
                    if (blendState == null)
                    {
                        MBlendStateDesc desc = new MBlendStateDesc();
                        desc.targetBlends.blendEnable           = true;
                        desc.targetBlends.destinationBlend      = MBlendState.BlendOption.kInvSourceAlpha;
                        desc.targetBlends.alphaDestinationBlend = MBlendState.BlendOption.kInvSourceAlpha;
                        blendState = MStateManager.acquireBlendState(desc);
                    }

                    if (blendState != null)
                    {
                        pOldBlendState      = stateMgr.blendState;
                        stateMgr.blendState = blendState;
                    }
                }

                // Override culling mode since we always want double-sided
                //
                pOldRasterState = (stateMgr != null) ? stateMgr.rasterizerState : null;
                if (pOldRasterState != null)
                {
                    MRasterizerStateDesc desc = new MRasterizerStateDesc(pOldRasterState.desc);
                    // It's also possible to change this to kCullFront or kCullBack if we
                    // wanted to set it to that.
                    MRasterizerState.CullMode cullMode = MRasterizerState.CullMode.kCullNone;
                    if (desc.cullMode != cullMode)
                    {
                        if (rasterState != null)
                        {
                            // Just override the cullmode
                            desc.cullMode = cullMode;
                            rasterState   = MStateManager.acquireRasterizerState(desc);
                        }
                        if (rasterState == null)
                        {
                            rasterStateModified      = true;
                            stateMgr.rasterizerState = rasterState;
                        }
                    }
                }
            }

            //========================
            // Start the draw work
            //========================

            // Prepare draw agent, default using OpenGL
            FootPrintDrawAgentGL drawAgentRef = FootPrintDrawAgentGL.getDrawAgent();
            FootPrintDrawAgent   drawAgentPtr = drawAgentRef;

            if (drawAgentPtr != null)
            {
                // Set color
                drawAgentPtr.setColor(new MColor(color[0], color[1], color[2], color[3]));
                // Set matrix
                drawAgentPtr.setMatrix(transform, projection);

                drawAgentPtr.beginDraw();

                if (drawAsBoundingBox)
                {
                    // If it is in bounding bode, draw only bounding box wireframe, nothing else
                    MPoint min = footData.fCurrentBoundingBox.min;
                    MPoint max = footData.fCurrentBoundingBox.max;

                    drawAgentPtr.drawBoundingBox(min, max);
                }
                else
                {
                    // Templated, only draw wirefame and it is not selectale
                    bool overideTemplated = objectOverrideInfo.fOverrideEnabled &&
                                            (objectOverrideInfo.fDisplayType == MDAGDrawOverrideInfo.DrawOverrideDisplayType.kDisplayTypeTemplate);
                    // Override no shaded, only show wireframe
                    bool overrideNoShaded = objectOverrideInfo.fOverrideEnabled && !objectOverrideInfo.fEnableShading;

                    if (overideTemplated || overrideNoShaded)
                    {
                        drawAgentPtr.drawWireframe(multiplier);
                    }
                    else
                    {
                        if (((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0) ||
                            ((displayStyle & (uint)MFrameContext.DisplayStyle.kTextured)) != 0)
                        {
                            drawAgentPtr.drawShaded(multiplier);
                        }

                        if ((displayStyle & (uint)MFrameContext.DisplayStyle.kWireFrame) != 0)
                        {
                            drawAgentPtr.drawWireframe(multiplier);
                        }
                    }
                }

                drawAgentPtr.endDraw();
            }

            //========================
            // End the draw work
            //========================

            // Restore old blend state and old raster state
            if ((stateMgr != null) && ((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0))
            {
                if ((stateMgr != null) && (pOldBlendState != null))
                {
                    stateMgr.setBlendState(pOldBlendState);
                }
                if (rasterStateModified && (pOldBlendState != null))
                {
                    stateMgr.setRasterizerState(pOldRasterState);
                }
            }
        }
コード例 #28
0
        /// <summary>
        /// Extract geometry (position, normal, UVs...) for a specific vertex
        /// </summary>
        /// <param name="mFnMesh"></param>
        /// <param name="polygonId">The polygon (face) to examine</param>
        /// <param name="vertexIndexGlobal">The object-relative (mesh-relative/global) vertex index</param>
        /// <param name="vertexIndexLocal">The face-relative (local) vertex id to examine</param>
        /// <param name="uvSetNames"></param>
        /// <param name="isUVExportSuccess"></param>
        /// <returns></returns>
        private GlobalVertex ExtractVertex(MFnMesh mFnMesh, int polygonId, int vertexIndexGlobal, int vertexIndexLocal, MStringArray uvSetNames, ref bool[] isUVExportSuccess)
        {
            MPoint point = new MPoint();

            mFnMesh.getPoint(vertexIndexGlobal, point);

            MVector normal = new MVector();

            mFnMesh.getFaceVertexNormal(polygonId, vertexIndexGlobal, normal);

            MVector tangent = new MVector();

            mFnMesh.getFaceVertexTangent(polygonId, vertexIndexGlobal, tangent);

            // Switch coordinate system at object level
            point.z   *= -1;
            normal.z  *= -1;
            tangent.z *= -1;

            float[] tangentVec4 = new float[] { (float)tangent.x, (float)tangent.y, (float)tangent.z, -1 };

            var vertex = new GlobalVertex
            {
                BaseIndex = vertexIndexGlobal,
                Position  = point.toArray(),
                Normal    = normal.toArray(),
                Tangent   = tangentVec4,
            };

            // Color
            int    colorIndex;
            string colorSetName;

            float[] defaultColor = new float[] { 1, 1, 1, 0 };
            MColor  color        = new MColor();

            mFnMesh.getCurrentColorSetName(out colorSetName);

            if (mFnMesh.numColors(colorSetName) > 0)
            {
                //Get the color index
                mFnMesh.getColorIndex(polygonId, vertexIndexLocal, out colorIndex);

                //if a color is set
                if (colorIndex != -1)
                {
                    mFnMesh.getColor(colorIndex, color);
                    vertex.Color = color.toArray();
                }
                //else set the default color
                else
                {
                    vertex.Color = defaultColor;
                }
            }

            // UV
            int indexUVSet = 0;

            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV = new float[] { u, v };
                }
                catch (Exception e)
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }
            indexUVSet = 1;
            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV2 = new float[] { u, v };
                }
                catch (Exception e)
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }

            return(vertex);
        }
コード例 #29
0
 public override bool getAvailableImages( ShaderContext context, string uvSetName, MStringArray imageNames)
 {
     MGlobal.displayInfo("testHLSLShader::getAvailableImages");
     return base.getAvailableImages(context, uvSetName, imageNames);
 }
コード例 #30
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mDagPath">DAG path to the transform above light</param>
        /// <param name="babylonScene"></param>
        /// <returns></returns>
        private BabylonNode ExportLight(MDagPath mDagPath, BabylonScene babylonScene)
        {
            RaiseMessage(mDagPath.partialPathName, 1);

            // Transform above light
            MFnTransform mFnTransform = new MFnTransform(mDagPath);

            // Light direct child of the transform
            MFnLight mFnLight = null;

            for (uint i = 0; i < mFnTransform.childCount; i++)
            {
                MObject childObject = mFnTransform.child(i);
                if (childObject.hasFn(MFn.Type.kLight))
                {
                    var _mFnLight = new MFnLight(childObject);
                    if (!_mFnLight.isIntermediateObject)
                    {
                        mFnLight = _mFnLight;
                    }
                }
            }
            if (mFnLight == null)
            {
                RaiseError("No light found has child of " + mDagPath.fullPathName);
                return(null);
            }

            RaiseMessage("mFnLight.fullPathName=" + mFnLight.fullPathName, 2);

            // --- prints ---
            #region prints

            // MFnLight
            RaiseVerbose("BabylonExporter.Light | mFnLight data", 2);
            RaiseVerbose("BabylonExporter.Light | mFnLight.color.toString()=" + mFnLight.color.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.intensity=" + mFnLight.intensity, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.useRayTraceShadows=" + mFnLight.useRayTraceShadows, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.shadowColor.toString()=" + mFnLight.shadowColor.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.centerOfIllumination=" + mFnLight.centerOfIllumination, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.numShadowSamples=" + mFnLight.numShadowSamples, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.rayDepthLimit=" + mFnLight.rayDepthLimit, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.opticalFXvisibility.toString()=" + mFnLight.opticalFXvisibility.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightIntensity.toString()=" + mFnLight.lightIntensity.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.instanceCount(true)=" + mFnLight.instanceCount(true), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDirection(0).toString()=" + mFnLight.lightDirection(0).toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightAmbient=" + mFnLight.lightAmbient, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDiffuse=" + mFnLight.lightDiffuse, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightSpecular=" + mFnLight.lightSpecular, 3);

            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                // MFnNonAmbientLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.decayRate=" + mFnSpotLight.decayRate, 3);     // dropdown enum value
                // MFnNonExtendedLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.shadowRadius=" + mFnSpotLight.shadowRadius, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.castSoftShadows=" + mFnSpotLight.castSoftShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDepthMapShadows=" + mFnSpotLight.useDepthMapShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapFilterSize()=" + mFnSpotLight.depthMapFilterSize(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapResolution()=" + mFnSpotLight.depthMapResolution(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapBias()=" + mFnSpotLight.depthMapBias(), 3);
                // MFnSpotLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.coneAngle=" + mFnSpotLight.coneAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.penumbraAngle=" + mFnSpotLight.penumbraAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.dropOff=" + mFnSpotLight.dropOff, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.barnDoors=" + mFnSpotLight.barnDoors, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDecayRegions=" + mFnSpotLight.useDecayRegions, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                break;
            }

            Print(mFnTransform, 2, "Print ExportLight mFnTransform");

            Print(mFnLight, 2, "Print ExportLight mFnLight");

            #endregion

            if (IsLightExportable(mFnLight, mDagPath) == false)
            {
                return(null);
            }

            var babylonLight = new BabylonLight {
                name = mFnTransform.name, id = mFnTransform.uuid().asString()
            };

            // Hierarchy
            ExportHierarchy(babylonLight, mFnTransform);

            // User custom attributes
            babylonLight.metadata = ExportCustomAttributeFromTransform(mFnTransform);

            // Position
            //RaiseVerbose("BabylonExporter.Light | ExportTransform", 2);
            float[] position = null;
            GetTransform(mFnTransform, ref position);
            babylonLight.position = position;

            // Direction
            var vDir = new MVector(0, 0, -1);
            var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
            vDir = vDir.multiply(transformationMatrix.asMatrixProperty);
            vDir.normalize();
            babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z };

            // Common fields
            babylonLight.intensity = mFnLight.intensity;
            babylonLight.diffuse   = mFnLight.lightDiffuse ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };
            babylonLight.specular  = mFnLight.lightSpecular ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };

            // Type
            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kPointLight:
                babylonLight.type = 0;
                break;

            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                babylonLight.type     = 2;
                babylonLight.angle    = (float)mFnSpotLight.coneAngle;
                babylonLight.exponent = 1;

                if (mFnSpotLight.useDecayRegions)
                {
                    babylonLight.range = mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird);     // Max distance
                }
                break;

            case MFn.Type.kDirectionalLight:
                babylonLight.type = 1;
                break;

            case MFn.Type.kAmbientLight:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };

                // No emit diffuse /specular checkbox for ambient light
                babylonLight.diffuse  = mFnLight.color.toArrayRGB();
                babylonLight.specular = babylonLight.diffuse;

                // Direction
                vDir = new MVector(0, 1, 0);
                transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
                vDir = vDir.multiply(transformationMatrix.asMatrixProperty);
                vDir.normalize();
                babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z };
                break;

            case MFn.Type.kAreaLight:
            case MFn.Type.kVolumeLight:
                RaiseError("Unsupported light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored. Supported light types are: ambient, directional, point and spot.", 1);
                return(null);

            default:
                RaiseWarning("Unknown light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored.", 1);
                return(null);
            }

            // TODO - Shadows

            //Variable declaration
            MStringArray  enlightedMeshesFullPathNames = new MStringArray();
            List <string> includeMeshesIds             = new List <string>();
            MStringArray  kTransMesh = new MStringArray();
            String        typeMesh   = null;
            MStringArray  UUIDMesh   = new MStringArray();

            //MEL Command that get the enlighted mesh for a given light
            MGlobal.executeCommand($@"lightlink -query -light {mFnTransform.fullPathName};", enlightedMeshesFullPathNames);

            //For each enlighted mesh
            foreach (String Mesh in enlightedMeshesFullPathNames)
            {
                //MEL Command use to get the type of each mesh
                typeMesh = MGlobal.executeCommandStringResult($@"nodeType -api {Mesh};");

                //We are targeting the type kMesh and not kTransform (for parenting)
                if (typeMesh == "kMesh")
                {
                    MGlobal.executeCommand($@"listRelatives -parent -fullPath {Mesh};", kTransMesh);

                    //And finally the MEL Command for the uuid of each mesh
                    MGlobal.executeCommand($@"ls -uuid {kTransMesh[0]};", UUIDMesh);
                    includeMeshesIds.Add(UUIDMesh[0]);
                }
            }

            babylonLight.includedOnlyMeshesIds = includeMeshesIds.ToArray();

            // Animations
            if (exportParameters.bakeAnimationFrames)
            {
                ExportNodeAnimationFrameByFrame(babylonLight, mFnTransform);
            }
            else
            {
                ExportNodeAnimation(babylonLight, mFnTransform);
            }

            babylonScene.LightsList.Add(babylonLight);

            return(babylonLight);
        }
コード例 #31
0
        private void parseArgs(MArgList args)
        {
            const string kMessageFlag = "m";

            MArgDatabase argData = new MArgDatabase(syntax, args);

            if (argData.isFlagSet(kMessageFlag))
            {
                bool flag = false;

                try
                {
                    flag = argData.flagArgumentBool(kMessageFlag, 0);
                }
                catch (Exception)
                {
                    throw new ArgumentException("could not parse message flag", "args");
                }

                if (flag)
                {
                    addMessage = true;
                }
                else
                {
                    delMessage = true;
                }
            }

            try
            {
                argData.getObjects(conditions);
            }
            catch(Exception)
            {
                displayError("could not parse condition names");
            }

            // If there are no conditions specified, operate on all of them
            //
            if (conditions.length == 0)
            {
                // conditionNames is set in initializePlugin to all the
                // currently available condition names.
                //
                conditions = conditionNames;
            }
        }
コード例 #32
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mDagPath">DAG path to the transform above mesh</param>
        /// <param name="babylonScene"></param>
        /// <returns></returns>
        private BabylonNode ExportMesh(MDagPath mDagPath, BabylonScene babylonScene)
        {
            RaiseMessage(mDagPath.partialPathName, 1);

            // Transform above mesh
            MFnTransform mFnTransform = new MFnTransform(mDagPath);

            // Mesh direct child of the transform
            MFnMesh mFnMesh = null;

            for (uint i = 0; i < mFnTransform.childCount; i++)
            {
                MObject childObject = mFnTransform.child(i);
                if (childObject.apiType == MFn.Type.kMesh)
                {
                    var _mFnMesh = new MFnMesh(childObject);
                    if (!_mFnMesh.isIntermediateObject)
                    {
                        mFnMesh = _mFnMesh;
                    }
                }
            }
            if (mFnMesh == null)
            {
                RaiseError("No mesh found has child of " + mDagPath.fullPathName);
                return(null);
            }

            RaiseMessage("mFnMesh.fullPathName=" + mFnMesh.fullPathName, 2);

            // --- prints ---
            #region prints

            Action <MFnDagNode> printMFnDagNode = (MFnDagNode mFnDagNode) =>
            {
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.name=" + mFnDagNode.name, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.absoluteName=" + mFnDagNode.absoluteName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.fullPathName=" + mFnDagNode.fullPathName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.partialPathName=" + mFnDagNode.partialPathName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.activeColor=" + mFnDagNode.activeColor.toString(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.attributeCount=" + mFnDagNode.attributeCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.childCount=" + mFnDagNode.childCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.dormantColor=" + mFnDagNode.dormantColor, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.hasUniqueName=" + mFnDagNode.hasUniqueName, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.inUnderWorld=" + mFnDagNode.inUnderWorld, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isDefaultNode=" + mFnDagNode.isDefaultNode, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanceable=" + mFnDagNode.isInstanceable, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced(true)=" + mFnDagNode.isInstanced(true), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced(false)=" + mFnDagNode.isInstanced(false), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isInstanced()=" + mFnDagNode.isInstanced(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.instanceCount(true)=" + mFnDagNode.instanceCount(true), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.instanceCount(false)=" + mFnDagNode.instanceCount(false), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isIntermediateObject=" + mFnDagNode.isIntermediateObject, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.isShared=" + mFnDagNode.isShared, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.objectColor=" + mFnDagNode.objectColor, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.parentCount=" + mFnDagNode.parentCount, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.parentNamespace=" + mFnDagNode.parentNamespace, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.uuid().asString()=" + mFnDagNode.uuid().asString(), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.dagRoot().apiType=" + mFnDagNode.dagRoot().apiType, 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.model.equalEqual(mFnDagNode.objectProperty)=" + mFnDagNode.model.equalEqual(mFnDagNode.objectProperty), 3);
                RaiseVerbose("BabylonExporter.Mesh | mFnDagNode.transformationMatrix.toString()=" + mFnDagNode.transformationMatrix.toString(), 3);
            };

            Action <MFnMesh> printMFnMesh = (MFnMesh _mFnMesh) =>
            {
                printMFnDagNode(mFnMesh);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numVertices=" + _mFnMesh.numVertices, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numEdges=" + _mFnMesh.numEdges, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numPolygons=" + _mFnMesh.numPolygons, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numFaceVertices=" + _mFnMesh.numFaceVertices, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numNormals=" + _mFnMesh.numNormals, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numUVSets=" + _mFnMesh.numUVSets, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numUVsProperty=" + _mFnMesh.numUVsProperty, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.displayColors=" + _mFnMesh.displayColors, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numColorSets=" + _mFnMesh.numColorSets, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.numColorsProperty=" + _mFnMesh.numColorsProperty, 3);
                RaiseVerbose("BabylonExporter.Mesh | _mFnMesh.currentUVSetName()=" + _mFnMesh.currentUVSetName(), 3);

                var _uvSetNames = new MStringArray();
                mFnMesh.getUVSetNames(_uvSetNames);
                foreach (var uvSetName in _uvSetNames)
                {
                    RaiseVerbose("BabylonExporter.Mesh | uvSetName=" + uvSetName, 3);
                    RaiseVerbose("BabylonExporter.Mesh | mFnMesh.numUVs(uvSetName)=" + mFnMesh.numUVs(uvSetName), 4);
                    MFloatArray us = new MFloatArray();
                    MFloatArray vs = new MFloatArray();
                    mFnMesh.getUVs(us, vs, uvSetName);
                    RaiseVerbose("BabylonExporter.Mesh | us.Count=" + us.Count, 4);
                }
            };

            Action <MFnTransform> printMFnTransform = (MFnTransform _mFnMesh) =>
            {
                printMFnDagNode(mFnMesh);
            };

            RaiseVerbose("BabylonExporter.Mesh | mFnMesh data", 2);
            printMFnMesh(mFnMesh);

            RaiseVerbose("BabylonExporter.Mesh | mFnTransform data", 2);
            printMFnTransform(mFnTransform);

            Print(mFnTransform, 2, "Print ExportMesh mFnTransform");

            Print(mFnMesh, 2, "Print ExportMesh mFnMesh");

            //// Geometry
            //MIntArray triangleCounts = new MIntArray();
            //MIntArray trianglesVertices = new MIntArray();
            //mFnMesh.getTriangles(triangleCounts, trianglesVertices);
            //RaiseVerbose("BabylonExporter.Mesh | triangleCounts.ToArray()=" + triangleCounts.ToArray().toString(), 3);
            //RaiseVerbose("BabylonExporter.Mesh | trianglesVertices.ToArray()=" + trianglesVertices.ToArray().toString(), 3);
            //int[] polygonsVertexCount = new int[mFnMesh.numPolygons];
            //for (int polygonId = 0; polygonId < mFnMesh.numPolygons; polygonId++)
            //{
            //    polygonsVertexCount[polygonId] = mFnMesh.polygonVertexCount(polygonId);
            //}
            //RaiseVerbose("BabylonExporter.Mesh | polygonsVertexCount=" + polygonsVertexCount.toString(), 3);

            ////MFloatPointArray points = new MFloatPointArray();
            ////mFnMesh.getPoints(points);
            ////RaiseVerbose("BabylonExporter.Mesh | points.ToArray()=" + points.ToArray().Select(mFloatPoint => mFloatPoint.toString()), 3);

            ////MFloatVectorArray normals = new MFloatVectorArray();
            ////mFnMesh.getNormals(normals);
            ////RaiseVerbose("BabylonExporter.Mesh | normals.ToArray()=" + normals.ToArray().Select(mFloatPoint => mFloatPoint.toString()), 3);

            //for (int polygonId = 0; polygonId < mFnMesh.numPolygons; polygonId++)
            //{
            //    MIntArray verticesId = new MIntArray();
            //    RaiseVerbose("BabylonExporter.Mesh | polygonId=" + polygonId, 3);

            //    int nbTriangles = triangleCounts[polygonId];
            //    RaiseVerbose("BabylonExporter.Mesh | nbTriangles=" + nbTriangles, 3);

            //    for (int triangleIndex = 0; triangleIndex < triangleCounts[polygonId]; triangleIndex++)
            //    {
            //        RaiseVerbose("BabylonExporter.Mesh | triangleIndex=" + triangleIndex, 3);
            //        int[] triangleVertices = new int[3];
            //        mFnMesh.getPolygonTriangleVertices(polygonId, triangleIndex, triangleVertices);
            //        RaiseVerbose("BabylonExporter.Mesh | triangleVertices=" + triangleVertices.toString(), 3);

            //        foreach (int vertexId in triangleVertices)
            //        {
            //            RaiseVerbose("BabylonExporter.Mesh | vertexId=" + vertexId, 3);
            //            MPoint point = new MPoint();
            //            mFnMesh.getPoint(vertexId, point);
            //            RaiseVerbose("BabylonExporter.Mesh | point=" + point.toString(), 3);

            //            MVector normal = new MVector();
            //            mFnMesh.getFaceVertexNormal(polygonId, vertexId, normal);
            //            RaiseVerbose("BabylonExporter.Mesh | normal=" + normal.toString(), 3);
            //        }
            //    }
            //}

            #endregion


            if (IsMeshExportable(mFnMesh, mDagPath) == false)
            {
                return(null);
            }

            var babylonMesh = new BabylonMesh {
                name = mFnTransform.name, id = mFnTransform.uuid().asString()
            };

            // Position / rotation / scaling / hierarchy
            ExportNode(babylonMesh, mFnTransform, babylonScene);

            // Misc.
            // TODO - Retreive from Maya
            // TODO - What is the difference between isVisible and visibility?
            // TODO - Fix fatal error: Attempting to save in C:/Users/Fabrice/AppData/Local/Temp/Fabrice.20171205.1613.ma
            //babylonMesh.isVisible = mDagPath.isVisible;
            //babylonMesh.visibility = meshNode.MaxNode.GetVisibility(0, Tools.Forever);
            //babylonMesh.receiveShadows = meshNode.MaxNode.RcvShadows == 1;
            //babylonMesh.applyFog = meshNode.MaxNode.ApplyAtmospherics == 1;

            if (mFnMesh.numPolygons < 1)
            {
                RaiseError($"Mesh {babylonMesh.name} has no face", 2);
            }

            if (mFnMesh.numVertices < 3)
            {
                RaiseError($"Mesh {babylonMesh.name} has not enough vertices", 2);
            }

            if (mFnMesh.numVertices >= 65536)
            {
                RaiseWarning($"Mesh {babylonMesh.name} has more than 65536 vertices which means that it will require specific WebGL extension to be rendered. This may impact portability of your scene on low end devices.", 2);
            }

            // Material
            MObjectArray shaders = new MObjectArray();
            mFnMesh.getConnectedShaders(0, shaders, new MIntArray());
            if (shaders.Count > 0)
            {
                List <MFnDependencyNode> materials = new List <MFnDependencyNode>();
                foreach (MObject shader in shaders)
                {
                    // Retreive material
                    MFnDependencyNode shadingEngine      = new MFnDependencyNode(shader);
                    MPlug             mPlugSurfaceShader = shadingEngine.findPlug("surfaceShader");
                    MObject           materialObject     = mPlugSurfaceShader.source.node;
                    MFnDependencyNode material           = new MFnDependencyNode(materialObject);

                    materials.Add(material);
                }

                if (shaders.Count == 1)
                {
                    MFnDependencyNode material = materials[0];

                    // Material is referenced by id
                    babylonMesh.materialId = material.uuid().asString();

                    // Register material for export if not already done
                    if (!referencedMaterials.Contains(material, new MFnDependencyNodeEqualityComparer()))
                    {
                        referencedMaterials.Add(material);
                    }
                }
                else
                {
                    // Create a new id for the group of sub materials
                    string uuidMultiMaterial = GetMultimaterialUUID(materials);

                    // Multi material is referenced by id
                    babylonMesh.materialId = uuidMultiMaterial;

                    // Register multi material for export if not already done
                    if (!multiMaterials.ContainsKey(uuidMultiMaterial))
                    {
                        multiMaterials.Add(uuidMultiMaterial, materials);
                    }
                }
            }

            var vertices = new List <GlobalVertex>();
            var indices  = new List <int>();

            var uvSetNames = new MStringArray();
            mFnMesh.getUVSetNames(uvSetNames);
            bool[] isUVExportSuccess = new bool[Math.Min(uvSetNames.Count, 2)];
            for (int indexUVSet = 0; indexUVSet < isUVExportSuccess.Length; indexUVSet++)
            {
                isUVExportSuccess[indexUVSet] = true;
            }

            // TODO - color, alpha
            //var hasColor = unskinnedMesh.NumberOfColorVerts > 0;
            //var hasAlpha = unskinnedMesh.GetNumberOfMapVerts(-2) > 0;

            // TODO - Add custom properties
            var optimizeVertices = false; // meshNode.MaxNode.GetBoolProperty("babylonjs_optimizevertices");

            // Compute normals
            var subMeshes = new List <BabylonSubMesh>();
            ExtractGeometry(mFnMesh, vertices, indices, subMeshes, uvSetNames, ref isUVExportSuccess, optimizeVertices);

            if (vertices.Count >= 65536)
            {
                RaiseWarning($"Mesh {babylonMesh.name} has {vertices.Count} vertices. This may prevent your scene to work on low end devices where 32 bits indice are not supported", 2);

                if (!optimizeVertices)
                {
                    RaiseError("You can try to optimize your object using [Try to optimize vertices] option", 2);
                }
            }

            for (int indexUVSet = 0; indexUVSet < isUVExportSuccess.Length; indexUVSet++)
            {
                string uvSetName = uvSetNames[indexUVSet];
                // If at least one vertex is mapped to an UV coordinate but some have failed to be exported
                if (isUVExportSuccess[indexUVSet] == false && mFnMesh.numUVs(uvSetName) > 0)
                {
                    RaiseWarning($"Failed to export UV set named {uvSetName}. Ensure all vertices are mapped to a UV coordinate.", 2);
                }
            }

            RaiseMessage($"{vertices.Count} vertices, {indices.Count / 3} faces", 2);

            // Buffers
            babylonMesh.positions = vertices.SelectMany(v => v.Position).ToArray();
            babylonMesh.normals   = vertices.SelectMany(v => v.Normal).ToArray();
            // TODO - Export colors ?
            //babylonMesh.colors = vertices.SelectMany(v => v.Color).ToArray();

            if (uvSetNames.Count > 0 && isUVExportSuccess[0])
            {
                babylonMesh.uvs = vertices.SelectMany(v => v.UV).ToArray();
            }
            if (uvSetNames.Count > 1 && isUVExportSuccess[1])
            {
                babylonMesh.uvs2 = vertices.SelectMany(v => v.UV2).ToArray();
            }

            babylonMesh.subMeshes = subMeshes.ToArray();

            // Buffers - Indices
            babylonMesh.indices = indices.ToArray();


            babylonScene.MeshesList.Add(babylonMesh);
            RaiseMessage("BabylonExporter.Mesh | done", 2);

            return(babylonMesh);
        }
コード例 #33
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		protected void getAddAttrCmds(MObject node, MStringArray cmds)
		{
			//
			// Run through the node's attributes.
			//
			MFnDependencyNode	nodeFn = new MFnDependencyNode(node);
			uint numAttrs = nodeFn.attributeCount;
			uint i;

			for (i = 0; i < numAttrs; i++)
			{
				//
				// Use the attribute ordering which Maya uses when doing I/O.
				//
				MObject	attr = nodeFn.reorderedAttribute(i);

				//
				// If this attribute has been added since the node was created,
				// then we may want to write out an addAttr statement for it.
				//
				if (nodeFn.isNewAttribute(attr))
				{
					MFnAttribute	attrFn = new MFnAttribute(attr);

					//
					// If the attribute has a parent then ignore it because it will
					// be processed when we process the parent.
					//
                    bool bFound;
					attrFn.parent(out bFound);
					if ( !bFound )
					{
							//
						// If the attribute is a compound, then we can do its entire
						// tree at once.
						//
						try
						{
							MFnCompoundAttribute	cAttrFn = new MFnCompoundAttribute(attr);
							MStringArray	newCmds = new MStringArray();

							cAttrFn.getAddAttrCmds(newCmds);

							uint	numCommands = newCmds.length;
							int	c;

							for (c = 0; c < numCommands; c++)
							{
								if (newCmds[c] != "")
									cmds.append(newCmds[c]);
							}
						}
						catch (Exception)
						{
							string	newCmd = attrFn.getAddAttrCmd();
						
							if (newCmd != "") cmds.append(newCmd);
						}
					}
				}
			}
		}
コード例 #34
0
ファイル: MayaParser.cs プロジェクト: KasumiL5x/ciri
        private void computeMeshData()
        {
            foreach( MayaMesh mesh in allMeshes )
            {
                // Get the Maya mesh
                MFnMesh mayaMesh = new MFnMesh(mesh.mayaObjectPath);

                // Does the maya mesh have UVs?
                MStringArray uvSetNames = new MStringArray();
                mayaMesh.getUVSetNames(uvSetNames);
                bool hasUvs = (uvSetNames.length > 0) && (mayaMesh.numUVs(uvSetNames[0]) > 0);

                // Iterate through all of the vertices and build the data.
                MItMeshFaceVertex it = new MItMeshFaceVertex(mesh.mayaObjectPath);
                while( !it.isDone )
                {
                    // Create a new vertex and populate its data.
                    Vertex vert = new Vertex();

                    // Get the local position relative to the world origin.
                    MPoint mayaPos = it.position(MSpace.Space.kObject);
                    vert.position = new Vector3((float)mayaPos.x, (float)mayaPos.y, (float)mayaPos.z);
                    //vert.position = new Vector3((float)mayaPos.x - mesh.sourceXForm.mayaWorldPosition.x,
                                                                            //(float)mayaPos.y - mesh.sourceXForm.mayaWorldPosition.y,
                                                                            //(float)mayaPos.z - mesh.sourceXForm.mayaWorldPosition.z);

                    // Get the normal.
                    MVector mayaNrm = new MVector();
                    it.getNormal(mayaNrm, MSpace.Space.kObject);
                    vert.normal = new Vector3((float)mayaNrm.x, (float)mayaNrm.y, (float)mayaNrm.z);

                    // Texcoords.
                    if( hasUvs && it.hasUVsProperty )
                    {
                        float[] mayaUvs = new float[2];
                        it.getUV(mayaUvs, uvSetNames[0]);
                        vert.texcoord = new Vector2(mayaUvs[0], mayaUvs[1]);
                    }

                    // Append the vertex.
                    mesh.vertices.Add(vert);
                    it.next();
                }

                // Get all index data.
                MIntArray mia1 = new MIntArray();
                MIntArray mia2 = new MIntArray();
                mayaMesh.getTriangleOffsets(mia1, mia2);
                foreach( int idx in mia2 )
                {
                    mesh.indices.Add((uint)idx);
                }
            }
        }
コード例 #35
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		//
		// Write out the "fileInfo" command for the freeform information associated
		// with the scene.
		//
		protected void writeFileInfo(FileStream f)
		{
			//
			// There's no direct access to the scene's fileInfo from within the API,
			// so we have to call MEL's 'fileInfo' command.
			//
			MStringArray fileInfo = new MStringArray();

			try
			{
				MGlobal.executeCommand("fileInfo -q", fileInfo);
				uint numEntries = fileInfo.length;
				int i;
				string result = "";
				for (i = 0; i < numEntries; i += 2)
				{
					result += ("fileInfo " + quote(fileInfo[i]) + " " + quote(fileInfo[i+1]) + ";" + "\n");
				}
				writeString(f, result);
			}
			catch (Exception)
			{
				MGlobal.displayWarning("Could not get scene's fileInfo.");
			}	
		}
コード例 #36
0
ファイル: referenceQueryCmd.cs プロジェクト: meshdgp/MeshDGP
        public override void doIt(MArgList args)
        {
            MStringArray referenceFiles = new MStringArray();
            MFileIO.getReferences(referenceFiles);

            string log = "";
            for (int i = 0; i < referenceFiles.length; i++)
            {
                MStringArray connectionsMade = new MStringArray();
                MFileIO.getReferenceConnectionsMade(referenceFiles[i],
                                                      connectionsMade);

                log = string.Format("{0} Referenced File: {1}:\nConnections Made:\n", log, referenceFiles[i]);
                int j;
                for (j = 0; j < connectionsMade.length; j += 2)
                {
                    log = string.Format("	 {0} -> ", connectionsMade[j]);
                    if (j + 1 < connectionsMade.length)
                    {
                        log = log + connectionsMade[j + 1];
                    }
                    log += "\n";
                }

                MStringArray connectionsBroken = new MStringArray();
                MFileIO.getReferenceConnectionsBroken(referenceFiles[i],
                                                      connectionsBroken);

                log += "\n	Connections Broken: \n";
                for (j = 0; j < connectionsBroken.length; j += 2)
                {
                    log = string.Format("{0}	{1} -> ", log, connectionsBroken[j]);
                    if (j + 1 < connectionsBroken.length)
                    {
                        log += connectionsBroken[j + 1];
                    }
                    log += "\n";
                }
                log += "\n";

                MStringArray referencedNodes = new MStringArray();

                log += "	Attrs Changed Since File Open:\n";
                MFileIO.getReferenceNodes(referenceFiles[i], referencedNodes);
                for (j = 0; j < referencedNodes.length; j++)
                {
                    // For each node, call a MEL command to get its
                    // attributes.  Say we're only interested in scalars.
                    //
                    string cmd = string.Format("listAttr -s -cfo {0}", referencedNodes[j]);

                    MStringArray referencedAttributes = new MStringArray();

                    MGlobal.executeCommand(cmd, referencedAttributes);
                    for (int k = 0; k < referencedAttributes.length; k++)
                    {
                        log += string.Format("		{0}.{1}\n",
                            referencedNodes[j], referencedAttributes[k]);
                    }
                }
                log += "\n";
            }

            // End of output 
            //
            log += "=====================================";
            MGlobal.displayInfo(log);
            return;
        }
コード例 #37
0
ファイル: maTranslator.cs プロジェクト: meshdgp/MeshDGP
		//
		// Write out the "requires" lines which specify the plugins needed by the
		// scene.
		//
		protected void writeRequirements(FileStream f)
		{
			//
			// Every scene requires Maya itself.
			//
			string result = "";
			result += ("requires maya \"" + fFileVersion + "\";\n");

			//
			// Write out requirements for each plugin.
			//
			MStringArray pluginsUsed = new MStringArray();

			try
			{
			    MGlobal.executeCommand("pluginInfo -q -pluginsInUse", pluginsUsed);
			    uint numPlugins = pluginsUsed.length;
			    int i;

			    for (i = 0; i < numPlugins; i += 2)
			    {
				    result += ("requires " + quote(pluginsUsed[i]) + " "
						    + quote(pluginsUsed[i+1]) + ";" + "\n");
			    }
			}
			catch (Exception)
			{
				MGlobal.displayWarning(
					"Could not get list of plugins currently in use."
				);
			}
			writeString(f, result);
		}
コード例 #38
0
ファイル: filteredAsciiFile.cs プロジェクト: meshdgp/MeshDGP
        protected override void processWriteOptions(string optionsString)
        {
	        includedNodeTypesArray = new MStringArray();
            excludedNodeTypesArray = new MStringArray();
            sourcedFilesArray = new MStringArray();
            excludedNamesArray = new MStringArray();
	
	        outputRequirements = true;
	        outputReferences = true;
	
            MStringArray optionsArray = new MStringArray(optionsString.Split(';'));

	        for (int i = 0; i < optionsArray.length; i++)
	        {
		        string option = optionsArray[i];
		        MStringArray optionArray = new MStringArray(option.Split(' '));

		        if (optionArray[0] == "includeNodeType" && optionArray.length > 1)
		        {
			        includedNodeTypesArray.append(optionArray[1]);
		        }
		        else if (optionArray[0] == "excludeNodeType" && optionArray.length > 1)
		        {
			        excludedNodeTypesArray.append(optionArray[1]);
		        }
		        else if (optionArray[0] == "sourceFile" && optionArray.length > 1)
		        {
			        sourcedFilesArray.append(optionArray[1]);
		        }
	        }

            return;
        }
コード例 #39
0
        private Dictionary <string, object> _ExportCustomUserAttributes(BaseObject baseObject)
        {
            var objectName = "";

            if (baseObject.mFnTransform != null)
            {
                objectName = baseObject.mFnTransform.name;
            }
            else if (baseObject.babylonMaterial != null)
            {
                objectName = baseObject.babylonMaterial.name;
            }

            MStringArray customAttributeNamesMStringArray = new MStringArray();
            Dictionary <string, object> customsAttributes = new Dictionary <string, object>();

            MGlobal.executeCommand($"listAttr -ud {objectName}", customAttributeNamesMStringArray);

            var customAttributeNames = customAttributeNamesMStringArray.Where((attributeName) => { return(!_DisallowedCustomAttributeNames.Contains(attributeName)); });

            foreach (string name in customAttributeNames)
            {
                MStringArray type = new MStringArray();

                MGlobal.executeCommand($"getAttr -type {objectName}.{name}", type);

                switch (type[0])
                {
                case "double":
                    double floatValue = 0;
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", out floatValue);
                    customsAttributes.Add(name, floatValue);
                    break;

                case "bool":
                    int boolBinValue = 0;
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", out boolBinValue);
                    customsAttributes.Add(name, boolBinValue);
                    break;

                case "long":
                    int intValue = 0;
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", out intValue);
                    customsAttributes.Add(name, intValue);
                    break;

                case "string":
                    string stringValue = "";
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", out stringValue);
                    customsAttributes.Add(name, stringValue);
                    break;

                case "enum":
                    int enumValue = 0;
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", out enumValue);
                    customsAttributes.Add(name, enumValue);
                    break;

                case "double3":
                    MDoubleArray vectorValue = new MDoubleArray();
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", vectorValue);
                    customsAttributes.Add(name, vectorValue);
                    break;

                default:
                    MCommandResult attrValue = new MCommandResult();
                    MGlobal.executeCommand($"getAttr {objectName}.{name}", attrValue);
                    customsAttributes.Add(name, attrValue);
                    break;
                }
            }

            foreach (string name in customAttributeNames)
            {
                if (customsAttributes.ContainsKey(name + "X") && customsAttributes.ContainsKey(name + "Y") && customsAttributes.ContainsKey(name + "Z"))
                {
                    customsAttributes.Remove(name + "X");
                    customsAttributes.Remove(name + "Y");
                    customsAttributes.Remove(name + "Z");
                }
            }

            return(customsAttributes);
        }
コード例 #40
0
ファイル: MayaPlugin.cs プロジェクト: YangYangSaSa6/Exporters
        /// <summary>
        /// Write "ScriptToBabylon" in the Maya console to export with MEL
        /// </summary>
        /// <param name="argl"></param>
        ///
        public override void doIt(MArgList argl)
        {
            uint         index = 1;
            MStringArray argExportParameters = argl.asStringArray(ref index);
            string       errorMessage        = null;

            for (var i = 0; i < argExportParameters.length; i++)
            {
                switch (i)
                {
                case 0:
                    if (argExportParameters[i] != "")
                    {
                        ScriptExportParameters.outputPath = argExportParameters[i];
                    }
                    else
                    {
                        errorMessage = "The specified path is not valid";
                    }
                    break;

                case 1:
                    if (argExportParameters[i] != "babylon" || argExportParameters[i] != "gltf" || argExportParameters[i] != "glb" || argExportParameters[i] != "binary babylon")
                    {
                        ScriptExportParameters.outputFormat = argExportParameters[i];
                    }
                    else
                    {
                        errorMessage = "The specified output format is not valid";
                    }
                    break;

                case 2:
                    ScriptExportParameters.textureFolder = argExportParameters[i];
                    break;

                case 3:
                    ScriptExportParameters.scaleFactor = float.Parse(argExportParameters[i]);
                    break;

                case 4:
                    ScriptExportParameters.writeTextures = bool.Parse(argExportParameters[i]);
                    break;

                case 5:
                    ScriptExportParameters.overwriteTextures = bool.Parse(argExportParameters[i]);
                    break;

                case 6:
                    ScriptExportParameters.exportHiddenObjects = bool.Parse(argExportParameters[i]);
                    break;

                case 7:
                    ScriptExportParameters.exportMaterials = bool.Parse(argExportParameters[i]);
                    break;

                case 8:
                    ScriptExportParameters.exportOnlySelected = bool.Parse(argExportParameters[i]);
                    break;

                case 9:
                    ScriptExportParameters.bakeAnimationFrames = bool.Parse(argExportParameters[i]);
                    break;

                case 10:
                    ScriptExportParameters.optimizeAnimations = bool.Parse(argExportParameters[i]);
                    break;

                case 11:
                    ScriptExportParameters.optimizeVertices = bool.Parse(argExportParameters[i]);
                    break;

                case 12:
                    ScriptExportParameters.animgroupExportNonAnimated = bool.Parse(argExportParameters[i]);
                    break;

                case 13:
                    ScriptExportParameters.generateManifest = bool.Parse(argExportParameters[i]);
                    break;

                case 14:
                    ScriptExportParameters.autoSaveSceneFile = bool.Parse(argExportParameters[i]);
                    break;

                case 15:
                    ScriptExportParameters.exportTangents = bool.Parse(argExportParameters[i]);
                    break;

                case 16:
                    ScriptExportParameters.exportSkins = bool.Parse(argExportParameters[i]);
                    break;

                case 17:
                    ScriptExportParameters.exportMorphTangents = bool.Parse(argExportParameters[i]);
                    break;

                case 18:
                    ScriptExportParameters.exportMorphNormals = bool.Parse(argExportParameters[i]);
                    break;

                case 19:
                    ScriptExportParameters.txtQuality = long.Parse(argExportParameters[i]);
                    break;

                case 20:
                    ScriptExportParameters.mergeAOwithMR = bool.Parse(argExportParameters[i]);
                    break;

                case 21:
                    ScriptExportParameters.dracoCompression = bool.Parse(argExportParameters[i]);
                    break;

                case 22:
                    ScriptExportParameters.enableKHRLightsPunctual = bool.Parse(argExportParameters[i]);
                    break;

                case 23:
                    ScriptExportParameters.enableKHRTextureTransform = bool.Parse(argExportParameters[i]);
                    break;

                case 24:
                    ScriptExportParameters.enableKHRMaterialsUnlit = bool.Parse(argExportParameters[i]);
                    break;

                case 25:
                    ScriptExportParameters.pbrFull = bool.Parse(argExportParameters[i]);
                    break;

                case 26:
                    ScriptExportParameters.pbrNoLight = bool.Parse(argExportParameters[i]);
                    break;

                case 27:
                    ScriptExportParameters.createDefaultSkybox = bool.Parse(argExportParameters[i]);
                    break;

                case 28:
                    ScriptExportParameters.pbrEnvironment = argExportParameters[i];
                    break;
                }
            }

            if (errorMessage == null)
            {
                try
                {
                    BabylonExporter exporterInstance = new BabylonExporter();

                    exporterInstance.OnError += (error, rank) =>
                    {
                        try
                        {
                            displayError(error);
                        }
                        catch
                        {
                        }
                        Application.DoEvents();
                    };

                    exporterInstance.OnWarning += (error, rank) =>
                    {
                        try
                        {
                            displayWarning(error);
                        }
                        catch
                        {
                        }
                        Application.DoEvents();
                    };

                    exporterInstance.OnMessage += (message, color, rank, emphasis) =>
                    {
                        try
                        {
                            displayInfo(message);
                        }
                        catch
                        {
                        }
                        Application.DoEvents();
                    };

                    exporterInstance.Export(ScriptExportParameters);
                }
                catch (Exception ex)
                {
                    displayError("Export cancelled: " + ex.Message);
                }
            }
            else
            {
                displayError(errorMessage);
            }
        }
コード例 #41
0
 public override bool getSourceStreams(MObject objPath, MStringArray sourceStreams)
 {
     // No source stream needed
     return(false);
 }
コード例 #42
0
        /// <summary>
        /// Extract geometry (position, normal, UVs...) for a specific vertex
        /// </summary>
        /// <param name="mFnMesh"></param>
        /// <param name="polygonId">The polygon (face) to examine</param>
        /// <param name="vertexIndexGlobal">The object-relative (mesh-relative/global) vertex index</param>
        /// <param name="vertexIndexLocal">The face-relative (local) vertex id to examine</param>
        /// <param name="uvSetNames"></param>
        /// <param name="isUVExportSuccess"></param>
        /// <returns></returns>
        private GlobalVertex ExtractVertex(MFnMesh mFnMesh, int polygonId, int vertexIndexGlobal, int vertexIndexLocal, MStringArray uvSetNames, ref bool[] isUVExportSuccess, ref bool isTangentExportSuccess)
        {
            MPoint point = new MPoint();

            mFnMesh.getPoint(vertexIndexGlobal, point);

            MVector normal = new MVector();

            mFnMesh.getFaceVertexNormal(polygonId, vertexIndexGlobal, normal);

            // Switch coordinate system at object level
            point.z  *= -1;
            normal.z *= -1;

            var vertex = new GlobalVertex
            {
                BaseIndex = vertexIndexGlobal,
                Position  = point.toArray(),
                Normal    = normal.toArray()
            };

            // Tangent
            if (isTangentExportSuccess)
            {
                try
                {
                    MVector tangent = new MVector();
                    mFnMesh.getFaceVertexTangent(polygonId, vertexIndexGlobal, tangent);

                    // Switch coordinate system at object level
                    tangent.z *= -1;

                    int  tangentId            = mFnMesh.getTangentId(polygonId, vertexIndexGlobal);
                    bool isRightHandedTangent = mFnMesh.isRightHandedTangent(tangentId);

                    // Invert W to switch to left handed system
                    vertex.Tangent = new float[] { (float)tangent.x, (float)tangent.y, (float)tangent.z, isRightHandedTangent ? -1 : 1 };
                }
                catch
                {
                    // Exception raised when mesh don't have tangents
                    isTangentExportSuccess = false;
                }
            }

            // Color
            int    colorIndex;
            string colorSetName;

            float[] defaultColor = new float[] { 1, 1, 1, 0 };
            MColor  color        = new MColor();

            mFnMesh.getCurrentColorSetName(out colorSetName);

            if (mFnMesh.numColors(colorSetName) > 0)
            {
                //Get the color index
                mFnMesh.getColorIndex(polygonId, vertexIndexLocal, out colorIndex);

                //if a color is set
                if (colorIndex != -1)
                {
                    mFnMesh.getColor(colorIndex, color);
                    vertex.Color = color.toArray();
                }
                //else set the default color
                else
                {
                    vertex.Color = defaultColor;
                }
            }

            // UV
            int indexUVSet = 0;

            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV = new float[] { u, v };
                }
                catch
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }
            indexUVSet = 1;
            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV2 = new float[] { u, v };
                }
                catch
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }

            // skin
            if (mFnSkinCluster != null)
            {
                // Filter null weights
                Dictionary <int, double> weightByInfluenceIndex = new Dictionary <int, double>(); // contains the influence indices with weight > 0

                // Export Weights and BonesIndices for the vertex
                // Get the weight values of all the influences for this vertex
                allMayaInfluenceWeights = new MDoubleArray();
                MGlobal.executeCommand($"skinPercent -query -value {mFnSkinCluster.name} {mFnTransform.name}.vtx[{vertexIndexGlobal}]",
                                       allMayaInfluenceWeights);
                allMayaInfluenceWeights.get(out double[] allInfluenceWeights);

                for (int influenceIndex = 0; influenceIndex < allInfluenceWeights.Length; influenceIndex++)
                {
                    double weight = allInfluenceWeights[influenceIndex];

                    if (weight > 0)
                    {
                        try
                        {
                            // add indice and weight in the local lists
                            weightByInfluenceIndex.Add(indexByNodeName[allMayaInfluenceNames[influenceIndex]], weight);
                        }
                        catch (Exception e)
                        {
                            RaiseError(e.Message, 2);
                            RaiseError(e.StackTrace, 3);
                        }
                    }
                }

                // normalize weights => Sum weights == 1
                Normalize(ref weightByInfluenceIndex);

                // decreasing sort
                OrderByDescending(ref weightByInfluenceIndex);

                int   bonesCount = indexByNodeName.Count; // number total of bones/influences for the mesh
                float weight0    = 0;
                float weight1    = 0;
                float weight2    = 0;
                float weight3    = 0;
                int   bone0      = bonesCount;
                int   bone1      = bonesCount;
                int   bone2      = bonesCount;
                int   bone3      = bonesCount;
                int   nbBones    = weightByInfluenceIndex.Count; // number of bones/influences for this vertex

                if (nbBones == 0)
                {
                    weight0 = 1.0f;
                    bone0   = bonesCount;
                }

                if (nbBones > 0)
                {
                    bone0   = weightByInfluenceIndex.ElementAt(0).Key;
                    weight0 = (float)weightByInfluenceIndex.ElementAt(0).Value;

                    if (nbBones > 1)
                    {
                        bone1   = weightByInfluenceIndex.ElementAt(1).Key;
                        weight1 = (float)weightByInfluenceIndex.ElementAt(1).Value;

                        if (nbBones > 2)
                        {
                            bone2   = weightByInfluenceIndex.ElementAt(2).Key;
                            weight2 = (float)weightByInfluenceIndex.ElementAt(2).Value;

                            if (nbBones > 3)
                            {
                                bone3   = weightByInfluenceIndex.ElementAt(3).Key;
                                weight3 = (float)weightByInfluenceIndex.ElementAt(3).Value;
                            }
                        }
                    }
                }

                float[] weights = { weight0, weight1, weight2, weight3 };
                vertex.Weights      = weights;
                vertex.BonesIndices = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;

                if (nbBones > 4)
                {
                    bone0   = weightByInfluenceIndex.ElementAt(4).Key;
                    weight0 = (float)weightByInfluenceIndex.ElementAt(4).Value;
                    weight1 = 0;
                    weight2 = 0;
                    weight3 = 0;

                    if (nbBones > 5)
                    {
                        bone1   = weightByInfluenceIndex.ElementAt(5).Key;
                        weight1 = (float)weightByInfluenceIndex.ElementAt(4).Value;

                        if (nbBones > 6)
                        {
                            bone2   = weightByInfluenceIndex.ElementAt(6).Key;
                            weight2 = (float)weightByInfluenceIndex.ElementAt(4).Value;

                            if (nbBones > 7)
                            {
                                bone3   = weightByInfluenceIndex.ElementAt(7).Key;
                                weight3 = (float)weightByInfluenceIndex.ElementAt(7).Value;
                            }
                        }
                    }

                    float[] weightsExtra = { weight0, weight1, weight2, weight3 };
                    vertex.WeightsExtra      = weightsExtra;
                    vertex.BonesIndicesExtra = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
                }
            }
            return(vertex);
        }
コード例 #43
0
        /// <summary>
        /// Extract ordered indices on a triangle basis
        /// Extract position and normal of each vertex per face
        /// </summary>
        /// <param name="mFnMesh"></param>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        /// <param name="subMeshes"></param>
        /// <param name="uvSetNames"></param>
        /// <param name="isUVExportSuccess"></param>
        /// <param name="optimizeVertices"></param>
        private void ExtractGeometry(MFnMesh mFnMesh, List <GlobalVertex> vertices, List <int> indices, List <BabylonSubMesh> subMeshes, MStringArray uvSetNames, ref bool[] isUVExportSuccess, bool optimizeVertices)
        {
            // TODO - optimizeVertices
            MIntArray triangleCounts    = new MIntArray();
            MIntArray trianglesVertices = new MIntArray();

            mFnMesh.getTriangles(triangleCounts, trianglesVertices);

            MObjectArray shaders        = new MObjectArray();
            MIntArray    faceMatIndices = new MIntArray(); // given a face index => get a shader index

            mFnMesh.getConnectedShaders(0, shaders, faceMatIndices);

            // Export geometry even if an error occured with shaders
            // This is a fix for Maya test files
            // TODO - Find the reason why shaders.count = 0
            int  nbShaders   = Math.Max(1, shaders.Count);
            bool checkShader = nbShaders == shaders.Count;

            RaiseVerbose("shaders.Count=" + shaders.Count, 2);

            // For each material of this mesh
            for (int indexShader = 0; indexShader < nbShaders; indexShader++)
            {
                var nbIndicesSubMesh      = 0;
                var minVertexIndexSubMesh = int.MaxValue;
                var maxVertexIndexSubMesh = int.MinValue;
                var subMesh = new BabylonSubMesh {
                    indexStart = indices.Count, materialIndex = indexShader
                };

                // For each polygon of this mesh
                for (int polygonId = 0; polygonId < faceMatIndices.Count; polygonId++)
                {
                    if (checkShader && faceMatIndices[polygonId] != indexShader)
                    {
                        continue;
                    }

                    // The object-relative (mesh-relative/global) vertex indices for this face
                    MIntArray polygonVertices = new MIntArray();
                    mFnMesh.getPolygonVertices(polygonId, polygonVertices);

                    // For each triangle of this polygon
                    for (int triangleId = 0; triangleId < triangleCounts[polygonId]; triangleId++)
                    {
                        int[] polygonTriangleVertices = new int[3];
                        mFnMesh.getPolygonTriangleVertices(polygonId, triangleId, polygonTriangleVertices);

                        /*
                         * Switch coordinate system at global level
                         *
                         * Piece of code kept just in case
                         * See BabylonExporter for more information
                         */
                        //// Inverse winding order to flip faces
                        //var tmp = triangleVertices[1];
                        //triangleVertices[1] = triangleVertices[2];
                        //triangleVertices[2] = tmp;

                        // For each vertex of this triangle (3 vertices per triangle)
                        foreach (int vertexIndexGlobal in polygonTriangleVertices)
                        {
                            // Get the face-relative (local) vertex id
                            int vertexIndexLocal = 0;
                            for (vertexIndexLocal = 0; vertexIndexLocal < polygonVertices.Count; vertexIndexLocal++)
                            {
                                if (polygonVertices[vertexIndexLocal] == vertexIndexGlobal)
                                {
                                    break;
                                }
                            }

                            GlobalVertex vertex = ExtractVertex(mFnMesh, polygonId, vertexIndexGlobal, vertexIndexLocal, uvSetNames, ref isUVExportSuccess);
                            vertex.CurrentIndex = vertices.Count;

                            indices.Add(vertex.CurrentIndex);
                            vertices.Add(vertex);

                            minVertexIndexSubMesh = Math.Min(minVertexIndexSubMesh, vertex.CurrentIndex);
                            maxVertexIndexSubMesh = Math.Max(maxVertexIndexSubMesh, vertex.CurrentIndex);
                            nbIndicesSubMesh++;
                        }
                    }
                }

                if (nbIndicesSubMesh != 0)
                {
                    subMesh.indexCount    = nbIndicesSubMesh;
                    subMesh.verticesStart = minVertexIndexSubMesh;
                    subMesh.verticesCount = maxVertexIndexSubMesh - minVertexIndexSubMesh + 1;

                    subMeshes.Add(subMesh);
                }
            }
        }
コード例 #44
0
ファイル: lineManipContainer.cs プロジェクト: meshdgp/MeshDGP
		//! Ensure that valid geometry is selected
		bool validGeometrySelected()
		{
			MSelectionList list = new MSelectionList();
			MGlobal.getActiveSelectionList(list);
			MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

			for (; !iter.isDone; iter.next())
			{
				MObject dependNode = new MObject();
				iter.getDependNode(dependNode);
				if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kTransform))
				{
					MGlobal.displayWarning("Object in selection list is not right type of node");
					return false;
				}

				MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
				MStringArray attributeNames = new MStringArray();
				attributeNames.append("scaleX");
				attributeNames.append("translateX");

				int i;
				for ( i = 0; i < attributeNames.length; i++ )
				{
					MPlug plug = dependNodeFn.findPlug(attributeNames[i]);
					if ( plug.isNull )
					{
						MGlobal.displayWarning("Object cannot be manipulated: " +
							dependNodeFn.name);
						return false;
					}
				}
			}
			return true;
		}
コード例 #45
0
        /// <summary>
        /// Extract geometry (position, normal, UVs...) for a specific vertex
        /// </summary>
        /// <param name="mFnMesh"></param>
        /// <param name="polygonId">The polygon (face) to examine</param>
        /// <param name="vertexIndexGlobal">The object-relative (mesh-relative/global) vertex index</param>
        /// <param name="vertexIndexLocal">The face-relative (local) vertex id to examine</param>
        /// <param name="uvSetNames"></param>
        /// <param name="isUVExportSuccess"></param>
        /// <returns></returns>
        private GlobalVertex ExtractVertex(MFnMesh mFnMesh, int polygonId, int vertexIndexGlobal, int vertexIndexLocal, MStringArray uvSetNames, ref bool[] isUVExportSuccess)
        {
            MPoint point = new MPoint();

            mFnMesh.getPoint(vertexIndexGlobal, point);

            MVector normal = new MVector();

            mFnMesh.getFaceVertexNormal(polygonId, vertexIndexGlobal, normal);

            // Switch coordinate system at object level
            point.z  *= -1;
            normal.z *= -1;

            var vertex = new GlobalVertex
            {
                BaseIndex = vertexIndexGlobal,
                Position  = point.toArray(),
                Normal    = normal.toArray(),
            };

            // TODO - Export colors ?
            //// Color
            //int colorIndex;
            //string colorSetName;
            //float[] defaultColor = new float[] { 0.5f, 0.5f, 0.5f, 1 };
            //MColor color = new MColor();
            //mFnMesh.getCurrentColorSetName(out colorSetName);

            //if (mFnMesh.numColors(colorSetName) > 0)
            //{
            //    //Get the color index
            //    mFnMesh.getColorIndex(polygonId, vertexIndexLocal, out colorIndex);

            //    //if a color is set
            //    if (colorIndex != -1)
            //    {
            //        mFnMesh.getColor(colorIndex, color);
            //        vertex.Color = color.toArray();
            //    }
            //    //else set the color to the default one of Maya
            //    else
            //    {
            //        vertex.Color = defaultColor;
            //    }
            //}
            //else
            //{
            //    vertex.Color = defaultColor;
            //}

            // UV
            int indexUVSet = 0;

            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV = new float[] { u, v };
                }
                catch (Exception e)
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }
            indexUVSet = 1;
            if (uvSetNames.Count > indexUVSet && isUVExportSuccess[indexUVSet])
            {
                try
                {
                    float u = 0, v = 0;
                    mFnMesh.getPolygonUV(polygonId, vertexIndexLocal, ref u, ref v, uvSetNames[indexUVSet]);
                    vertex.UV2 = new float[] { u, v };
                }
                catch (Exception e)
                {
                    // An exception is raised when a vertex isn't mapped to an UV coordinate
                    isUVExportSuccess[indexUVSet] = false;
                }
            }


            return(vertex);
        }
コード例 #46
0
        private void _exportUV(MFnDependencyNode textureDependencyNode, BabylonTexture babylonTexture, List <MFnDependencyNode> textureModifiers = null, bool updateCoordinatesMode = false)
        {
            // Coordinates mode
            if (updateCoordinatesMode)
            {
                // Default is spherical
                babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.SPHERICAL_MODE;

                if (textureModifiers != null)
                {
                    MFnDependencyNode lastProjectionTextureModifier = textureModifiers.FindLast(textureModifier => textureModifier.objectProperty.hasFn(MFn.Type.kProjection));
                    if (lastProjectionTextureModifier != null)
                    {
                        var projType = lastProjectionTextureModifier.findPlug("projType").asIntProperty;
                        switch (projType)
                        {
                        case 1:     // Planar
                            babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.PLANAR_MODE;
                            break;

                        case 2:     // Spherical
                            babylonTexture.coordinatesMode = BabylonTexture.CoordinatesMode.SPHERICAL_MODE;
                            break;
                        }
                    }
                }
            }

            // UV set
            MStringArray uvLinks = new MStringArray();

            MGlobal.executeCommand($@"uvLink -query -texture {textureDependencyNode.name};", uvLinks);
            if (uvLinks.Count == 0)
            {
                babylonTexture.coordinatesIndex = 0;
            }
            else
            {
                // Retreive UV set indices
                HashSet <int> uvSetIndices = new HashSet <int>();
                foreach (string uvLink in uvLinks)
                {
                    int    indexOpenBracket   = uvLink.LastIndexOf("[");
                    int    indexCloseBracket  = uvLink.LastIndexOf("]");
                    string uvSetIndexAsString = uvLink.Substring(indexOpenBracket + 1, indexCloseBracket - indexOpenBracket - 1);
                    int    uvSetIndex         = int.Parse(uvSetIndexAsString);
                    uvSetIndices.Add(uvSetIndex);
                }
                if (uvSetIndices.Count > 1)
                {
                    // Check that all uvSet indices are all 0 or all not 0
                    int nbZero = 0;
                    foreach (int uvSetIndex in uvSetIndices)
                    {
                        if (uvSetIndex == 0)
                        {
                            nbZero++;
                        }
                    }
                    if (nbZero != 0 && nbZero != uvSetIndices.Count)
                    {
                        RaiseWarning("Texture is linked to UV1 and UV2. Only one UV set per texture is supported.", logRankTexture + 1);
                    }
                }
                // The first UV set of a mesh is special because it can never be deleted
                // Thus if the UV set index is 0 then the binded mesh UV set is always UV1
                // Other UV sets of a mesh can be created / deleted at will
                // Thus the UV set index can have any value (> 0)
                // In this case, the exported UV set is always UV2 even though it would be UV3 or UV4 in Maya
                babylonTexture.coordinatesIndex = (new List <int>(uvSetIndices))[0] == 0 ? 0 : 1;
            }

            // For more information about UV
            // see http://help.autodesk.com/view/MAYAUL/2018/ENU/?guid=GUID-94070C7E-C550-42FD-AFC9-FBE82B173B1D
            babylonTexture.uOffset = textureDependencyNode.findPlug("offsetU").asFloat();

            babylonTexture.vOffset = textureDependencyNode.findPlug("offsetV").asFloat();

            babylonTexture.uScale = textureDependencyNode.findPlug("repeatU").asFloat();
            babylonTexture.vScale = textureDependencyNode.findPlug("repeatV").asFloat();

            if (Path.GetExtension(babylonTexture.name).ToLower() == ".dds")
            {
                babylonTexture.vScale *= -1; // Need to invert Y-axis for DDS texture
            }

            // Maya only has a W rotation
            babylonTexture.uAng = 0;
            babylonTexture.vAng = 0;
            babylonTexture.wAng = textureDependencyNode.findPlug("rotateFrame").asFloat();

            // TODO - rotation and scale
            if (babylonTexture.wAng != 0f && (babylonTexture.uScale != 1f || babylonTexture.vScale != 1f))
            {
                RaiseWarning("Rotation and tiling (scale) on a texture are only supported separatly. You can use the map UV of the mesh for those transformation.", logRankTexture + 1);
            }

            // Adress mode U
            // TODO - What is adress mode when both wrap and mirror?
            if (textureDependencyNode.findPlug("mirrorU").asBool())
            {
                babylonTexture.wrapU = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE;
            }
            else if (textureDependencyNode.findPlug("wrapU").asBool())
            {
                babylonTexture.wrapU = BabylonTexture.AddressMode.WRAP_ADDRESSMODE;
            }
            else
            {
                // TODO - What is adress mode when not wrap nor mirror?
                babylonTexture.wrapU = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE;
            }

            // Adress mode V
            // TODO - What is adress mode when both wrap and mirror?
            if (textureDependencyNode.findPlug("mirrorV").asBool())
            {
                babylonTexture.wrapV = BabylonTexture.AddressMode.MIRROR_ADDRESSMODE;
            }
            else if (textureDependencyNode.findPlug("wrapV").asBool())
            {
                babylonTexture.wrapV = BabylonTexture.AddressMode.WRAP_ADDRESSMODE;
            }
            else
            {
                // TODO - What is adress mode when not wrap nor mirror?
                babylonTexture.wrapV = BabylonTexture.AddressMode.CLAMP_ADDRESSMODE;
            }

            // Animation
            babylonTexture.animations = GetTextureAnimations(textureDependencyNode).ToArray();
        }