예제 #1
0
        public MSelectionList RestoreSelectionOnList(MSelectionList targetList = null, bool selectResult = false)
        {
            if (targetList == null || targetList.length == 0)
            {
                targetList = BasicFunc.GetSelectedList();
            }

            MSelectionList resultSelection = new MSelectionList();

            for (int i = 0; i < targetList.length; i++)
            {
                if (i >= selectedIndicesList.Count)
                {
                    break;
                }
                MDagPath dag = new MDagPath();
                targetList.getDagPath((uint)i, dag);
                MFnSingleIndexedComponent sic = new MFnSingleIndexedComponent();
                MObject components            = sic.create(MFn.Type.kMeshPolygonComponent);
                sic.addElements(new MIntArray(selectedIndicesList[i]));
                resultSelection.add(dag, components);
                //resultSelection.add(dag);
            }
            if (selectResult)
            {
                BasicFunc.Select(resultSelection);
            }
            return(resultSelection);
        }
예제 #2
0
        public MSelectionList RestoreSelectionOnDag(MDagPath targetDag = null, bool selectResult = false)
        {
            if (targetDag == null)
            {
                return(null);
            }

            MSelectionList resultSelection = new MSelectionList();

            MFnSingleIndexedComponent sic = new MFnSingleIndexedComponent();
            MObject components            = sic.create(MFn.Type.kMeshPolygonComponent);

            sic.addElements(new MIntArray(selectedIndicesList[0]));
            resultSelection.add(targetDag, components);
            //resultSelection.add(targetDag);
            if (selectResult)
            {
                BasicFunc.Select(resultSelection);
            }
            return(resultSelection);
        }
예제 #3
0
        //
        // Description:
        //
        //    Component/attribute matching method.
        //    This method validates component names and indices which are
        //    specified as a string and adds the corresponding component
        //    to the passed in selection list.
        //
        //    For instance, select commands such as "select shape1.vtx[0:7]"
        //    are validated with this method and the corresponding component
        //    is added to the selection list.
        //
        // Arguments
        //
        //    item - DAG selection item for the object being matched
        //    spec - attribute specification object
        //    list - list to add components to
        //
        // Returns
        //
        //    the result of the match
        //
        public override MatchResult matchComponent(MSelectionList item, MAttributeSpecArray spec, MSelectionList list)
        {
            MatchResult result = MatchResult.kMatchOk;
            MAttributeSpec attrSpec = spec[0];
            int dim = attrSpec.dimensions;

            // Look for attributes specifications of the form :
            //     vtx[ index ]
            //     vtx[ lower:upper ]
            //
            if ( (1 == spec.length) && (dim > 0) && (attrSpec.name == "vtx") ) {
                int numVertices = (int)meshGeom().vertices.length;
                MAttributeIndex attrIndex = attrSpec[0];

                int upper = 0;
                int lower = 0;
                if ( attrIndex.hasLowerBound ) {
                    attrIndex.getLower( out lower );
                }
                if ( attrIndex.hasUpperBound ) {
                    attrIndex.getUpper( out upper );
                }

                // Check the attribute index range is valid
                //
                if ( (lower > upper) || (upper >= numVertices) ) {
                    result = MatchResult.kMatchInvalidAttributeRange;
                }
                else {
                    MDagPath path = new MDagPath();
                    item.getDagPath( 0, path );
                    MFnSingleIndexedComponent fnVtxComp = new MFnSingleIndexedComponent();
                    MObject vtxComp = fnVtxComp.create( MFn.Type.kMeshVertComponent );

                    for ( int i=lower; i<=upper; i++ )
                    {
                        fnVtxComp.addElement( i );
                    }
                    list.add( path, vtxComp );
                }
            }
            else {
                // Pass this to the parent class
                return base.matchComponent( item, spec, list );
            }

            return result;
        }
예제 #4
0
        //
        // Description
        //     This method is used by Maya when it needs to create a component
        //     containing every vertex (or control point) in the shape.
        //     This will get called if you apply some deformer to the whole
        //     shape, i.e. select the shape in object mode and add a deformer to it.
        //
        // Returns
        //
        //    A "complete" component representing all vertices in the shape.
        //
        // Support deformers (components)
        //
        public override MObject createFullVertexGroup()
        {
            // Create a vertex component
            //
            MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent();
            MObject fullComponent = fnComponent.create( MFn.Type.kMeshVertComponent );

            // Set the component to be complete, i.e. the elements in
            // the component will be [0:numVertices-1]
            //
            int numVertices = (int)meshGeom().vertices.length;
            fnComponent.setCompleteData( numVertices );

            return fullComponent;
        }
예제 #5
0
        public void Load(string name)
        {
            List <StaticObjectVertex> vertices = GetVertices();
            List <uint> indices = GetIndices();

            MIntArray        polygonIndexCounts = new MIntArray((uint)indices.Count / 3);
            MIntArray        polygonIndices     = new MIntArray((uint)indices.Count);
            MFloatPointArray meshVertices       = new MFloatPointArray((uint)vertices.Count);
            MFloatArray      arrayU             = new MFloatArray((uint)vertices.Count);
            MFloatArray      arrayV             = new MFloatArray((uint)vertices.Count);
            MFnMesh          mesh        = new MFnMesh();
            MDagPath         meshDagPath = new MDagPath();
            MDGModifier      modifier    = new MDGModifier();
            MFnSet           set         = new MFnSet();

            for (int i = 0; i < indices.Count / 3; i++)
            {
                polygonIndexCounts[i] = 3;
            }

            for (int i = 0; i < indices.Count; i++)
            {
                polygonIndices[i] = (int)indices[i];
            }

            for (int i = 0; i < vertices.Count; i++)
            {
                StaticObjectVertex vertex = vertices[i];

                meshVertices[i] = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z);
                arrayU[i]       = vertex.UV.X;
                arrayV[i]       = 1 - vertex.UV.Y;
            }

            //Assign mesh data
            mesh.create(vertices.Count, indices.Count / 3, meshVertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj);
            mesh.getPath(meshDagPath);
            mesh.assignUVs(polygonIndexCounts, polygonIndices);

            //Set names
            mesh.setName(name);
            MFnTransform transformNode = new MFnTransform(mesh.parent(0));

            transformNode.setName("transform_" + name);

            //Get render partition
            MFnPartition renderPartition = MayaHelper.FindRenderPartition();

            //Create Materials
            uint startIndex = 0;

            for (int i = 0; i < this.Submeshes.Count; i++)
            {
                MFnDependencyNode   dependencyNode = new MFnDependencyNode();
                MFnLambertShader    lambertShader  = new MFnLambertShader();
                StaticObjectSubmesh submesh        = this.Submeshes[i];

                lambertShader.create(true);
                lambertShader.setName(submesh.Name);
                lambertShader.color = MaterialProvider.GetMayaColor(i);

                MObject shadingEngine = dependencyNode.create("shadingEngine", submesh.Name + "_SG");
                MObject materialInfo  = dependencyNode.create("materialInfo", submesh.Name + "_MaterialInfo");
                MPlug   partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition");
                MPlug   setsPlug      = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets"));
                modifier.connect(partitionPlug, setsPlug);

                MPlug outColorPlug      = lambertShader.findPlug("outColor");
                MPlug surfaceShaderPlug = new MFnDependencyNode(shadingEngine).findPlug("surfaceShader");
                modifier.connect(outColorPlug, surfaceShaderPlug);

                MPlug messagePlug      = new MFnDependencyNode(shadingEngine).findPlug("message");
                MPlug shadingGroupPlug = new MFnDependencyNode(materialInfo).findPlug("shadingGroup");
                modifier.connect(messagePlug, shadingGroupPlug);

                modifier.doIt();

                MFnSingleIndexedComponent component = new MFnSingleIndexedComponent();
                MObject   faceComponent             = component.create(MFn.Type.kMeshPolygonComponent);
                MIntArray groupPolygonIndices       = new MIntArray();
                uint      endIndex = (startIndex + (uint)submesh.Indices.Count) / 3;
                for (uint j = startIndex / 3; j < endIndex; j++)
                {
                    groupPolygonIndices.append((int)j);
                }
                component.addElements(groupPolygonIndices);

                set.setObject(shadingEngine);
                set.addMember(meshDagPath, faceComponent);

                startIndex += (uint)submesh.Indices.Count;
            }

            mesh.updateSurface();
        }
예제 #6
0
		// Support deformers (components)
		//
		public override MObject createFullVertexGroup()
		//
		// Description
		//     This method is used by Maya when it needs to create a component
		//     containing every vertex (or control point) in the shape.
		//     This will get called if you apply some deformer to the whole
		//     shape, i.e. select the shape in object mode and add a deformer to it.
		//
		// Returns
		//
		//    A "complete" component representing all vertices in the shape.
		//
		{
			// Create a vertex component
			//
			MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent();
			MObject fullComponent = fnComponent.create( MFn.Type.kMeshVertComponent );

			// Set the component to be complete, i.e. the elements in
			// the component will be [0:numVertices-1]
			//
			int numVertices = (int)meshGeom().vertices.length;
			fnComponent.setCompleteData( numVertices );

			return fullComponent;
		}
예제 #7
0
		public override MatchResult matchComponent(MSelectionList item, MAttributeSpecArray spec, MSelectionList list)
		//
		// Description:
		//
		//    Component/attribute matching method.
		//    This method validates component names and indices which are
		//    specified as a string and adds the corresponding component
		//    to the passed in selection list.
		//
		//    For instance, select commands such as "select shape1.vtx[0:7]"
		//    are validated with this method and the corresponding component
		//    is added to the selection list.
		//
		// Arguments
		//
		//    item - DAG selection item for the object being matched
		//    spec - attribute specification object
		//    list - list to add components to
		//
		// Returns
		//
		//    the result of the match
		//
		{
			MatchResult result = MatchResult.kMatchOk;
			MAttributeSpec attrSpec = spec[0];
			int dim = attrSpec.dimensions;

			// Look for attributes specifications of the form :
			//     vtx[ index ]
			//     vtx[ lower:upper ]
			//
			if ( (1 == spec.length) && (dim > 0) && (attrSpec.name == "vtx") ) {
				int numVertices = (int)meshGeom().vertices.length;
				MAttributeIndex attrIndex = attrSpec[0];

				int upper = 0;
				int lower = 0;
				if ( attrIndex.hasLowerBound ) {
					attrIndex.getLower( out lower );
				}
				if ( attrIndex.hasUpperBound ) {
					attrIndex.getUpper( out upper );
				}

				// Check the attribute index range is valid
				//
				if ( (lower > upper) || (upper >= numVertices) ) {
					result = MatchResult.kMatchInvalidAttributeRange;
				}
				else {
					MDagPath path = new MDagPath();
					item.getDagPath( 0, path );
					MFnSingleIndexedComponent fnVtxComp = new MFnSingleIndexedComponent();
					MObject vtxComp = fnVtxComp.create( MFn.Type.kMeshVertComponent );

					for ( int i=lower; i<=upper; i++ )
					{
						fnVtxComp.addElement( i );
					}
					list.add( path, vtxComp );
				}
			}
			else {
				// Pass this to the parent class
				return base.matchComponent( item, spec, list );
			}

			return result;
		}
예제 #8
0
        public void Load(string name, SKLFile skl = null)
        {
            MIntArray        polygonIndexCounts = new MIntArray((uint)this.Indices.Count / 3);
            MIntArray        polygonIndices     = new MIntArray((uint)this.Indices.Count);
            MFloatPointArray vertices           = new MFloatPointArray((uint)this.Vertices.Count);
            MFloatArray      arrayU             = new MFloatArray((uint)this.Vertices.Count);
            MFloatArray      arrayV             = new MFloatArray((uint)this.Vertices.Count);
            MVectorArray     normals            = new MVectorArray((uint)this.Vertices.Count);
            MIntArray        normalIndices      = new MIntArray((uint)this.Vertices.Count);
            MFnMesh          mesh        = new MFnMesh();
            MDagPath         meshDagPath = new MDagPath();
            MDGModifier      modifier    = new MDGModifier();
            MFnSet           set         = new MFnSet();

            for (int i = 0; i < this.Indices.Count / 3; i++)
            {
                polygonIndexCounts[i] = 3;
            }

            for (int i = 0; i < this.Indices.Count; i++)
            {
                polygonIndices[i] = this.Indices[i];
            }

            for (int i = 0; i < this.Vertices.Count; i++)
            {
                SKNVertex vertex = this.Vertices[i];

                vertices[i]      = new MFloatPoint(vertex.Position.X, vertex.Position.Y, vertex.Position.Z);
                arrayU[i]        = vertex.UV.X;
                arrayV[i]        = 1 - vertex.UV.Y;
                normals[i]       = new MVector(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z);
                normalIndices[i] = i;
            }

            //Assign mesh data
            mesh.create(this.Vertices.Count, this.Indices.Count / 3, vertices, polygonIndexCounts, polygonIndices, arrayU, arrayV, MObject.kNullObj);
            mesh.setVertexNormals(normals, normalIndices);
            mesh.getPath(meshDagPath);
            mesh.assignUVs(polygonIndexCounts, polygonIndices);

            //Set names
            mesh.setName(name);
            MFnTransform transformNode = new MFnTransform(mesh.parent(0));

            transformNode.setName("transform_" + name);

            //Get render partition
            MGlobal.displayInfo("SKNFile:Load - Searching for Render Partition");
            MItDependencyNodes itDependencyNodes = new MItDependencyNodes(MFn.Type.kPartition);
            MFnPartition       renderPartition   = new MFnPartition();
            bool foundRenderPartition            = false;

            for (; !itDependencyNodes.isDone; itDependencyNodes.next())
            {
                renderPartition.setObject(itDependencyNodes.thisNode);
                MGlobal.displayInfo("SKNFile:Load - Iterating through partition: " + renderPartition.name + " IsRenderPartition: " + renderPartition.isRenderPartition);
                if (renderPartition.name == "renderPartition" && renderPartition.isRenderPartition)
                {
                    MGlobal.displayInfo("SKNFile:Load - Found render partition");
                    foundRenderPartition = true;
                    break;
                }
            }


            //Create Materials
            for (int i = 0; i < this.Submeshes.Count; i++)
            {
                MFnDependencyNode dependencyNode = new MFnDependencyNode();
                MFnLambertShader  lambertShader  = new MFnLambertShader();
                SKNSubmesh        submesh        = this.Submeshes[i];
                MObject           shader         = lambertShader.create(true);

                lambertShader.setName(submesh.Name);
                lambertShader.color = MaterialProvider.GetMayaColor(i);

                MObject shadingEngine = dependencyNode.create("shadingEngine", submesh.Name + "_SG");
                MObject materialInfo  = dependencyNode.create("materialInfo", submesh.Name + "_MaterialInfo");
                if (foundRenderPartition)
                {
                    MPlug partitionPlug = new MFnDependencyNode(shadingEngine).findPlug("partition");
                    MPlug setsPlug      = MayaHelper.FindFirstNotConnectedElement(renderPartition.findPlug("sets"));
                    modifier.connect(partitionPlug, setsPlug);
                }
                else
                {
                    MGlobal.displayInfo("SKNFile:Load - Couldn't find Render Partition for mesh: " + name + "." + submesh.Name);
                }

                MPlug outColorPlug      = lambertShader.findPlug("outColor");
                MPlug surfaceShaderPlug = new MFnDependencyNode(shadingEngine).findPlug("surfaceShader");
                modifier.connect(outColorPlug, surfaceShaderPlug);

                MPlug messagePlug      = new MFnDependencyNode(shadingEngine).findPlug("message");
                MPlug shadingGroupPlug = new MFnDependencyNode(materialInfo).findPlug("shadingGroup");
                modifier.connect(messagePlug, shadingGroupPlug);

                modifier.doIt();

                MFnSingleIndexedComponent component = new MFnSingleIndexedComponent();
                MObject   faceComponent             = component.create(MFn.Type.kMeshPolygonComponent);
                MIntArray groupPolygonIndices       = new MIntArray();
                uint      endIndex = (submesh.StartIndex + submesh.IndexCount) / 3;
                for (uint j = submesh.StartIndex / 3; j < endIndex; j++)
                {
                    groupPolygonIndices.append((int)j);
                }
                component.addElements(groupPolygonIndices);

                set.setObject(shadingEngine);
                set.addMember(meshDagPath, faceComponent);
            }

            if (skl == null)
            {
                mesh.updateSurface();
            }
            else
            {
                MFnSkinCluster skinCluster             = new MFnSkinCluster();
                MSelectionList jointPathsSelectionList = new MSelectionList();

                jointPathsSelectionList.add(meshDagPath);
                for (int i = 0; i < skl.Influences.Count; i++)
                {
                    short    jointIndex = skl.Influences[i];
                    SKLJoint joint      = skl.Joints[jointIndex];
                    jointPathsSelectionList.add(skl.JointDagPaths[jointIndex]);

                    MGlobal.displayInfo(string.Format("SKNFile:Load:Bind - Added joint [{0}] {1} to binding selection", joint.ID, joint.Name));
                }

                MGlobal.selectCommand(jointPathsSelectionList);
                MGlobal.executeCommand("skinCluster -mi 4 -tsb -n skinCluster_" + name);

                MPlug      inMeshPlug        = mesh.findPlug("inMesh");
                MPlugArray inMeshConnections = new MPlugArray();
                inMeshPlug.connectedTo(inMeshConnections, true, false);

                if (inMeshConnections.length == 0)
                {
                    MGlobal.displayError("SKNFile:Load:Bind - Failed to find the created Skin Cluster");
                    throw new Exception("SKNFile:Load:Bind - Failed to find the created Skin Cluster");
                }

                MPlug         outputGeometryPlug = inMeshConnections[0];
                MDagPathArray influencesDagPaths = new MDagPathArray();

                skinCluster.setObject(outputGeometryPlug.node);
                skinCluster.influenceObjects(influencesDagPaths);

                MIntArray influenceIndices = new MIntArray((uint)skl.Influences.Count);
                for (int i = 0; i < skl.Influences.Count; i++)
                {
                    MDagPath influencePath = skl.JointDagPaths[skl.Influences[i]];

                    for (int j = 0; j < skl.Influences.Count; j++)
                    {
                        if (influencesDagPaths[j].partialPathName == influencePath.partialPathName)
                        {
                            influenceIndices[i] = j;
                            MGlobal.displayInfo("SKNReader:Load:Bind - Added Influence Joint: " + i + " -> " + j);
                            break;
                        }
                    }
                }

                MFnSingleIndexedComponent singleIndexedComponent = new MFnSingleIndexedComponent();
                MObject   vertexComponent    = singleIndexedComponent.create(MFn.Type.kMeshVertComponent);
                MIntArray groupVertexIndices = new MIntArray((uint)this.Vertices.Count);

                for (int i = 0; i < this.Vertices.Count; i++)
                {
                    groupVertexIndices[i] = i;
                }
                singleIndexedComponent.addElements(groupVertexIndices);

                MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 0", skinCluster.name));

                MDoubleArray weights = new MDoubleArray((uint)(this.Vertices.Count * skl.Influences.Count));
                for (int i = 0; i < this.Vertices.Count; i++)
                {
                    SKNVertex vertex = this.Vertices[i];

                    for (int j = 0; j < 4; j++)
                    {
                        double weight    = vertex.Weights[j];
                        int    influence = vertex.BoneIndices[j];

                        if (weight != 0)
                        {
                            weights[(i * skl.Influences.Count) + influence] = weight;
                        }
                    }
                }

                skinCluster.setWeights(meshDagPath, vertexComponent, influenceIndices, weights, false);
                MGlobal.executeCommand(string.Format("setAttr {0}.normalizeWeights 1", skinCluster.name));
                MGlobal.executeCommand(string.Format("skinPercent -normalize true {0} {1}", skinCluster.name, mesh.name));
                mesh.updateSurface();
            }
        }
예제 #9
0
        public void Create(SKLFile skl)
        {
            MSelectionList   currentSelection         = MGlobal.activeSelectionList;
            MItSelectionList currentSelectionIterator = new MItSelectionList(currentSelection, MFn.Type.kMesh);
            MDagPath         meshDagPath = new MDagPath();

            if (currentSelectionIterator.isDone)
            {
                MGlobal.displayError("SKNFile:Create - No mesh selected!");
                throw new Exception("SKNFile:Create - No mesh selected!");
            }
            else
            {
                currentSelectionIterator.getDagPath(meshDagPath);
                currentSelectionIterator.next();

                if (!currentSelectionIterator.isDone)
                {
                    MGlobal.displayError("SKNFile:Create - More than one mesh selected!");
                    throw new Exception("SKNFile:Create - More than one mesh selected!");
                }
            }

            MFnMesh mesh = new MFnMesh(meshDagPath);

            //Find Skin Cluster
            MPlug      inMeshPlug        = mesh.findPlug("inMesh");
            MPlugArray inMeshConnections = new MPlugArray();

            inMeshPlug.connectedTo(inMeshConnections, true, false);
            if (inMeshConnections.length == 0)
            {
                MGlobal.displayError("SKNFile:Create - Failed to find Skin Cluster!");
                throw new Exception("SKNFile:Create - Failed to find Skin Cluster!");
            }

            MPlug          outputGeometryPlug = inMeshConnections[0];
            MFnSkinCluster skinCluster        = new MFnSkinCluster(outputGeometryPlug.node);
            MDagPathArray  influenceDagPaths  = new MDagPathArray();
            uint           influenceCount     = skinCluster.influenceObjects(influenceDagPaths);

            MGlobal.displayInfo("SKNFile:Create - Influence Count: " + influenceCount);

            //Get SKL Influence Indices
            MIntArray sklInfluenceIndices = new MIntArray(influenceCount);

            for (int i = 0; i < influenceCount; i++)
            {
                MDagPath jointDagPath = influenceDagPaths[i];

                MGlobal.displayInfo(jointDagPath.fullPathName);

                //Loop through Joint DAG Paths, if we find a math for the influence, write the index
                for (int j = 0; j < skl.JointDagPaths.Count; j++)
                {
                    if (jointDagPath.equalEqual(skl.JointDagPaths[j]))
                    {
                        MGlobal.displayInfo("Found coresponding DAG path");
                        sklInfluenceIndices[i] = j;
                        break;
                    }
                }
            }

            //Add Influence indices to SKL File
            MIntArray maskInfluenceIndex = new MIntArray(influenceCount);

            for (int i = 0; i < influenceCount; i++)
            {
                maskInfluenceIndex[i] = i;
                skl.Influences.Add((short)sklInfluenceIndices[i]);
            }

            MObjectArray shaders = new MObjectArray();
            MIntArray    polygonShaderIndices = new MIntArray();

            mesh.getConnectedShaders(meshDagPath.isInstanced ? meshDagPath.instanceNumber : 0, shaders, polygonShaderIndices);

            uint shaderCount = shaders.length;

            if (shaderCount > 32) //iirc 32 is the limit of how many submeshes there can be for an SKN file
            {
                MGlobal.displayError("SKNFile:Create - You've exceeded the maximum limit of 32 shaders");
                throw new Exception("SKNFile:Create - You've exceeded the maximum limit of 32 shaders");
            }

            MIntArray vertexShaders = new MIntArray();

            ValidateMeshTopology(mesh, meshDagPath, polygonShaderIndices, ref vertexShaders, shaderCount);

            //Get Weights
            MFnSingleIndexedComponent vertexIndexedComponent = new MFnSingleIndexedComponent();
            MObject   vertexComponent    = vertexIndexedComponent.create(MFn.Type.kMeshVertComponent);
            MIntArray groupVertexIndices = new MIntArray((uint)mesh.numVertices);

            for (int i = 0; i < mesh.numVertices; i++)
            {
                groupVertexIndices[i] = i;
            }
            vertexIndexedComponent.addElements(groupVertexIndices);

            MDoubleArray weights = new MDoubleArray();
            uint         weightsInfluenceCount = 0;

            skinCluster.getWeights(meshDagPath, vertexComponent, weights, ref weightsInfluenceCount);

            //Check if vertices don't have more than 4 influences and normalize weights
            for (int i = 0; i < mesh.numVertices; i++)
            {
                int    vertexInfluenceCount = 0;
                double weightSum            = 0;
                for (int j = 0; j < weightsInfluenceCount; j++)
                {
                    double weight = weights[(int)(i * weightsInfluenceCount) + j];
                    if (weight != 0)
                    {
                        vertexInfluenceCount++;
                        weightSum += weight;
                    }
                }

                if (vertexInfluenceCount > 4)
                {
                    MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with more than 4 influences");
                    throw new Exception("SKNFile:Create - Mesh contains a vertex with more than 4 influences");
                }

                //Normalize weights
                for (int j = 0; j < weightsInfluenceCount; j++)
                {
                    weights[(int)(i * influenceCount) + j] /= weightSum;
                }
            }

            List <MIntArray>         shaderVertexIndices = new List <MIntArray>();
            List <List <SKNVertex> > shaderVertices      = new List <List <SKNVertex> >();
            List <MIntArray>         shaderIndices       = new List <MIntArray>();

            for (int i = 0; i < shaderCount; i++)
            {
                shaderVertexIndices.Add(new MIntArray());
                shaderVertices.Add(new List <SKNVertex>());
                shaderIndices.Add(new MIntArray());
            }

            MItMeshVertex meshVertexIterator = new MItMeshVertex(meshDagPath);

            for (meshVertexIterator.reset(); !meshVertexIterator.isDone; meshVertexIterator.next())
            {
                int index  = meshVertexIterator.index();
                int shader = vertexShaders[index];
                if (shader == -1)
                {
                    MGlobal.displayWarning("SKNFile:Create - Mesh contains a vertex with no shader");
                    continue;
                }

                MPoint       pointPosition = meshVertexIterator.position(MSpace.Space.kWorld);
                Vector3      position      = new Vector3((float)pointPosition.x, (float)pointPosition.y, (float)pointPosition.z);
                MVectorArray normals       = new MVectorArray();
                MIntArray    uvIndices     = new MIntArray();
                Vector3      normal        = new Vector3();
                byte[]       weightIndices = new byte[4];
                float[]      vertexWeights = new float[4];

                meshVertexIterator.getNormals(normals);

                //Normalize normals
                for (int i = 0; i < normals.length; i++)
                {
                    normal.X += (float)normals[i].x;
                    normal.Y += (float)normals[i].y;
                    normal.Z += (float)normals[i].z;
                }

                normal.X /= normals.length;
                normal.Y /= normals.length;
                normal.Z /= normals.length;

                //Get Weight Influences and Weights
                int weightsFound = 0;
                for (int j = 0; j < weightsInfluenceCount && weightsFound < 4; j++)
                {
                    double weight = weights[(int)(index * weightsInfluenceCount) + j];

                    if (weight != 0)
                    {
                        weightIndices[weightsFound] = (byte)maskInfluenceIndex[j];
                        vertexWeights[weightsFound] = (float)weight;
                        weightsFound++;
                    }
                }

                //Get unique UVs
                meshVertexIterator.getUVIndices(uvIndices);
                if (uvIndices.length != 0)
                {
                    List <int> seen = new List <int>();
                    for (int j = 0; j < uvIndices.length; j++)
                    {
                        int uvIndex = uvIndices[j];
                        if (!seen.Contains(uvIndex))
                        {
                            seen.Add(uvIndex);

                            float u = 0;
                            float v = 0;
                            mesh.getUV(uvIndex, ref u, ref v);

                            SKNVertex vertex = new SKNVertex(position, weightIndices, vertexWeights, normal, new Vector2(u, 1 - v));
                            vertex.UVIndex = uvIndex;

                            shaderVertices[shader].Add(vertex);
                            shaderVertexIndices[shader].append(index);
                        }
                    }
                }
                else
                {
                    MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with no UVs");
                    throw new Exception("SKNFile:Create - Mesh contains a vertex with no UVs");
                }
            }

            //Convert from Maya indices to data indices
            int       currentIndex = 0;
            MIntArray dataIndices  = new MIntArray((uint)mesh.numVertices, -1);

            for (int i = 0; i < shaderCount; i++)
            {
                for (int j = 0; j < shaderVertexIndices[i].length; j++)
                {
                    int index = shaderVertexIndices[i][j];
                    if (dataIndices[index] == -1)
                    {
                        dataIndices[index]             = currentIndex;
                        shaderVertices[i][j].DataIndex = currentIndex;
                    }
                    else
                    {
                        shaderVertices[i][j].DataIndex = dataIndices[index];
                    }

                    currentIndex++;
                }

                this.Vertices.AddRange(shaderVertices[i]);
            }

            MItMeshPolygon polygonIterator = new MItMeshPolygon(meshDagPath);

            for (polygonIterator.reset(); !polygonIterator.isDone; polygonIterator.next())
            {
                int polygonIndex = (int)polygonIterator.index();
                int shaderIndex  = polygonShaderIndices[polygonIndex];

                MIntArray   indices = new MIntArray();
                MPointArray points  = new MPointArray();
                polygonIterator.getTriangles(points, indices);

                if (polygonIterator.hasUVsProperty)
                {
                    MIntArray vertices   = new MIntArray();
                    MIntArray newIndices = new MIntArray(indices.length, -1);
                    polygonIterator.getVertices(vertices);

                    for (int i = 0; i < vertices.length; i++)
                    {
                        int dataIndex = dataIndices[vertices[i]];
                        int uvIndex;
                        polygonIterator.getUVIndex(i, out uvIndex);

                        if (dataIndex == -1 || dataIndex >= this.Vertices.Count)
                        {
                            MGlobal.displayError("SKNFIle:Create - Data Index outside of range");
                            throw new Exception("SKNFIle:Create - Data Index outside of range");
                        }

                        for (int j = dataIndex; j < this.Vertices.Count; j++)
                        {
                            if (this.Vertices[j].DataIndex != dataIndex)
                            {
                                MGlobal.displayError("SKNFIle:Create - Can't find corresponding face vertex in data");
                                throw new Exception("SKNFIle:Create - Can't find corresponding face vertex in data");
                            }
                            else if (this.Vertices[j].UVIndex == uvIndex)
                            {
                                for (int k = 0; k < indices.length; k++)
                                {
                                    if (indices[k] == vertices[i])
                                    {
                                        newIndices[k] = j;
                                    }
                                }

                                break;
                            }
                        }
                    }

                    for (int i = 0; i < newIndices.length; i++)
                    {
                        shaderIndices[shaderIndex].append(newIndices[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < indices.length; i++)
                    {
                        shaderIndices[shaderIndex].append(dataIndices[indices[i]]);
                    }
                }
            }

            uint startIndex  = 0;
            uint startVertex = 0;

            for (int i = 0; i < shaderCount; i++)
            {
                MPlug      shaderPlug = new MFnDependencyNode(shaders[i]).findPlug("surfaceShader");
                MPlugArray plugArray  = new MPlugArray();
                shaderPlug.connectedTo(plugArray, true, false);

                string name        = new MFnDependencyNode(plugArray[0].node).name;
                uint   indexCount  = shaderIndices[i].length;
                uint   vertexCount = shaderVertexIndices[i].length;

                //Copy indices to SKLFile
                for (int j = 0; j < indexCount; j++)
                {
                    this.Indices.Add((ushort)shaderIndices[i][j]);
                }

                this.Submeshes.Add(new SKNSubmesh(name, startVertex, vertexCount, startIndex, indexCount));

                startIndex  += indexCount;
                startVertex += vertexCount;
            }

            MGlobal.displayInfo("SKNFile:Create - Created SKN File");
        }
예제 #10
0
        //
        // Description:
        //
        //     Vertex selection.
        //
        // Arguments:
        //
        //     selectInfo           - the selection state information
        //     selectionList        - the list of selected items to add to
        //     worldSpaceSelectPts  -
        //
        public bool selectVertices( MSelectInfo selectInfo,
            MSelectionList selectionList,
            MPointArray worldSpaceSelectPts)
        {
            bool selected = false;
            M3dView view = selectInfo.view;

            MPoint xformedPoint = new MPoint();
            MPoint selectionPoint = new MPoint();
            double z = 0.0;
            double previousZ = 0.0;
             			int closestPointVertexIndex = -1;

            MDagPath path = selectInfo.multiPath;

            // Create a component that will store the selected vertices
            //
            MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent();
            MObject surfaceComponent = fnComponent.create( MFn.Type.kMeshVertComponent );
            uint vertexIndex;

            // if the user did a single mouse click and we find > 1 selection
            // we will use the alignmentMatrix to find out which is the closest
            //
            MMatrix alignmentMatrix = new MMatrix();
            MPoint singlePoint = new MPoint();
            bool singleSelection = selectInfo.singleSelection;
            if( singleSelection ) {
                alignmentMatrix = selectInfo.alignmentMatrix;
            }

            // Get the geometry information
            //
            apiMesh meshNode = (apiMesh)surfaceShape;
            apiMeshGeom geom = meshNode.meshGeom();

            // Loop through all vertices of the mesh and
            // see if they lie withing the selection area
            //
            uint numVertices = geom.vertices.length;
            for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ )
            {
                MPoint currentPoint = geom.vertices[ (int)vertexIndex ];

                // Sets OpenGL's render mode to select and stores
                // selected items in a pick buffer
                //
                view.beginSelect();

                OpenGL.glBegin(OpenGL.GL_POINTS);
                OpenGL.glVertex3f((float)currentPoint[0],
                            (float)currentPoint[1],
                            (float)currentPoint[2] );
                OpenGL.glEnd();

                if ( view.endSelect() > 0 )	// Hit count > 0
                {
                    selected = true;

                    if ( singleSelection ) {
                        xformedPoint = currentPoint;
                        xformedPoint.homogenize();
                        xformedPoint.multiplyEqual( alignmentMatrix );
                        z = xformedPoint.z;
                        if ( closestPointVertexIndex < 0 || z > previousZ ) {
                            closestPointVertexIndex = (int)vertexIndex;
                            singlePoint = currentPoint;
                            previousZ = z;
                        }
                    } else {
                        // multiple selection, store all elements
                        //
                        fnComponent.addElement( (int)vertexIndex );
                    }
                }
            }

            // If single selection, insert the closest point into the array
            //
            if ( selected && selectInfo.singleSelection ) {
                fnComponent.addElement(closestPointVertexIndex);

                // need to get world space position for this vertex
                //
                selectionPoint = singlePoint;
                selectionPoint.multiplyEqual( path.inclusiveMatrix );
            }

            // Add the selected component to the selection list
            //
            if ( selected ) {
                MSelectionList selectionItem = new MSelectionList();
                selectionItem.add( path, surfaceComponent );

                MSelectionMask mask = new MSelectionMask( MSelectionMask.SelectionType.kSelectComponentsMask );
                selectInfo.addSelection(
                    selectionItem, selectionPoint,
                    selectionList, worldSpaceSelectPts,
                    mask, true );
            }

            return selected;
        }
예제 #11
0
        public bool selectVertices(MSelectInfo selectInfo,
                                   MSelectionList selectionList,
                                   MPointArray worldSpaceSelectPts)
        //
        // Description:
        //
        //     Vertex selection.
        //
        // Arguments:
        //
        //     selectInfo           - the selection state information
        //     selectionList        - the list of selected items to add to
        //     worldSpaceSelectPts  -
        //
        {
            bool    selected = false;
            M3dView view     = selectInfo.view;

            MPoint xformedPoint   = new MPoint();
            MPoint selectionPoint = new MPoint();
            double z         = 0.0;
            double previousZ = 0.0;
            int    closestPointVertexIndex = -1;

            MDagPath path = selectInfo.multiPath;

            // Create a component that will store the selected vertices
            //
            MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent();
            MObject surfaceComponent = fnComponent.create(MFn.Type.kMeshVertComponent);
            uint    vertexIndex;

            // if the user did a single mouse click and we find > 1 selection
            // we will use the alignmentMatrix to find out which is the closest
            //
            MMatrix alignmentMatrix = new MMatrix();
            MPoint  singlePoint     = new MPoint();
            bool    singleSelection = selectInfo.singleSelection;

            if (singleSelection)
            {
                alignmentMatrix = selectInfo.alignmentMatrix;
            }

            // Get the geometry information
            //
            apiMesh     meshNode = (apiMesh)surfaceShape;
            apiMeshGeom geom     = meshNode.meshGeom();

            // Loop through all vertices of the mesh and
            // see if they lie withing the selection area
            //
            uint numVertices = geom.vertices.length;

            for (vertexIndex = 0; vertexIndex < numVertices; vertexIndex++)
            {
                MPoint currentPoint = geom.vertices[(int)vertexIndex];

                // Sets OpenGL's render mode to select and stores
                // selected items in a pick buffer
                //
                view.beginSelect();

                OpenGL.glBegin(OpenGL.GL_POINTS);
                OpenGL.glVertex3f((float)currentPoint[0],
                                  (float)currentPoint[1],
                                  (float)currentPoint[2]);
                OpenGL.glEnd();

                if (view.endSelect() > 0)                       // Hit count > 0
                {
                    selected = true;

                    if (singleSelection)
                    {
                        xformedPoint = currentPoint;
                        xformedPoint.homogenize();
                        xformedPoint.multiplyEqual(alignmentMatrix);
                        z = xformedPoint.z;
                        if (closestPointVertexIndex < 0 || z > previousZ)
                        {
                            closestPointVertexIndex = (int)vertexIndex;
                            singlePoint             = currentPoint;
                            previousZ = z;
                        }
                    }
                    else
                    {
                        // multiple selection, store all elements
                        //
                        fnComponent.addElement((int)vertexIndex);
                    }
                }
            }

            // If single selection, insert the closest point into the array
            //
            if (selected && selectInfo.singleSelection)
            {
                fnComponent.addElement(closestPointVertexIndex);

                // need to get world space position for this vertex
                //
                selectionPoint = singlePoint;
                selectionPoint.multiplyEqual(path.inclusiveMatrix);
            }

            // Add the selected component to the selection list
            //
            if (selected)
            {
                MSelectionList selectionItem = new MSelectionList();
                selectionItem.add(path, surfaceComponent);

                MSelectionMask mask = new MSelectionMask(MSelectionMask.SelectionType.kSelectComponentsMask);
                selectInfo.addSelection(
                    selectionItem, selectionPoint,
                    selectionList, worldSpaceSelectPts,
                    mask, true);
            }

            return(selected);
        }