Пример #1
0
        public override void writeDoubleVectorArray(MVectorArray array)
        {
            if (myCurrentChanelNode != null)
            {
                uint    size     = array.length;
                XmlNode sizeNode = myXmlDoc.CreateElement(sizeTag);
                sizeNode.InnerText = Convert.ToString(size);
                myCurrentChanelNode.AppendChild(sizeNode);

                XmlNode arrayNode = myXmlDoc.CreateElement(doubleVectorArrayTag);
                myCurrentChanelNode.AppendChild(arrayNode);

                for (int i = 0; i < size; i++)
                {
                    MVector value     = array[i];
                    XmlNode valueNode = myXmlDoc.CreateElement("value");
                    arrayNode.AppendChild(valueNode);

                    XmlNode xValueNode = myXmlDoc.CreateElement("x");
                    xValueNode.InnerText = Convert.ToString(value.x);
                    valueNode.AppendChild(xValueNode);

                    XmlNode yValueNode = myXmlDoc.CreateElement("y");
                    yValueNode.InnerText = Convert.ToString(value.y);
                    valueNode.AppendChild(yValueNode);

                    XmlNode zValueNode = myXmlDoc.CreateElement("z");
                    zValueNode.InnerText = Convert.ToString(value.z);
                    valueNode.AppendChild(zValueNode);
                }
            }

            return;
        }
Пример #2
0
        public override void readDoubleVectorArray(MVectorArray array, uint arraySize)
        {
            Trace.Assert(myCurrentChanelNode != null);

            XmlNode     doubleVectorArrayNode = myCurrentChanelNode.SelectSingleNode(doubleVectorArrayTag);
            XmlNodeList valueNodeList         = doubleVectorArrayNode.SelectNodes("value");
            uint        i = 0;

            array.clear();
            array.length = arraySize;
            foreach (XmlNode valueNode in valueNodeList)
            {
                XmlNode xNode  = valueNode.SelectSingleNode("x");
                double  valueX = Convert.ToDouble(xNode.InnerText);

                XmlNode yNode  = valueNode.SelectSingleNode("y");
                double  valuey = Convert.ToDouble(yNode.InnerText);

                XmlNode zNode  = valueNode.SelectSingleNode("z");
                double  valuez = Convert.ToDouble(zNode.InnerText);

                MVector v = new MVector(valueX, valuey, valuez);
                array.set(v, i);
                i++;
            }
            return;
        }
Пример #3
0
 public apiMeshGeom()
 {
     vertices      = new MPointArray();
     face_counts   = new MIntArray();
     face_connects = new MIntArray();
     normals       = new MVectorArray();
     uvcoords      = new apiMeshGeomUV();
     faceCount     = 0;
 }
Пример #4
0
		public apiMeshGeom()
		{
			vertices = new MPointArray();
			face_counts = new MIntArray();
			face_connects = new MIntArray();
			normals = new MVectorArray();
			uvcoords = new apiMeshGeomUV();
			faceCount = 0;
		}
Пример #5
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);
        }
Пример #6
0
        //
        // Description
        //
        //    Constructs a cube
        //
        public void buildCube(double cube_size,
                              MPointArray pa,
                              MIntArray faceCounts,
                              MIntArray faceConnects,
                              MVectorArray normals,
                              apiMeshGeomUV uvs)
        {
            const int    num_faces         = 6;
            const int    num_face_connects = 24;
            const double normal_value      = 0.5775;
            const int    uv_count          = 14;

            pa.clear();
            faceCounts.clear();
            faceConnects.clear();
            uvs.reset();

            pa.append(new MPoint(-cube_size, -cube_size, -cube_size));
            pa.append(new MPoint(cube_size, -cube_size, -cube_size));
            pa.append(new MPoint(cube_size, -cube_size, cube_size));
            pa.append(new MPoint(-cube_size, -cube_size, cube_size));
            pa.append(new MPoint(-cube_size, cube_size, -cube_size));
            pa.append(new MPoint(-cube_size, cube_size, cube_size));
            pa.append(new MPoint(cube_size, cube_size, cube_size));
            pa.append(new MPoint(cube_size, cube_size, -cube_size));

            normals.append(new MVector(-normal_value, -normal_value, -normal_value));
            normals.append(new MVector(normal_value, -normal_value, -normal_value));
            normals.append(new MVector(normal_value, -normal_value, normal_value));
            normals.append(new MVector(-normal_value, -normal_value, normal_value));
            normals.append(new MVector(-normal_value, normal_value, -normal_value));
            normals.append(new MVector(-normal_value, normal_value, normal_value));
            normals.append(new MVector(normal_value, normal_value, normal_value));
            normals.append(new MVector(normal_value, normal_value, -normal_value));

            // Define the UVs for the cube.
            //
            float[] uv_pts = new float[uv_count * 2] {
                0.375f, 0.0f,
                0.625f, 0.0f,
                0.625f, 0.25f,
                0.375f, 0.25f,
                0.625f, 0.5f,
                0.375f, 0.5f,
                0.625f, 0.75f,
                0.375f, 0.75f,
                0.625f, 1.0f,
                0.375f, 1.0f,
                0.875f, 0.0f,
                0.875f, 0.25f,
                0.125f, 0.0f,
                0.125f, 0.25f
            };

            // UV Face Vertex Id.
            //
            int[] uv_fvid = new int[num_face_connects] {
                0, 1, 2, 3,
                3, 2, 4, 5,
                5, 4, 6, 7,
                7, 6, 8, 9,
                1, 10, 11, 2,
                12, 0, 3, 13
            };

            int i;

            for (i = 0; i < uv_count; i++)
            {
                uvs.append_uv(uv_pts[i * 2], uv_pts[i * 2 + 1]);
            }

            for (i = 0; i < num_face_connects; i++)
            {
                uvs.faceVertexIndex.append(uv_fvid[i]);
            }

            // Set up an array containing the number of vertices
            // for each of the 6 cube faces (4 vertices per face)
            //
            int[] face_counts = new int[num_faces] {
                4, 4, 4, 4, 4, 4
            };

            for (i = 0; i < num_faces; i++)
            {
                faceCounts.append(face_counts[i]);
            }

            // Set up and array to assign vertices from pa to each face
            //
            int[] face_connects = new int[num_face_connects] {
                0, 1, 2, 3,
                4, 5, 6, 7,
                3, 2, 6, 5,
                0, 3, 5, 4,
                0, 4, 7, 1,
                1, 7, 6, 2
            };
            for (i = 0; i < num_face_connects; i++)
            {
                faceConnects.append(face_connects[i]);
            }
        }
Пример #7
0
		public override bool compute(MPlug plug, MDataBlock dataBlock)
		//
		//	Descriptions:
		//		compute output force.
		//
		{
			if (plug.notEqual(mOutputForce))
                return false;

			// get the logical index of the element this plug refers to.
			//
			uint multiIndex = plug.logicalIndex;

			// Get input data handle, use outputArrayValue since we do not
			// want to evaluate both inputs, only the one related to the
			// requested multiIndex. Evaluating both inputs at once would cause
			// a dependency graph loop.

			MArrayDataHandle hInputArray = dataBlock.outputArrayValue(mInputData);
			hInputArray.jumpToElement(multiIndex);

			// get children of aInputData.

			MDataHandle hCompond = hInputArray.inputValue();

			MDataHandle hPosition = hCompond.child(mInputPositions);
			MObject dPosition = hPosition.data();
			MFnVectorArrayData fnPosition = new MFnVectorArrayData(dPosition);
			MVectorArray points = fnPosition.array();

			// The attribute mInputPPData contains the attribute in an array form 
			// prepared by the particleShape if the particleShape has per particle 
			// attribute fieldName_attrName.  
			//
			// Suppose a field with the name dynExprField1 is connecting to 
			// particleShape1, and the particleShape1 has per particle float attribute
			// dynExprField1_magnitude and vector attribute dynExprField1_direction,
			// then hInputPPArray will contains a MdoubleArray with the corresponding
			// name "magnitude" and a MvectorArray with the name "direction".  This 
			// is a mechanism to allow the field attributes being driven by dynamic 
			// expression.
			MArrayDataHandle mhInputPPData = dataBlock.inputArrayValue(mInputPPData);
			mhInputPPData.jumpToElement(multiIndex);
			
			MDataHandle hInputPPData = mhInputPPData.inputValue();
			MObject dInputPPData = hInputPPData.data();
			MFnArrayAttrsData inputPPArray = new MFnArrayAttrsData(dInputPPData);

			MDataHandle hOwnerPPData = dataBlock.inputValue(mOwnerPPData);
			MObject dOwnerPPData = hOwnerPPData.data();
			MFnArrayAttrsData ownerPPArray = new MFnArrayAttrsData(dOwnerPPData);

			string magString = "magnitude";
			MFnArrayAttrsData.Type doubleType = MFnArrayAttrsData.Type.kDoubleArray;

			bool arrayExist;
			MDoubleArray magnitudeArray;
			arrayExist = inputPPArray.checkArrayExist(magString, out doubleType);
            if (arrayExist)
            {
                magnitudeArray = inputPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeArray = new MDoubleArray();
            }
		   
			MDoubleArray magnitudeOwnerArray;
			arrayExist = ownerPPArray.checkArrayExist(magString, out doubleType);
			if (arrayExist)
			{
				magnitudeOwnerArray = ownerPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeOwnerArray = new MDoubleArray();
            }

			string dirString = "direction";
			MFnArrayAttrsData.Type vectorType = MFnArrayAttrsData.Type.kVectorArray;
			MVectorArray directionArray;
			arrayExist = inputPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionArray = inputPPArray.getVectorData(dirString);
            }
            else
            {
                directionArray = new MVectorArray();
            }
		 
			MVectorArray directionOwnerArray;
			arrayExist = ownerPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionOwnerArray = ownerPPArray.getVectorData(dirString);
            }
            else
            {
                directionOwnerArray = new MVectorArray();
            }

			// Compute the output force.
			//
			MVectorArray forceArray = new MVectorArray();

			apply(dataBlock, points.length, magnitudeArray, magnitudeOwnerArray,
				   directionArray, directionOwnerArray, forceArray);

			// get output data handle
			//
			MArrayDataHandle hOutArray = dataBlock.outputArrayValue(mOutputForce);
			MArrayDataBuilder bOutArray = hOutArray.builder();

			// get output force array from block.
			//
			MDataHandle hOut = bOutArray.addElement(multiIndex);
			MFnVectorArrayData fnOutputForce = new MFnVectorArrayData();
			MObject dOutputForce = fnOutputForce.create(forceArray);

			// update data block with new output force data.
			//
			hOut.set(dOutputForce);
			dataBlock.setClean(plug);

			return true;
		}
Пример #8
0
        public static void ExportXModel(string FilePath, XModelType FileType, bool Siege = false, string Cosmetic = "")
        {
            // Configure scene
            using (var MayaCfg = new MayaSceneConfigure())
            {
                // First, get the current selection
                var ExportObjectList = new MSelectionList();
                MGlobal.getActiveSelectionList(ExportObjectList);

                // If empty, select all joints and meshes
                if (ExportObjectList.length == 0)
                {
                    // Select all joints and meshes
                    MGlobal.executeCommand("string $selected[] = `ls -type joint`; select -r $selected;");
                    MGlobal.executeCommand("string $transforms[] = `ls -tr`;string $polyMeshes[] = `filterExpand -sm 12 $transforms`;select -add $polyMeshes;");

                    // Get it again
                    MGlobal.getActiveSelectionList(ExportObjectList);
                }

                // If still empty, error blank scene
                if (ExportObjectList.length == 0)
                {
                    MGlobal.displayError("[CODTools] The current scene is empty...");
                    return;
                }

                // Progress
                MayaCfg.StartProgress("Exporting XModel...", (int)ExportObjectList.length);

                // Create new model
                var Result = new XModel(System.IO.Path.GetFileNameWithoutExtension(FilePath));
                // Assign siege model flag (Default: false)
                Result.SiegeModel = Siege;

                // Metadata
                var SceneName = string.Empty;
                MGlobal.executeCommand("file -q -sceneName", out SceneName);

                Result.Comments.Add(string.Format("Export filename: '{0}'", FilePath));
                Result.Comments.Add(string.Format("Source filename: '{0}'", SceneName));
                Result.Comments.Add(string.Format("Export time: {0}", DateTime.Now.ToString()));

                // Iterate and add joints
                var ParentStack = new List <string>();
                var UniqueBones = new HashSet <string>();

                foreach (var Joint in ExportObjectList.DependNodes(MFn.Type.kJoint))
                {
                    // Step
                    MayaCfg.StepProgress();

                    // Grab the controller
                    var Path       = GetObjectDagPath(Joint);
                    var Controller = new MFnIkJoint(Path);

                    // Create a new bone
                    var TagName = CleanNodeName(Controller.name);

                    if (UniqueBones.Contains(TagName))
                    {
                        continue;
                    }
                    UniqueBones.Add(TagName);

                    var NewBone = new Bone(TagName);
                    // Add parent
                    ParentStack.Add(GetParentName(Controller));

                    // Fetch the world-space position and rotation
                    var WorldPosition = Controller.getTranslation(MSpace.Space.kWorld);

                    var WorldRotation = new MQuaternion(MQuaternion.identity);
                    Controller.getRotation(WorldRotation, MSpace.Space.kWorld);

                    var WorldScale = new double[3] {
                        1, 1, 1
                    };
                    Controller.getScale(WorldScale);

                    // Create the matrix
                    NewBone.Translation    = WorldPosition * (1 / 2.54);
                    NewBone.Scale          = new MVector(WorldScale[0], WorldScale[1], WorldScale[2]);
                    NewBone.RotationMatrix = WorldRotation.asMatrix;

                    // Add it
                    Result.Bones.Add(NewBone);
                }
                // Sort joints
                SortJoints(ref Result, ParentStack, Cosmetic);

                // Pre-fetch skins
                var SkinClusters = GetSkinClusters();
                var BoneMapping  = Result.GetBoneMapping();

                // A list of used materials
                int MaterialIndex = 0;
                var UsedMaterials = new Dictionary <string, int>();
                var UsedMeshes    = new HashSet <string>();

                // Iterate and add meshes
                foreach (var Mesh in ExportObjectList.DependNodes(MFn.Type.kMesh))
                {
                    // Step
                    MayaCfg.StepProgress();

                    // Grab the controller
                    var Path = GetObjectDagPath(Mesh);
                    Path.extendToShape();
                    var Controller = new MFnMesh(Path);

                    // Ignore duplicates
                    if (UsedMeshes.Contains(Path.partialPathName))
                    {
                        continue;
                    }
                    UsedMeshes.Add(Path.partialPathName);

                    // Pre-fetch materials
                    var MeshMaterials = GetMaterialsMesh(ref Controller, ref Path);
                    foreach (var Mat in MeshMaterials)
                    {
                        if (!UsedMaterials.ContainsKey(Mat.Name))
                        {
                            UsedMaterials.Add(Mat.Name, MaterialIndex++);
                            Result.Materials.Add(Mat);
                        }
                    }

                    // New mesh
                    var NewMesh = new Mesh();

                    // Grab iterators
                    var VertexIterator = new MItMeshVertex(Path);
                    var FaceIterator   = new MItMeshPolygon(Path);

                    // Get the cluster for this
                    var SkinCluster = FindSkinCluster(ref SkinClusters, Controller);
                    var SkinJoints  = new MDagPathArray();

                    if (SkinCluster != null)
                    {
                        SkinCluster.influenceObjects(SkinJoints);
                    }

                    // Build vertex array
                    for (; !VertexIterator.isDone; VertexIterator.next())
                    {
                        // Prepare
                        var NewVert = new Vertex();

                        // Grab data
                        NewVert.Position = VertexIterator.position(MSpace.Space.kWorld) * (1 / 2.54);

                        // Weights if valid
                        if (SkinCluster != null)
                        {
                            var WeightValues = new MDoubleArray();

                            uint Influence = 0;
                            SkinCluster.getWeights(Path, VertexIterator.currentItem(), WeightValues, ref Influence);

                            for (int i = 0; i < (int)WeightValues.length; i++)
                            {
                                if (WeightValues[i] < 0.000001)
                                {
                                    continue;
                                }
                                var WeightTagName = CleanNodeName(SkinJoints[i].partialPathName);
                                var WeightID      = (BoneMapping.ContainsKey(WeightTagName)) ? BoneMapping[WeightTagName] : 0;

                                NewVert.Weights.Add(new Tuple <int, float>(WeightID, (float)WeightValues[i]));
                            }
                        }
                        if (NewVert.Weights.Count == 0)
                        {
                            NewVert.Weights.Add(new Tuple <int, float>(0, 1.0f));
                        }

                        // Add it
                        NewMesh.Vertices.Add(NewVert);
                    }

                    // Build face array
                    for (; !FaceIterator.isDone; FaceIterator.next())
                    {
                        var Indices = new MIntArray();
                        var Normals = new MVectorArray();
                        var UVUs    = new MFloatArray();
                        var UVVs    = new MFloatArray();

                        FaceIterator.getVertices(Indices);
                        FaceIterator.getNormals(Normals, MSpace.Space.kWorld);
                        FaceIterator.getUVs(UVUs, UVVs);

                        // Only support TRIS/QUAD
                        if (Indices.Count < 3)
                        {
                            continue;
                        }

                        if (Indices.Count == 3)
                        {
                            // Create new face
                            var NewFace = new FaceVertex();
                            // Setup
                            NewFace.Indices[0] = Indices[0];
                            NewFace.Indices[2] = Indices[1];
                            NewFace.Indices[1] = Indices[2];

                            // Normals
                            NewFace.Normals[0] = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]);
                            NewFace.Normals[2] = new MVector(Normals[1][0], Normals[1][1], Normals[1][2]);
                            NewFace.Normals[1] = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]);

                            // Colors
                            FaceIterator.getColor(NewFace.Colors[0], 0);
                            FaceIterator.getColor(NewFace.Colors[2], 1);
                            FaceIterator.getColor(NewFace.Colors[1], 2);

                            // Append UV Layers
                            NewFace.UVs[0] = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]);
                            NewFace.UVs[2] = new Tuple <float, float>(UVUs[1], 1 - UVVs[1]);
                            NewFace.UVs[1] = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]);

                            // Set material index
                            if (MeshMaterials.Count > 0)
                            {
                                NewFace.MaterialIndex = UsedMaterials[MeshMaterials[0].Name];
                            }

                            // Add it
                            NewMesh.Faces.Add(NewFace);
                        }
                        else
                        {
                            // Create new faces
                            FaceVertex NewFace = new FaceVertex(), NewFace2 = new FaceVertex();
                            // Setup
                            NewFace.Indices[0]  = Indices[0];
                            NewFace.Indices[2]  = Indices[1];
                            NewFace.Indices[1]  = Indices[2];
                            NewFace2.Indices[0] = Indices[0];
                            NewFace2.Indices[2] = Indices[2];
                            NewFace2.Indices[1] = Indices[3];

                            // Normals
                            NewFace.Normals[0]  = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]);
                            NewFace.Normals[2]  = new MVector(Normals[1][0], Normals[1][1], Normals[1][2]);
                            NewFace.Normals[1]  = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]);
                            NewFace2.Normals[0] = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]);
                            NewFace2.Normals[2] = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]);
                            NewFace2.Normals[1] = new MVector(Normals[3][0], Normals[3][1], Normals[3][2]);

                            // Colors
                            FaceIterator.getColor(NewFace.Colors[0], 0);
                            FaceIterator.getColor(NewFace.Colors[2], 1);
                            FaceIterator.getColor(NewFace.Colors[1], 2);
                            FaceIterator.getColor(NewFace2.Colors[0], 0);
                            FaceIterator.getColor(NewFace2.Colors[2], 2);
                            FaceIterator.getColor(NewFace2.Colors[1], 3);

                            // Append UV Layers
                            NewFace.UVs[0]  = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]);
                            NewFace.UVs[2]  = new Tuple <float, float>(UVUs[1], 1 - UVVs[1]);
                            NewFace.UVs[1]  = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]);
                            NewFace2.UVs[0] = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]);
                            NewFace2.UVs[2] = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]);
                            NewFace2.UVs[1] = new Tuple <float, float>(UVUs[3], 1 - UVVs[3]);

                            // Set material index
                            if (MeshMaterials.Count > 0)
                            {
                                NewFace.MaterialIndex  = UsedMaterials[MeshMaterials[0].Name];
                                NewFace2.MaterialIndex = UsedMaterials[MeshMaterials[0].Name];
                            }

                            // Add it
                            NewMesh.Faces.Add(NewFace);
                            NewMesh.Faces.Add(NewFace2);
                        }
                    }

                    // Add it
                    Result.Meshes.Add(NewMesh);
                }

                // Write
                switch (FileType)
                {
                case XModelType.Export:
                    Result.WriteExport(FilePath);
                    break;

                case XModelType.Bin:
                    Result.WriteBin(FilePath);
                    break;
                }
            }

            // Log complete
            MGlobal.displayInfo(string.Format("[CODTools] Exported {0}", System.IO.Path.GetFileName(FilePath)));
        }
Пример #9
0
		// Support the move tools normal/u/v mode (components)
		//
		public override bool vertexOffsetDirection( MObject component,
													MVectorArray direction,
													MVertexOffsetMode mode,
													bool normalize )
		//
		// Description
		//
		//    Returns offsets for the given components to be used my the
		//    move tool in normal/u/v mode.
		//
		// Arguments
		//
		//    component - components to calculate offsets for
		//    direction - array of offsets to be filled
		//    mode      - the type of offset to be calculated
		//    normalize - specifies whether the offsets should be normalized
		//
		// Returns
		//
		//    true if the offsets could be calculated, false otherwise
		//
		{
			bool offsetOkay = false ;

			MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( component );
			if ( component.apiType != MFn.Type.kMeshVertComponent ) {
				return false;
			}

			offsetOkay = true ;

			apiMeshGeom geomPtr = meshGeom();
			if ( null == geomPtr ) {
				return false;
			}

			// For each vertex add the appropriate offset
			//
			int count = fnComp.elementCount;
			for ( int idx=0; idx<count; idx++ )
			{
				MVector normal = geomPtr.normals[ fnComp.element(idx) ];

				if( mode == MVertexOffsetMode.kNormal ) {
					if( normalize ) normal.normalize() ;
					direction.append( normal );
				}
				else {
					// Construct an orthonormal basis from the normal
					// uAxis, and vAxis are the new vectors.
					//
					MVector uAxis = new MVector();
					MVector vAxis = new MVector();
					uint i, j, k;
					double a;
					normal.normalize();

					i = 0;
					a = Math.Abs( normal[0] );
					if ( a < Math.Abs(normal[1]) )
					{
						i = 1;
						a = Math.Abs(normal[1]);
					}

					if ( a < Math.Abs(normal[2]) )
					{
						i = 2;
					}

					j = (i+1)%3;
					k = (j+1)%3;

					a = Math.Sqrt(normal[i]*normal[i] + normal[j]*normal[j]);
					uAxis[i] = -normal[j]/a;
					uAxis[j] = normal[i]/a;
					uAxis[k] = 0.0;
					vAxis = normal.crossProduct( uAxis );

					if ( mode == MVertexOffsetMode.kUTangent ||
						 mode == MVertexOffsetMode.kUVNTriad )
					{
						if( normalize ) uAxis.normalize() ;
						direction.append( uAxis );
					}

					if ( mode == MVertexOffsetMode.kVTangent ||
						 mode == MVertexOffsetMode.kUVNTriad )
					{
						if( normalize ) vAxis.normalize() ;
						direction.append( vAxis );
					}

					if ( mode == MVertexOffsetMode.kUVNTriad ) {
						if( normalize ) normal.normalize() ;
						direction.append( normal );
					}
				}
			}

			return offsetOkay;
		}
Пример #10
0
        public override void writeDoubleVectorArray(MVectorArray array)
        {
            if (myCurrentChanelNode != null)
            {
                uint size = array.length;
                XmlNode sizeNode = myXmlDoc.CreateElement(sizeTag);
                sizeNode.InnerText = Convert.ToString(size);
                myCurrentChanelNode.AppendChild(sizeNode);

                XmlNode arrayNode = myXmlDoc.CreateElement(doubleVectorArrayTag);
                myCurrentChanelNode.AppendChild(arrayNode);

                for (int i = 0; i < size; i++)
                {
                    MVector value = array[i];
                    XmlNode valueNode = myXmlDoc.CreateElement("value");
                    arrayNode.AppendChild(valueNode);

                    XmlNode xValueNode = myXmlDoc.CreateElement("x");
                    xValueNode.InnerText = Convert.ToString(value.x);
                    valueNode.AppendChild(xValueNode);

                    XmlNode yValueNode = myXmlDoc.CreateElement("y");
                    yValueNode.InnerText = Convert.ToString(value.y);
                    valueNode.AppendChild(yValueNode);

                    XmlNode zValueNode = myXmlDoc.CreateElement("z");
                    zValueNode.InnerText = Convert.ToString(value.z);
                    valueNode.AppendChild(zValueNode);

                }
            }

            return;
        }
Пример #11
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();
            }
        }
Пример #12
0
        public override bool compute(MPlug plug, MDataBlock dataBlock)
        //
        //	Descriptions:
        //		compute output force.
        //
        {
            if (plug.notEqual(mOutputForce))
            {
                return(false);
            }

            // get the logical index of the element this plug refers to.
            //
            uint multiIndex = plug.logicalIndex;

            // Get input data handle, use outputArrayValue since we do not
            // want to evaluate both inputs, only the one related to the
            // requested multiIndex. Evaluating both inputs at once would cause
            // a dependency graph loop.

            MArrayDataHandle hInputArray = dataBlock.outputArrayValue(mInputData);

            hInputArray.jumpToElement(multiIndex);

            // get children of aInputData.

            MDataHandle hCompond = hInputArray.inputValue();

            MDataHandle        hPosition  = hCompond.child(mInputPositions);
            MObject            dPosition  = hPosition.data();
            MFnVectorArrayData fnPosition = new MFnVectorArrayData(dPosition);
            MVectorArray       points     = fnPosition.array();

            // The attribute mInputPPData contains the attribute in an array form
            // prepared by the particleShape if the particleShape has per particle
            // attribute fieldName_attrName.
            //
            // Suppose a field with the name dynExprField1 is connecting to
            // particleShape1, and the particleShape1 has per particle float attribute
            // dynExprField1_magnitude and vector attribute dynExprField1_direction,
            // then hInputPPArray will contains a MdoubleArray with the corresponding
            // name "magnitude" and a MvectorArray with the name "direction".  This
            // is a mechanism to allow the field attributes being driven by dynamic
            // expression.
            MArrayDataHandle mhInputPPData = dataBlock.inputArrayValue(mInputPPData);

            mhInputPPData.jumpToElement(multiIndex);

            MDataHandle       hInputPPData = mhInputPPData.inputValue();
            MObject           dInputPPData = hInputPPData.data();
            MFnArrayAttrsData inputPPArray = new MFnArrayAttrsData(dInputPPData);

            MDataHandle       hOwnerPPData = dataBlock.inputValue(mOwnerPPData);
            MObject           dOwnerPPData = hOwnerPPData.data();
            MFnArrayAttrsData ownerPPArray = new MFnArrayAttrsData(dOwnerPPData);

            string magString = "magnitude";

            MFnArrayAttrsData.Type doubleType = MFnArrayAttrsData.Type.kDoubleArray;

            bool         arrayExist;
            MDoubleArray magnitudeArray;

            arrayExist = inputPPArray.checkArrayExist(magString, out doubleType);
            if (arrayExist)
            {
                magnitudeArray = inputPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeArray = new MDoubleArray();
            }

            MDoubleArray magnitudeOwnerArray;

            arrayExist = ownerPPArray.checkArrayExist(magString, out doubleType);
            if (arrayExist)
            {
                magnitudeOwnerArray = ownerPPArray.getDoubleData(magString);
            }
            else
            {
                magnitudeOwnerArray = new MDoubleArray();
            }

            string dirString = "direction";

            MFnArrayAttrsData.Type vectorType = MFnArrayAttrsData.Type.kVectorArray;
            MVectorArray           directionArray;

            arrayExist = inputPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionArray = inputPPArray.getVectorData(dirString);
            }
            else
            {
                directionArray = new MVectorArray();
            }

            MVectorArray directionOwnerArray;

            arrayExist = ownerPPArray.checkArrayExist(dirString, out vectorType);
            if (arrayExist)
            {
                directionOwnerArray = ownerPPArray.getVectorData(dirString);
            }
            else
            {
                directionOwnerArray = new MVectorArray();
            }

            // Compute the output force.
            //
            MVectorArray forceArray = new MVectorArray();

            apply(dataBlock, points.length, magnitudeArray, magnitudeOwnerArray,
                  directionArray, directionOwnerArray, forceArray);

            // get output data handle
            //
            MArrayDataHandle  hOutArray = dataBlock.outputArrayValue(mOutputForce);
            MArrayDataBuilder bOutArray = hOutArray.builder();

            // get output force array from block.
            //
            MDataHandle        hOut          = bOutArray.addElement(multiIndex);
            MFnVectorArrayData fnOutputForce = new MFnVectorArrayData();
            MObject            dOutputForce  = fnOutputForce.create(forceArray);

            // update data block with new output force data.
            //
            hOut.set(dOutputForce);
            dataBlock.setClean(plug);

            return(true);
        }
Пример #13
0
        private unsafe void apply(
            MDataBlock block,
            uint receptorSize,
            MDoubleArray magnitudeArray,
            MDoubleArray magnitudeOwnerArray,
            MVectorArray directionArray,
            MVectorArray directionOwnerArray,
            MVectorArray outputForce
            )
        //
        //      Compute output force for each particle.  If there exists the
        //      corresponding per particle attribute, use the data passed from
        //      particle shape (stored in magnitudeArray and directionArray).
        //      Otherwise, use the attribute value from the field.
        //
        {
            // get the default values
            MVector defaultDir        = direction(block);
            double  defaultMag        = magnitude(block);
            uint    magArraySize      = magnitudeArray.length;
            uint    dirArraySize      = directionArray.length;
            uint    magOwnerArraySize = magnitudeOwnerArray.length;
            uint    dirOwnerArraySize = directionOwnerArray.length;
            uint    numOfOwner        = magOwnerArraySize;

            if (dirOwnerArraySize > numOfOwner)
            {
                numOfOwner = dirOwnerArraySize;
            }

            double  m_magnitude = defaultMag;
            MVector m_direction = defaultDir;

            for (int ptIndex = 0; ptIndex < receptorSize; ptIndex++)
            {
                if (receptorSize == magArraySize)
                {
                    m_magnitude = magnitudeArray[ptIndex];
                }
                if (receptorSize == dirArraySize)
                {
                    m_direction = directionArray[ptIndex];
                }
                if (numOfOwner > 0)
                {
                    for (int nthOwner = 0; nthOwner < numOfOwner; nthOwner++)
                    {
                        if (magOwnerArraySize == numOfOwner)
                        {
                            m_magnitude = magnitudeOwnerArray[nthOwner];
                        }
                        if (dirOwnerArraySize == numOfOwner)
                        {
                            m_direction = directionOwnerArray[nthOwner];
                        }
                        outputForce.append(m_direction * m_magnitude);
                    }
                }
                else
                {
                    outputForce.append(m_direction * m_magnitude);
                }
            }
        }
Пример #14
0
        //
        // Description
        //
        //    Create circles of vertices starting with
        //    the top pole ending with the bottom pole
        //
        public void buildSphere(double rad,
                                int div,
                                MPointArray vertices,
                                MIntArray counts,
                                MIntArray connects,
                                MVectorArray normals,
                                apiMeshGeomUV uvs)
        {
            double u       = -Math.PI / 2.0;
            double v       = -Math.PI;
            double u_delta = Math.PI / ((double)div);
            double v_delta = 2 * Math.PI / ((double)div);

            MPoint topPole = new MPoint(0.0, rad, 0.0);
            MPoint botPole = new MPoint(0.0, -rad, 0.0);

            // Build the vertex and normal table
            //
            vertices.append(botPole);
            normals.append(botPole.minus(MPoint.origin));
            int i;

            for (i = 0; i < (div - 1); i++)
            {
                u += u_delta;
                v  = -Math.PI;

                for (int j = 0; j < div; j++)
                {
                    double x   = rad * Math.Cos(u) * Math.Cos(v);
                    double y   = rad * Math.Sin(u);
                    double z   = rad * Math.Cos(u) * Math.Sin(v);
                    MPoint pnt = new MPoint(x, y, z);
                    vertices.append(pnt);
                    normals.append(pnt.minus(MPoint.origin));
                    v += v_delta;
                }
            }
            vertices.append(topPole);
            normals.append(topPole.minus(MPoint.origin));

            // Create the connectivity lists
            //
            int vid  = 1;
            int numV = 0;

            for (i = 0; i < div; i++)
            {
                for (int j = 0; j < div; j++)
                {
                    if (i == 0)
                    {
                        counts.append(3);
                        connects.append(0);
                        connects.append(j + vid);
                        connects.append((j == (div - 1)) ? vid : j + vid + 1);
                    }
                    else if (i == (div - 1))
                    {
                        counts.append(3);
                        connects.append(j + vid + 1 - div);
                        connects.append(vid + 1);
                        connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div);
                    }
                    else
                    {
                        counts.append(4);
                        connects.append(j + vid + 1 - div);
                        connects.append(j + vid + 1);
                        connects.append(j == (div - 1) ? vid + 1 : j + vid + 2);
                        connects.append(j == (div - 1) ? vid + 1 - div : j + vid + 2 - div);
                    }
                    numV++;
                }
                vid = numV;
            }

            // TODO: Define UVs for sphere ...
            //
        }
Пример #15
0
        public void drawVertices(MDrawRequest request, M3dView view)
        {
            MDrawData    data = request.drawData();
            MVectorArray geom = data.geometry() as MVectorArray;

            view.beginGL();

            // Query current state so it can be restored
            //
            bool lightingWasOn = OpenGL.glIsEnabled(OpenGL.GL_LIGHTING) != 0 ? true : false;

            if (lightingWasOn)
            {
                OpenGL.glDisable(OpenGL.GL_LIGHTING);
            }
            float lastPointSize;

            getLastPointSize(out lastPointSize);

            // Set the point size of the vertices
            //
            OpenGL.glPointSize(POINT_SIZE);

            // If there is a component specified by the draw request
            // then loop over comp (using an MFnComponent class) and draw the
            // active vertices, otherwise draw all vertices.
            //
            MObject comp = request.component;

            if (!comp.isNull)
            {
                MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(comp);
                for (int i = 0; i < fnComponent.elementCount; i++)
                {
                    int index = fnComponent.element(i);
                    OpenGL.glBegin(OpenGL.GL_POINTS);
                    MVector point = geom[index];
                    OpenGL.glVertex3f((float)point[0],
                                      (float)point[1],
                                      (float)point[2]);
                    OpenGL.glEnd();

                    MPoint mp = new MPoint(point);
                    view.drawText(String.Format("{0}", index), mp);
                }
            }
            else
            {
                for (int i = 0; i < geom.length; i++)
                {
                    OpenGL.glBegin(OpenGL.GL_POINTS);
                    MVector point = geom[i];
                    OpenGL.glVertex3f((float)point[0], (float)point[1], (float)point[2]);
                    OpenGL.glEnd();
                }
            }

            // Restore the state
            //
            if (lightingWasOn)
            {
                OpenGL.glEnable(OpenGL.GL_LIGHTING);
            }
            OpenGL.glPointSize(lastPointSize);

            view.endGL();
        }
Пример #16
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");
        }
Пример #17
0
        public bool selectVertices(MSelectInfo selectInfo,
                                   MSelectionList selectionList,
                                   MPointArray worldSpaceSelectPts)
        {
            bool    selected = false;
            M3dView view     = selectInfo.view;

            MPoint xformedPoint;
            MPoint currentPoint = new MPoint();
            MPoint selectionPoint = new MPoint();
            double z, 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);
            int     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
            //
            apiSimpleShape shape = surfaceShape as apiSimpleShape;
            MVectorArray   geom  = shape.controlPoints;


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

            for (vertexIndex = 0; vertexIndex < numVertices; vertexIndex++)
            {
                MVector point = geom[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)point[0],
                                  (float)point[1],
                                  (float)point[2]);
                OpenGL.glEnd();

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

                    if (singleSelection)
                    {
                        xformedPoint = currentPoint;
                        xformedPoint.homogenize();
                        xformedPoint = xformedPoint.multiply(alignmentMatrix);
                        z            = xformedPoint.z;
                        if (closestPointVertexIndex < 0 || z > previousZ)
                        {
                            closestPointVertexIndex = vertexIndex;
                            singlePoint             = currentPoint;
                            previousZ = z;
                        }
                    }
                    else
                    {
                        // multiple selection, store all elements
                        //
                        fnComponent.addElement(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 = selectionPoint.multiply(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);
        }
Пример #18
0
        public override void readDoubleVectorArray(MVectorArray array, uint arraySize)
        {
            Trace.Assert(myCurrentChanelNode != null);

            XmlNode doubleVectorArrayNode = myCurrentChanelNode.SelectSingleNode(doubleVectorArrayTag);
            XmlNodeList valueNodeList = doubleVectorArrayNode.SelectNodes("value");
            uint i = 0;
            array.clear();
            array.length = arraySize;
            foreach (XmlNode valueNode in valueNodeList)
            {
                XmlNode xNode = valueNode.SelectSingleNode("x");
                double valueX = Convert.ToDouble(xNode.InnerText);

                XmlNode yNode = valueNode.SelectSingleNode("y");
                double valuey = Convert.ToDouble(yNode.InnerText);

                XmlNode zNode = valueNode.SelectSingleNode("z");
                double valuez = Convert.ToDouble(zNode.InnerText);

                MVector v = new MVector(valueX, valuey, valuez);
                array.set(v, i);
                i++;
            }
            return;
        }
Пример #19
0
        public override void getDrawRequests(MDrawInfo info,
                                             bool objectAndActiveOnly,
                                             MDrawRequestQueue queue)
        {
            apiSimpleShape shapeNode = surfaceShape as apiSimpleShape;

            if (shapeNode == null)
            {
                return;
            }

            // This call creates a prototype draw request that we can fill
            // in and then add to the draw queue.
            //
            MDrawRequest request = info.getPrototype(this);


            MDrawData    data;
            MVectorArray geomPtr = shapeNode.controlPoints;

            // Stuff our data into the draw request, it'll be used when the drawing
            // actually happens
            getDrawData(geomPtr, out data);

            request.setDrawData(data);

            // Decode the draw info and determine what needs to be drawn
            //

            M3dView.DisplayStyle  appearance    = info.displayStyle;
            M3dView.DisplayStatus displayStatus = info.displayStatus;

            switch (appearance)
            {
            case M3dView.DisplayStyle.kWireFrame:
            {
                request.token = (int)DrawShapeStyle.kDrawWireframe;

                M3dView.ColorTable activeColorTable  = M3dView.ColorTable.kActiveColors;
                M3dView.ColorTable dormantColorTable = M3dView.ColorTable.kDormantColors;

                switch (displayStatus)
                {
                case M3dView.DisplayStatus.kLead:
                    request.setColor(LEAD_COLOR, (int)activeColorTable);
                    break;

                case M3dView.DisplayStatus.kActive:
                    request.setColor(ACTIVE_COLOR, (int)activeColorTable);
                    break;

                case M3dView.DisplayStatus.kActiveAffected:
                    request.setColor(ACTIVE_AFFECTED_COLOR, (int)activeColorTable);
                    break;

                case M3dView.DisplayStatus.kDormant:
                    request.setColor(DORMANT_COLOR, (int)dormantColorTable);
                    break;

                case M3dView.DisplayStatus.kHilite:
                    request.setColor(HILITE_COLOR, (int)activeColorTable);
                    break;

                default:
                    break;
                }

                queue.add(request);

                break;
            }

            case M3dView.DisplayStyle.kGouraudShaded:
            {
                // Create the smooth shaded draw request
                //
                request.token = (int)DrawShapeStyle.kDrawSmoothShaded;

                // Need to get the material info
                //
                MDagPath  path     = info.multiPath;     // path to your dag object
                M3dView   view     = info.view;          // view to draw to
                MMaterial material = base.material(path);

                // Evaluate the material and if necessary, the texture.
                //
                material.evaluateMaterial(view, path);

                bool drawTexture = true;
                if (drawTexture && material.materialIsTextured)
                {
                    material.evaluateTexture(data);
                }

                request.material = material;

                bool materialTransparent = false;
                material.getHasTransparency(ref materialTransparent);
                if (materialTransparent)
                {
                    request.isTransparent = true;
                }

                queue.add(request);

                // create a draw request for wireframe on shaded if
                // necessary.
                //
                if ((displayStatus == M3dView.DisplayStatus.kActive) ||
                    (displayStatus == M3dView.DisplayStatus.kLead) ||
                    (displayStatus == M3dView.DisplayStatus.kHilite))
                {
                    MDrawRequest wireRequest = request;
                    wireRequest.setDrawData(data);
                    wireRequest.token        = (int)DrawShapeStyle.kDrawWireframeOnShaded;
                    wireRequest.displayStyle = M3dView.DisplayStyle.kWireFrame;

                    M3dView.ColorTable activeColorTable = M3dView.ColorTable.kActiveColors;

                    switch (displayStatus)
                    {
                    case M3dView.DisplayStatus.kLead:
                        wireRequest.setColor(LEAD_COLOR, (int)activeColorTable);
                        break;

                    case M3dView.DisplayStatus.kActive:
                        wireRequest.setColor(ACTIVE_COLOR, (int)activeColorTable);
                        break;

                    case M3dView.DisplayStatus.kHilite:
                        wireRequest.setColor(HILITE_COLOR, (int)activeColorTable);
                        break;

                    default:
                        break;
                    }

                    queue.add(wireRequest);
                }

                break;
            }

            case M3dView.DisplayStyle.kFlatShaded:
                request.token = (int)DrawShapeStyle.kDrawFlatShaded;
                break;

            default:
                break;
            }

            // Add draw requests for components
            //
            if (!objectAndActiveOnly)
            {
                // Inactive components
                //
                if ((appearance == M3dView.DisplayStyle.kPoints) ||
                    (displayStatus == M3dView.DisplayStatus.kHilite))
                {
                    MDrawRequest vertexRequest = request;
                    vertexRequest.setDrawData(data);
                    vertexRequest.token = (int)DrawShapeStyle.kDrawVertices;
                    vertexRequest.setColor(DORMANT_VERTEX_COLOR, (int)M3dView.ColorTable.kActiveColors);

                    queue.add(vertexRequest);
                }

                // Active components
                //
                if (shapeNode.hasActiveComponents)
                {
                    MDrawRequest activeVertexRequest = request;
                    activeVertexRequest.setDrawData(data);
                    activeVertexRequest.token = (int)DrawShapeStyle.kDrawVertices;
                    activeVertexRequest.setColor(ACTIVE_VERTEX_COLOR, (int)M3dView.ColorTable.kActiveColors);

                    MObjectArray clist           = shapeNode.activeComponents;
                    MObject      vertexComponent = clist[0]; // Should filter list
                    activeVertexRequest.component = vertexComponent;

                    queue.add(activeVertexRequest);
                }
            }
        }
 public apiSimpleShapeIterator(object userGeometry, MObject components)
     : base(userGeometry, components)
 {
     mGeometry = userGeometry as MVectorArray;
     reset();
 }
Пример #21
0
		//
		// Description
		//
		//     This function takes an input surface of type kMeshData and converts
		//     the geometry into this nodes attributes.
		//     Returns false if nothing is connected.
		//
		public bool computeInputMesh(MPlug plug,
									 MDataBlock datablock,
									 MPointArray vertices,
									 MIntArray counts,
									 MIntArray connects,
									 MVectorArray normals,
									 apiMeshGeomUV uvs)
		{
			// Get the input subdiv
			//
			MDataHandle inputData = datablock.inputValue( inputMesh );
			MObject surf = inputData.asMesh;

			// Check if anything is connected
			//
			MObject thisObj = thisMObject();
			MPlug surfPlug = new MPlug( thisObj, inputMesh );
			if ( !surfPlug.isConnected )
			{
				datablock.setClean( plug );
				return false;
			}

			// Extract the mesh data
			//
			MFnMesh surfFn = new MFnMesh(surf);
			surfFn.getPoints( vertices, MSpace.Space.kObject );

			// Check to see if we have UVs to copy.
			//
			bool hasUVs = surfFn.numUVsProperty > 0;
			surfFn.getUVs( uvs.ucoord, uvs.vcoord );

			for ( int i=0; i<surfFn.numPolygons; i++ )
			{
				MIntArray polyVerts = new MIntArray();
				surfFn.getPolygonVertices( i, polyVerts );
				int pvc = (int)polyVerts.length;
				counts.append( pvc );
				int uvId;
				for ( int v=0; v<pvc; v++ )
				{
					if ( hasUVs )
					{
						surfFn.getPolygonUVid( i, v, out uvId );
						uvs.faceVertexIndex.append( uvId );
					}
					connects.append( polyVerts[v] );
				}
			}

			for ( int n=0; n<(int)vertices.length; n++ )
			{
				MVector normal = new MVector();
				surfFn.getVertexNormal( n, normal );
				normals.append( normal );
			}

			return true;
		}
Пример #22
0
        //
        //      Compute output force for each particle.  If there exists the
        //      corresponding per particle attribute, use the data passed from
        //      particle shape (stored in magnitudeArray and directionArray).
        //      Otherwise, use the attribute value from the field.
        //
        private unsafe void apply(
            MDataBlock block,
            uint receptorSize,
            MDoubleArray magnitudeArray,
            MDoubleArray magnitudeOwnerArray,
            MVectorArray directionArray,
            MVectorArray directionOwnerArray,
            MVectorArray outputForce
            )
        {
            // get the default values
            MVector defaultDir = direction(block);
            double defaultMag = magnitude(block);
            uint magArraySize = magnitudeArray.length;
            uint dirArraySize = directionArray.length;
            uint magOwnerArraySize = magnitudeOwnerArray.length;
            uint dirOwnerArraySize = directionOwnerArray.length;
            uint numOfOwner = magOwnerArraySize;
            if (dirOwnerArraySize > numOfOwner)
                numOfOwner = dirOwnerArraySize;

            double m_magnitude = defaultMag;
            MVector m_direction = defaultDir;

            for (int ptIndex = 0; ptIndex < receptorSize; ptIndex++)
            {
                if (receptorSize == magArraySize)
                    m_magnitude = magnitudeArray[ptIndex];
                if (receptorSize == dirArraySize)
                    m_direction = directionArray[ptIndex];
                if (numOfOwner > 0)
                {
                    for (int nthOwner = 0; nthOwner < numOfOwner; nthOwner++)
                    {
                        if (magOwnerArraySize == numOfOwner)
                            m_magnitude = magnitudeOwnerArray[nthOwner];
                        if (dirOwnerArraySize == numOfOwner)
                            m_direction = directionOwnerArray[nthOwner];
                        outputForce.append(m_direction * m_magnitude);
                    }
                }
                else
                {
                    outputForce.append(m_direction * m_magnitude);
                }
            }
        }
Пример #23
0
		//
		// Description
		//
		//    Constructs a cube
		//
		public void buildCube(double cube_size, 
							  MPointArray pa,
							  MIntArray faceCounts, 
							  MIntArray faceConnects,
							  MVectorArray normals, 
							  apiMeshGeomUV uvs)
		{
			const int num_faces			= 6;
			const int num_face_connects	= 24;
			const double normal_value   = 0.5775;
			const int uv_count			= 14; 
	
			pa.clear();
			faceCounts.clear();
			faceConnects.clear();
			uvs.reset();

			pa.append( new MPoint( -cube_size, -cube_size, -cube_size ) );
			pa.append( new MPoint(  cube_size, -cube_size, -cube_size ) );
			pa.append( new MPoint(  cube_size, -cube_size,  cube_size ) );
			pa.append( new MPoint( -cube_size, -cube_size,  cube_size ) );
			pa.append( new MPoint( -cube_size,  cube_size, -cube_size ) );
			pa.append( new MPoint( -cube_size,  cube_size,  cube_size ) );
			pa.append( new MPoint(  cube_size,  cube_size,  cube_size ) );
			pa.append( new MPoint(  cube_size,  cube_size, -cube_size ) );

			normals.append( new MVector( -normal_value, -normal_value, -normal_value ) );
			normals.append( new MVector(  normal_value, -normal_value, -normal_value ) );
			normals.append( new MVector(  normal_value, -normal_value,  normal_value ) );
			normals.append( new MVector( -normal_value, -normal_value,  normal_value ) );
			normals.append( new MVector( -normal_value,  normal_value, -normal_value ) );
			normals.append( new MVector( -normal_value,  normal_value,  normal_value ) );
			normals.append( new MVector(  normal_value,  normal_value,  normal_value ) );
			normals.append( new MVector(  normal_value,  normal_value, -normal_value ) );

			// Define the UVs for the cube. 
			//
			float[] uv_pts = new float[uv_count*2] { 0.375f, 0.0f,
													 0.625f, 0.0f,
													 0.625f, 0.25f,
													 0.375f, 0.25f,
													 0.625f, 0.5f,
													 0.375f, 0.5f,
													 0.625f, 0.75f,
													 0.375f, 0.75f,
													 0.625f, 1.0f,
													 0.375f, 1.0f,
													 0.875f, 0.0f,
													 0.875f, 0.25f,
													 0.125f, 0.0f,
													 0.125f, 0.25f };

			// UV Face Vertex Id.
			//
			int[] uv_fvid = new int[num_face_connects]{ 0, 1, 2, 3, 
														3, 2, 4, 5, 
														5, 4, 6, 7, 
														7, 6, 8, 9, 
														1, 10, 11, 2, 
														12, 0, 3, 13 };

			int i;
			for ( i = 0; i < uv_count; i ++ ) {
				uvs.append_uv( uv_pts[i*2], uv_pts[i*2 + 1] ); 
			}
	
			for ( i = 0; i < num_face_connects; i ++ ) { 
				uvs.faceVertexIndex.append( uv_fvid[i] ); 
			}

			// Set up an array containing the number of vertices
			// for each of the 6 cube faces (4 vertices per face)
			//
			int[] face_counts = new int[num_faces]{ 4, 4, 4, 4, 4, 4 };

			for ( i=0; i<num_faces; i++ )
			{
				faceCounts.append( face_counts[i] );
			}

			// Set up and array to assign vertices from pa to each face 
			//
			int[] face_connects = new int[ num_face_connects ]{ 0, 1, 2, 3,
																4, 5, 6, 7,
																3, 2, 6, 5,
																0, 3, 5, 4,
																0, 4, 7, 1,
																1, 7, 6, 2 };
			for ( i=0; i<num_face_connects; i++ )
			{
				faceConnects.append( face_connects[i] );
			}
		}
Пример #24
0
		private unsafe void apply(
		MDataBlock block,
		uint receptorSize,
		MDoubleArray magnitudeArray,
		MDoubleArray magnitudeOwnerArray,
		MVectorArray directionArray,
		MVectorArray directionOwnerArray,
		MVectorArray outputForce
		)
		//
		//      Compute output force for each particle.  If there exists the 
		//      corresponding per particle attribute, use the data passed from
		//      particle shape (stored in magnitudeArray and directionArray).  
		//      Otherwise, use the attribute value from the field.
		//
		{
			// get the default values
			MVector defaultDir = direction(block);
			double defaultMag = magnitude(block);
			uint magArraySize = magnitudeArray.length;
			uint dirArraySize = directionArray.length;
			uint magOwnerArraySize = magnitudeOwnerArray.length;
			uint dirOwnerArraySize = directionOwnerArray.length;
			uint numOfOwner = magOwnerArraySize;
			if (dirOwnerArraySize > numOfOwner)
				numOfOwner = dirOwnerArraySize;

			double m_magnitude = defaultMag;
			MVector m_direction = defaultDir;

			for (int ptIndex = 0; ptIndex < receptorSize; ptIndex++)
			{
				if (receptorSize == magArraySize)
					m_magnitude = magnitudeArray[ptIndex];
				if (receptorSize == dirArraySize)
					m_direction = directionArray[ptIndex];
				if (numOfOwner > 0)
				{
					for (int nthOwner = 0; nthOwner < numOfOwner; nthOwner++)
					{
						if (magOwnerArraySize == numOfOwner)
							m_magnitude = magnitudeOwnerArray[nthOwner];
						if (dirOwnerArraySize == numOfOwner)
							m_direction = directionOwnerArray[nthOwner];
						outputForce.append(m_direction * m_magnitude);
					}
				}
				else
				{
					outputForce.append(m_direction * m_magnitude);
				}
			}
		}
Пример #25
0
		//
		// Description
		//
		//    Create circles of vertices starting with 
		//    the top pole ending with the bottom pole
		//
		public void buildSphere(double rad,
								int div,
								MPointArray vertices,
								MIntArray counts,
								MIntArray connects,
								MVectorArray normals,
								apiMeshGeomUV uvs)
		{
			double u = -Math.PI / 2.0;
			double v = -Math.PI;
			double u_delta = Math.PI / ((double)div); 
			double v_delta = 2 * Math.PI / ((double)div); 

			MPoint topPole = new MPoint( 0.0, rad, 0.0 );
			MPoint botPole = new MPoint( 0.0, -rad, 0.0 );

			// Build the vertex and normal table
			//
			vertices.append( botPole );
			normals.append( botPole.minus(MPoint.origin) );
			int i;
			for ( i=0; i<(div-1); i++ )
			{
				u += u_delta;
				v = -Math.PI;

				for ( int j=0; j<div; j++ )
				{
					double x = rad * Math.Cos(u) * Math.Cos(v);
					double y = rad * Math.Sin(u);
					double z = rad * Math.Cos(u) * Math.Sin(v) ;
					MPoint pnt = new MPoint( x, y, z );
					vertices.append( pnt );
					normals.append( pnt.minus(MPoint.origin) );
					v += v_delta;
				}
			}
			vertices.append( topPole );
			normals.append( topPole.minus(MPoint.origin) );

			// Create the connectivity lists
			//
			int vid = 1;
			int numV = 0;
			for ( i=0; i<div; i++ )
			{
				for ( int j=0; j<div; j++ )
				{
					if ( i==0 )
					{
						counts.append( 3 );
						connects.append( 0 );
						connects.append( j+vid );
						connects.append( (j==(div-1)) ? vid : j+vid+1 );
					}
					else if ( i==(div-1) )
					{
						counts.append( 3 );
						connects.append( j+vid+1-div );
						connects.append( vid+1 );
						connects.append( j==(div-1) ? vid+1-div : j+vid+2-div );
					}
					else
					{
						counts.append( 4 );
						connects.append( j + vid+1-div );
						connects.append( j + vid+1 );
						connects.append( j == (div-1) ? vid+1 : j+vid+2 );
						connects.append( j == (div-1) ? vid+1-div : j+vid+2-div );
					}
					numV++;
				}
				vid = numV;
			}

			// TODO: Define UVs for sphere ...
			//
		}
Пример #26
0
        //
        // Description
        //
        //    Returns offsets for the given components to be used my the
        //    move tool in normal/u/v mode.
        //
        // Arguments
        //
        //    component - components to calculate offsets for
        //    direction - array of offsets to be filled
        //    mode      - the type of offset to be calculated
        //    normalize - specifies whether the offsets should be normalized
        //
        // Returns
        //
        //    true if the offsets could be calculated, false otherwise
        //
        // Support the move tools normal/u/v mode (components)
        //
        public override bool vertexOffsetDirection( MObject component,
            MVectorArray direction,
            MVertexOffsetMode mode,
            bool normalize)
        {
            bool offsetOkay = false ;

            MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( component );
            if ( component.apiType != MFn.Type.kMeshVertComponent ) {
                return false;
            }

            offsetOkay = true ;

            apiMeshGeom geomPtr = meshGeom();
            if ( null == geomPtr ) {
                return false;
            }

            // For each vertex add the appropriate offset
            //
            int count = fnComp.elementCount;
            for ( int idx=0; idx<count; idx++ )
            {
                MVector normal = geomPtr.normals[ fnComp.element(idx) ];

                if( mode == MVertexOffsetMode.kNormal ) {
                    if( normalize ) normal.normalize() ;
                    direction.append( normal );
                }
                else {
                    // Construct an orthonormal basis from the normal
                    // uAxis, and vAxis are the new vectors.
                    //
                    MVector uAxis = new MVector();
                    MVector vAxis = new MVector();
                    uint i, j, k;
                    double a;
                    normal.normalize();

                    i = 0;
                    a = Math.Abs( normal[0] );
                    if ( a < Math.Abs(normal[1]) )
                    {
                        i = 1;
                        a = Math.Abs(normal[1]);
                    }

                    if ( a < Math.Abs(normal[2]) )
                    {
                        i = 2;
                    }

                    j = (i+1)%3;
                    k = (j+1)%3;

                    a = Math.Sqrt(normal[i]*normal[i] + normal[j]*normal[j]);
                    uAxis[i] = -normal[j]/a;
                    uAxis[j] = normal[i]/a;
                    uAxis[k] = 0.0;
                    vAxis = normal.crossProduct( uAxis );

                    if ( mode == MVertexOffsetMode.kUTangent ||
                         mode == MVertexOffsetMode.kUVNTriad )
                    {
                        if( normalize ) uAxis.normalize() ;
                        direction.append( uAxis );
                    }

                    if ( mode == MVertexOffsetMode.kVTangent ||
                         mode == MVertexOffsetMode.kUVNTriad )
                    {
                        if( normalize ) vAxis.normalize() ;
                        direction.append( vAxis );
                    }

                    if ( mode == MVertexOffsetMode.kUVNTriad ) {
                        if( normalize ) normal.normalize() ;
                        direction.append( normal );
                    }
                }
            }

            return offsetOkay;
        }
Пример #27
0
        //
        // Description
        //
        //     This function takes an input surface of type kMeshData and converts
        //     the geometry into this nodes attributes.
        //     Returns false if nothing is connected.
        //
        public bool computeInputMesh(MPlug plug,
                                     MDataBlock datablock,
                                     MPointArray vertices,
                                     MIntArray counts,
                                     MIntArray connects,
                                     MVectorArray normals,
                                     apiMeshGeomUV uvs)
        {
            // Get the input subdiv
            //
            MDataHandle inputData = datablock.inputValue(inputMesh);
            MObject     surf      = inputData.asMesh;

            // Check if anything is connected
            //
            MObject thisObj  = thisMObject();
            MPlug   surfPlug = new MPlug(thisObj, inputMesh);

            if (!surfPlug.isConnected)
            {
                datablock.setClean(plug);
                return(false);
            }

            // Extract the mesh data
            //
            MFnMesh surfFn = new MFnMesh(surf);

            surfFn.getPoints(vertices, MSpace.Space.kObject);

            // Check to see if we have UVs to copy.
            //
            bool hasUVs = surfFn.numUVsProperty > 0;

            surfFn.getUVs(uvs.ucoord, uvs.vcoord);

            for (int i = 0; i < surfFn.numPolygons; i++)
            {
                MIntArray polyVerts = new MIntArray();
                surfFn.getPolygonVertices(i, polyVerts);
                int pvc = (int)polyVerts.length;
                counts.append(pvc);
                int uvId;
                for (int v = 0; v < pvc; v++)
                {
                    if (hasUVs)
                    {
                        surfFn.getPolygonUVid(i, v, out uvId);
                        uvs.faceVertexIndex.append(uvId);
                    }
                    connects.append(polyVerts[v]);
                }
            }

            for (int n = 0; n < (int)vertices.length; n++)
            {
                MVector normal = new MVector();
                surfFn.getVertexNormal(n, normal);
                normals.append(normal);
            }

            return(true);
        }