// Adds a generic attribute that accepts a float, float2, float3 public static void addComplexFloatGenericAttribute(ref MObject attrObject, string longName, string shortName) { // Create the generic attribute and set the 3 accepts types MFnGenericAttribute gAttr = new MFnGenericAttribute(); attrObject = gAttr.create(longName, shortName); try { gAttr.addAccept(MFnNumericData.Type.kFloat); gAttr.addAccept(MFnNumericData.Type.k2Float); gAttr.addAccept(MFnNumericData.Type.k3Float); } catch (System.Exception) { MGlobal.displayError("error happens in addAccept"); } gAttr.isWritable = false; gAttr.isStorable = false; // Add the attribute to the node try { addAttribute(attrObject); } catch (System.Exception) { MGlobal.displayError("error happens in addAttribute"); } }
public static void initialize() { MFnNumericAttribute nAttr = new MFnNumericAttribute(); // single float attribute affecting a generic attribute try{ gInputInt = nAttr.create("gInputInt", "gii", MFnNumericData.Type.kInt, 0); } catch (System.Exception) { MGlobal.displayError("error happens in addAccept"); } nAttr.isStorable = true; nAttr.isKeyable = true; try{ addAttribute(gInputInt); } catch (System.Exception) { MGlobal.displayError("error happens in addAccept"); } addComplexFloatGenericAttribute(ref gOutputFloat_2Float_3Float, "gOutputFloat_2Float_3Float", "gof2f3f"); try{ attributeAffects(gInputInt, gOutputFloat_2Float_3Float); } catch (System.Exception) { MGlobal.displayError("error happens in addAccept"); } return; }
static public Bool32 DebugReportCallback(DebugReportFlagsExt flags, DebugReportObjectTypeExt objectType, ulong objectHandle, IntPtr location, int messageCode, IntPtr layerPrefix, IntPtr message, IntPtr userData) { string layerString = Marshal.PtrToStringAnsi(layerPrefix); string messageString = Marshal.PtrToStringAnsi(message); MGlobal.displayError(string.Format("DebugReport layer: {0} message: {1}", layerString, messageString)); //Console.WriteLine("DebugReport layer: {0} message: {1}", layerString, messageString); return(false); }
protected override void createdConstraint(MPxConstraint constraint) { if (constraint != null) { GeometrySurfaceConstraint c = (GeometrySurfaceConstraint)constraint; c.weightType = weightType; } else { MGlobal.displayError("Failed to get created constraint."); } }
public override void writer(MFileObject file, string optionsString, FileAccessMode mode) { if (mode == FileAccessMode.kExportActiveAccessMode) { StaticObject scb = StaticObject.Create(); scb.WriteSCB(file.expandedFullName); } else { MGlobal.displayError("SCBExporter - Wrong File Access Mode: " + mode); } }
private static void CurrentDomainOnUnhandledException( object sender, UnhandledExceptionEventArgs e) { // write the error the Output Window var error = MStreamUtils.stdErrorStream(); MStreamUtils.writeCharBuffer(error, e.ExceptionObject + "\n"); // write the error to the status bar MGlobal.displayError(e.ExceptionObject.ToString()); }
//! Removes the callback public override void toolOffCleanup() { try { MModelMessage.ActiveListModified -= updateManipulatorsFunc; } catch (System.Exception) { MGlobal.displayError("Model remove callback failed"); } base.toolOffCleanup(); }
// When the focus changes in the result grid private void ResultGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { // Get the selected information string ObjType = ((object[])ResultGrid.SelectedItem)[1].ToString(); string Name = ((object [])ResultGrid.SelectedItem)[0].ToString(); // Select the object if (!MGlobal.selectByName(Name, MGlobal.ListAdjustment.kReplaceList)) { MGlobal.displayError(Name + " not found"); } e.Handled = true; }
private void ValidateMeshTopology(MFnMesh mesh, MDagPath meshDagPath, MIntArray polygonShaderIndices, ref MIntArray vertexShaders, uint shaderCount) { //Check if the mesh contains holes MIntArray holeInfoArray = new MIntArray(); MIntArray holeVertexArray = new MIntArray(); mesh.getHoles(holeInfoArray, holeVertexArray); if (holeInfoArray.length != 0) { MGlobal.displayError("SKNFile:Create - Mesh contains holes"); throw new Exception("SKNFile:Create - Mesh contains holes"); } //Check for non-Triangulated polygons and shared shaders vertexShaders = new MIntArray((uint)mesh.numVertices, -1); MItMeshPolygon polygonIterator = new MItMeshPolygon(meshDagPath); for (polygonIterator.reset(); !polygonIterator.isDone; polygonIterator.next()) { if (!polygonIterator.hasValidTriangulation) { MGlobal.displayError("SKNFile:Create - Mesh contains a non-Triangulated polygon"); throw new Exception("SKNFile:Create - Mesh contains a non-Triangulated polygon"); } int shaderIndex = polygonShaderIndices[(int)polygonIterator.index()]; MIntArray vertices = new MIntArray(); polygonIterator.getVertices(vertices); if (shaderIndex == -1) { MGlobal.displayError("SKNFile:Create - Mesh contains a face with no shader"); throw new Exception("SKNFile:Create - Mesh contains a face with no shader"); } for (int i = 0; i < vertices.length; i++) { if (shaderCount > 1 && vertexShaders[vertices[i]] != -1 && shaderIndex != vertexShaders[vertices[i]]) { MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with multiple sahders"); throw new Exception("SKNFile:Create - Mesh contains a vertex with multiple sahders"); } else { vertexShaders[vertices[i]] = shaderIndex; } } } }
// The implementation here is a bit different from its counterpart C++ sample because // .NET SDK decides not to support the obsolete C++ API: // // bool connectTargetAttribute (void *opaqueTarget, int index, MObject &constraintAttr); // protected override bool connectTarget(MDagPath targetPath, int index) { try { MObject targetObject = new MObject(targetPath.node); MFnDagNode targetDagNode = new MFnDagNode(targetObject); connectTargetAttribute(targetPath, index, targetDagNode.attribute("worldMesh"), GeometrySurfaceConstraint.targetGeometry); } catch (Exception) { MGlobal.displayError("Failed to connect target."); return(false); } return(true); }
public override void toolOnSetup(MEvent arg0) { _setHelpString("Move the object using the manipulator"); //Todo after message implement updateManipulators(); try { MModelMessage.ActiveListModified += updateManipulatorsFunc; } catch (System.Exception) { MGlobal.displayError("Model addCallback failed"); } base.toolOnSetup(arg0); }
// Node added to model callback. private static void userNodeAddedCB(object sender, MNodeFunctionArgs args) { MObject node = args.node; if (!node.isNull) { MDagPath path = new MDagPath(); try { MDagPath.getAPathTo(node, path); string info = "DAG Model - Node added: "; info += path.fullPathName; try { MObject obj = path.transform; } catch (ArgumentException) { info += "(WORLD)"; } catch (Exception) { } MGlobal.displayInfo(info); } catch (System.Exception) { MGlobal.displayInfo("Error: failed to get dag path to node."); } } // remove the callback node.NodeAddedToModel -= userNodeAddedCB; // listen for removal message try { node.NodeRemovedFromModel += userNodeRemovedCB; } catch (System.Exception) { MGlobal.displayError("Failed to install node removed from model callback.\n"); } }
public bool importAim(string fileName, string flags) { MAnimCurveClipboard.theAPIClipboard.clear(); // If the selection list is empty, there is nothing to import. // MSelectionList sList = new MSelectionList(); MGlobal.getActiveSelectionList(sList); if (sList.isEmpty) { string msg = MStringResource.getString(RegisterMStringResources.kNothingSelected); MGlobal.displayError(msg); return(false); } StreamReaderExt readExt = new StreamReaderExt(fileName); fReader.readClipboard(ref readExt, MAnimCurveClipboard.theAPIClipboard); if (MAnimCurveClipboard.theAPIClipboard.isEmpty) { return(false); } string command = "pasteKey -cb api "; command += pasteFlags; try { int result = -1; MGlobal.executeCommand(command, out result, false, true); } catch (System.Exception) { string msg = MStringResource.getString(RegisterMStringResources.kPasteFailed); MGlobal.displayError(msg); return(false); } readExt.Close(); return(true); }
public override void writer(MFileObject file, string optionsString, FileAccessMode mode) { if (mode == FileAccessMode.kExportActiveAccessMode) { string sknPath = file.expandedFullName; string sklPath = Path.ChangeExtension(sknPath, ".skl"); SKLFile skl = new SKLFile(true); SKNFile skn = new SKNFile(skl); skl.Write(sklPath); skn.Write(sknPath); } else { MGlobal.displayError("SKNExporter - Wrong File Access Mode: " + mode); } }
public override void toolOnSetup(MEvent evt) { helpString = "Rotate the object using the rotation handles"; updateManipulators(this); try { if (bridge == null) { bridge = new updateManipulatorBridge(this); } MModelMessage.ActiveListModified += bridge.updateManipulators; } catch (System.Exception) { MGlobal.displayError("Model addCallback failed"); } }
static uint FindMemoryType(PhysicalDevice physicalDevice, uint typeFilter, MemoryPropertyFlags propertyFlags) { var memProperties = physicalDevice.GetMemoryProperties(); uint i = 0; foreach (var memType in memProperties.MemoryTypes) { if ((((typeFilter >> (int)i) & 1) == 1) && ((memType.PropertyFlags & propertyFlags) == propertyFlags)) { return(i); } i++; } MGlobal.displayError("failed to find memory type"); throw new Exception("failed to find memory type"); }
private bool exportSelected(ref StreamWriter animFile, ref string copyFlags, bool nodeNames = false, bool verboseUnits = false) { // If the selection list is empty, then there are no anim curves // to export. // MSelectionList sList = new MSelectionList(); MGlobal.getActiveSelectionList(sList); if (sList.isEmpty) { string msg = MStringResource.getString(RegisterMStringResources.kNothingSelected); MGlobal.displayError(msg); return(false); } // Copy any anim curves to the API clipboard. // int result = 0; string command = copyFlags; try { MGlobal.executeCommand(command, out result, false, true); } catch (System.Exception) { string msg = MStringResource.getString(RegisterMStringResources.kAnimCurveNotFound); MGlobal.displayError(msg); return(false); } if (result == 0 || MAnimCurveClipboard.theAPIClipboard.isEmpty) { string msg = MStringResource.getString(RegisterMStringResources.kAnimCurveNotFound); MGlobal.displayError(msg); return(false); } fWriter.writeClipboard(ref animFile, MAnimCurveClipboard.theAPIClipboard, nodeNames, verboseUnits); return(true); }
private void ReadLegacy(BinaryReader br) { string magic = Encoding.ASCII.GetString(br.ReadBytes(8)); if (magic != "r3d2sklt") { MGlobal.displayError("SKLFile:ReadLegacy - Invalid File Magic: " + magic); throw new Exception("SKLFile:ReadLegacy - Invalid File Magic: " + magic); } uint version = br.ReadUInt32(); if (version != 1 && version != 2) { MGlobal.displayError("SKLFile:ReadLegacy - Unsupported File Version: " + version); throw new Exception("SKLFile:ReadLegacy - Unsupported File Version: " + version); } uint skeletonID = br.ReadUInt32(); uint jointCount = br.ReadUInt32(); for (int i = 0; i < jointCount; i++) { this.Joints.Add(new SKLJoint(br, true, (short)i)); } if (version == 2) { uint influencesCount = br.ReadUInt32(); for (int i = 0; i < influencesCount; i++) { this.Influences.Add((short)br.ReadUInt32()); } } else if (version == 1) { for (int i = 0; i < this.Joints.Count; i++) { this.Influences.Add((short)i); } } }
public override void validateAndSetValue(MPlug plug, MDataHandle handle, MDGContext context) { // Make sure that there is something interesting to process. // if (plug.isNull) { throw new ArgumentNullException("plug"); } if (plug.equalEqual(aRockInX)) { MDataBlock block = _forceCache(context); MDataHandle blockHandle = block.outputValue(plug); // Update our new rock in x value double rockInX = handle.asDouble; blockHandle.set(rockInX); rockXValue = rockInX; // Update the custom transformation matrix to the // right rock value. rockingTransformCheckMatrix ltm = getRockingTransformMatrix(); if (ltm != null) { ltm.setRockInX(rockXValue); } else { MGlobal.displayError("Failed to get rock transform matrix"); } blockHandle.setClean(); // Mark the matrix as dirty so that DG information // will update. dirtyMatrix(); return; } base.validateAndSetValue(plug, handle, context); }
private void Compile(string filepath, string sourceCode) { var options = ScriptOptions.Default .WithReferences(Assembly.GetExecutingAssembly()) .WithReferences(typeof(object).Assembly) .WithReferences(Path.Combine(MayaRootPath, "bin", "openmayacs.dll")) .WithFilePath(filepath); _script = CSharpScript.Create(sourceCode, options); var diags = _script.Compile(); if (diags.Length > 0) { foreach (var diag in diags) { MGlobal.displayError(diag.ToString()); } throw new InvalidProgramException(); } }
// This function is a utility that can be used to extract vector values from // plugs. // private MVector vectorPlugValue(MPlug plug) { if (plug.numChildren == 3) { double x, y, z; MPlug rx = plug.child(0); MPlug ry = plug.child(1); MPlug rz = plug.child(2); x = rx.asDouble(); y = ry.asDouble(); z = rz.asDouble(); MVector result = new MVector(x, y, z); return(result); } else { MGlobal.displayError("Expected 3 children for plug " + plug.name); MVector result = new MVector(0, 0, 0); return(result); } }
// Install a node added callback for the node specified // by dagPath. private static void installNodeAddedCallback(MDagPath dagPath) { if (dagPath == null) { return; } MObject dagNode = dagPath.node; if (dagNode.isNull) { return; } try { dagNode.NodeAddedToModel += userNodeAddedCB; } catch (System.Exception) { MGlobal.displayError("Failed to install node added to model callback.\n"); } }
private void ReadNew(BinaryReader br) { uint fileSize = br.ReadUInt32(); uint formatToken = br.ReadUInt32(); uint version = br.ReadUInt32(); if (version != 0) { MGlobal.displayError("SKLFile:ReadNew - Unsupported Version: " + version); throw new Exception("Unsupported SKL version: " + version); } ushort flags = br.ReadUInt16(); ushort jointCount = br.ReadUInt16(); uint influencesCount = br.ReadUInt32(); int jointsOffset = br.ReadInt32(); int jointIndicesOffset = br.ReadInt32(); int influencesOffset = br.ReadInt32(); int nameOffset = br.ReadInt32(); int assetNameOffset = br.ReadInt32(); int boneNamesOffset = br.ReadInt32(); int reservedOffset1 = br.ReadInt32(); int reservedOffset2 = br.ReadInt32(); int reservedOffset3 = br.ReadInt32(); int reservedOffset4 = br.ReadInt32(); int reservedOffset5 = br.ReadInt32(); if (jointsOffset > 0 && jointCount != 0) //wesmart { br.BaseStream.Seek(jointsOffset, SeekOrigin.Begin); for (int i = 0; i < jointCount; i++) { this.Joints.Add(new SKLJoint(br, false)); } } if (influencesOffset > 0 && influencesCount != 0) { br.BaseStream.Seek(influencesOffset, SeekOrigin.Begin); for (int i = 0; i < influencesCount; i++) { this.Influences.Add(br.ReadInt16()); } } if (jointIndicesOffset > 0 && jointCount != 0) { br.BaseStream.Seek(jointIndicesOffset, SeekOrigin.Begin); for (int i = 0; i < jointCount; i++) { short index = br.ReadInt16(); br.ReadInt16(); //pad uint hash = br.ReadUInt32(); this.JointIndices.Add(hash, index); } } if (nameOffset > 0) { br.BaseStream.Seek(nameOffset, SeekOrigin.Begin); this.Name = Text.ReadZeroTerminatedString(br); MGlobal.displayInfo("SKNFile - Name: " + this.Name); } if (assetNameOffset > 0) { br.BaseStream.Seek(assetNameOffset, SeekOrigin.Begin); this.AssetName = Text.ReadZeroTerminatedString(br); MGlobal.displayInfo("SKNFile - Asset Name: " + this.AssetName); } }
public static StaticObject Create() { MDagPath meshDagPath = new MDagPath(); MItSelectionList selectionIterator = MayaHelper.GetActiveSelectionListIterator(MFn.Type.kMesh); selectionIterator.getDagPath(meshDagPath); MFnMesh mesh = new MFnMesh(meshDagPath); selectionIterator.next(); if (!selectionIterator.isDone) { MGlobal.displayError("StaticObject:Create - More than 1 mesh is selected"); throw new Exception("StaticObject:Create - More than 1 mesh is selected"); } if (!mesh.IsTriangulated()) { MGlobal.displayError("StaticObject:Create - Mesh isn't triangulated"); throw new Exception("StaticObject:Create - Mesh isn't triangulated"); } if (mesh.ContainsHoles()) { MGlobal.displayError("StaticObject:Create - Mesh Contains holes"); throw new Exception("StaticObject:Create - Mesh Contains holes"); } MayaMeshData meshData = mesh.GetMeshData(); Dictionary <int, string> shaderNames = new Dictionary <int, string>(); List <StaticObjectFace> faces = new List <StaticObjectFace>(); //Build Shader Name map for (int i = 0; i < meshData.ShaderIndices.Count; i++) { int shaderIndex = meshData.ShaderIndices[i]; if (!shaderNames.ContainsKey(shaderIndex)) { MPlug shaderPlug = new MFnDependencyNode(meshData.Shaders[shaderIndex]).findPlug("surfaceShader"); MPlugArray plugArray = new MPlugArray(); shaderPlug.connectedTo(plugArray, true, false); MFnDependencyNode material = new MFnDependencyNode(shaderPlug[0].node); shaderNames.Add(shaderIndex, material.name); } } //Construct faces int currentIndex = 0; for (int polygonIndex = 0; polygonIndex < mesh.numPolygons; polygonIndex++) { int shaderIndex = meshData.ShaderIndices[polygonIndex]; uint[] faceIndices = { (uint)meshData.TriangleVertices[currentIndex], (uint)meshData.TriangleVertices[currentIndex + 1], (uint)meshData.TriangleVertices[currentIndex + 2] }; Vector2[] uvs = { new Vector2(meshData.UArray[currentIndex], 1 - meshData.VArray[currentIndex]), new Vector2(meshData.UArray[currentIndex + 1], 1 - meshData.VArray[currentIndex + 1]), new Vector2(meshData.UArray[currentIndex + 2], 1 - meshData.VArray[currentIndex + 2]) }; faces.Add(new StaticObjectFace(faceIndices, shaderNames[shaderIndex], uvs)); currentIndex += 3; } return(new StaticObject(CreateSubmeshes(meshData.VertexArray.ToVector3List(), new List <ColorRGBA4B>(), faces))); }
public static void ExportXAnim(string FilePath, XAnimType FileType, bool Grab = true, bool ExportTagAlign = false) { // Configure scene using (var MayaCfg = new MayaSceneConfigure()) { // First, get the current selection var ExportObjectList = new MSelectionList(); MGlobal.getActiveSelectionList(ExportObjectList); // If empty, select all joints if (ExportObjectList.DependNodes(MFn.Type.kJoint).Count() == 0) { // Select all joints MGlobal.executeCommand("string $selected[] = `ls -type joint`; select -r $selected;"); // Get it again MGlobal.getActiveSelectionList(ExportObjectList); } // If still empty, error blank scene if (ExportObjectList.DependNodes(MFn.Type.kJoint).Count() == 0) { MGlobal.displayError("[CODTools] The current scene has no joints..."); return; } // Progress MayaCfg.StartProgress("Exporting XAnim...", ((int)ExportObjectList.length + Math.Max((MayaCfg.SceneEnd - MayaCfg.SceneStart) + 1, 1))); // Create new anim var Result = new XAnim(System.IO.Path.GetFileNameWithoutExtension(FilePath)); // 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 UniqueBones = new HashSet <string>(); var JointControllers = new List <MFnIkJoint>(); foreach (var Joint in ExportObjectList.DependNodes(MFn.Type.kJoint)) { // Step MayaCfg.StepProgress(); // Grab the controller var Path = CODXModel.GetObjectDagPath(Joint); var Controller = new MFnIkJoint(Path); // Create a new bone var TagName = CODXModel.CleanNodeName(Controller.name); if (UniqueBones.Contains(TagName)) { continue; } UniqueBones.Add(TagName); // Add to the controller list JointControllers.Add(Controller); // Add to the part list Result.Parts.Add(new Part(TagName)); } // Add TAG_ALIGN if (ExportTagAlign) { Result.Parts.Add(new Part("TAG_ALIGN")); } // Iterate over the frame range, then generate part frames for (int i = MayaCfg.SceneStart; i < (MayaCfg.SceneEnd + 1); i++) { // Step and set time MayaCfg.StepProgress(); MayaCfg.SetTime(i); // Iterate over the parts for this time for (int p = 0; p < JointControllers.Count; p++) { // Make new frame var NewFrame = new PartFrame(); // Fetch the world-space position and rotation var WorldPosition = JointControllers[p].getTranslation(MSpace.Space.kWorld); var WorldRotation = new MQuaternion(MQuaternion.identity); JointControllers[p].getRotation(WorldRotation, MSpace.Space.kWorld); // Create the matrix NewFrame.Offset = WorldPosition * (1 / 2.54); NewFrame.RotationMatrix = WorldRotation.asMatrix; // Add it Result.Parts[p].Frames.Add(NewFrame); } // Add TAG_ALIGN if (ExportTagAlign) { var NewFrame = new PartFrame(); NewFrame.Offset = new MVector(0, 0, 0); NewFrame.RotationMatrix = new MMatrix(); Result.Parts[JointControllers.Count].Frames.Add(NewFrame); } } // Reset time MayaCfg.SetTime(MayaCfg.SceneStart); // Grab XAnim notetracks if (Grab) { LoadNotetracks(ref Result); } // Write switch (FileType) { case XAnimType.Export: Result.WriteExport(FilePath); break; case XAnimType.Bin: Result.WriteBin(FilePath); break; case XAnimType.SiegeAnimSource: Result.WriteSiegeSource(FilePath); break; } } // Log complete MGlobal.displayInfo(string.Format("[CODTools] Exported {0}", System.IO.Path.GetFileName(FilePath))); }
private static void SortJoints(ref XModel Model, List <string> ParentStack, string CosmeticRoot = "") { // Handle no bones if (Model.Bones.Count == 0) { Model.Bones.Add(new Bone("tag_origin")); } // Prepare to sort, first, assign parent index, if any for (int i = 0; i < ParentStack.Count; i++) { // Assign parent Model.Bones[i].ParentIndex = Model.Bones.FindIndex(x => x.TagName == ParentStack[i]); } // Build root tree var RootJointList = Model.Bones.Where(x => x.ParentIndex == -1); if (RootJointList.Count() == 0) { MGlobal.displayError("[CODTools] No root joint was found..."); return; } else if (RootJointList.Count() > 1) { MGlobal.displayError("[CODTools] Multiple root joints not supported in Call of Duty..."); return; } var RootJoint = RootJointList.FirstOrDefault(); // Prepare root tree var RootTree = new List <Bone>() { RootJoint }; BuildRootTree(RootJoint, ref RootTree, ref Model); // Mark cosmetic bones using the root if (CosmeticRoot != string.Empty) { // Fetch it if it's in the list var CosmeticBone = RootTree.Find(x => x.TagName == CosmeticRoot.Trim()); if (CosmeticBone != null) { // Recursive iterate through children until marked MarkCosmetic(ref RootTree, RootTree.IndexOf(CosmeticBone)); } } // Ensure cosmetics are at the end of the tree var SortedCosmetic = RootTree.OrderBy(x => x.isCosmetic).ToList(); var SortedDict = new Dictionary <int, int>(); // Iterate and resort foreach (var Sorted in SortedCosmetic) { if (Sorted.ParentIndex == -1) { continue; } Sorted.ParentIndex = SortedCosmetic.FindIndex(x => x.TagName == RootTree[Sorted.ParentIndex].TagName); } // Assign final sorted indicies Model.Bones = SortedCosmetic; }
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))); }
//====================================================================== // // Do the metadata creation. The metadata will be randomly initialized // based on the channel type and the structure specified. For recognized // components the number of metadata elements will correspond to the count // of components in the selected mesh, otherwise a random number of metadata // elements between 1 and 100 will be created (at consecutive indices). // // The previously existing metadata is preserved for later undo. // override public void doIt(MArgList args) { MArgDatabase argsDb = new MArgDatabase(syntax, args); checkArgs(ref argsDb); clearResult(); MColorArray myColorArray = new MColorArray(); MFnDependencyNode node = new MFnDependencyNode(fObj); // Get the current metadata (empty if none yet) Associations newMetadata = new Associations(node.metadata); Channel newChannel = newMetadata.channel("vertex"); // Check to see if the requested stream name already exists Stream oldStream = newChannel.dataStream(fStreamName); if (oldStream != null) { string fmt = MStringResource.getString(MetaDataRegisterMStringResources.kCreateMetadataHasStream); string msg = String.Format(fmt, fStreamName); MGlobal.displayError(msg); return; } StreamForType <MyStructureClass> newStream = new StreamForType <MyStructureClass>(fStreamName); int indexCount = fMesh.numVertices; Random rndIndexCount = new Random(); // Fill specified stream ranges with random data int m; Random rnd = new Random(); for (m = 0; m < indexCount; ++m) { // Walk each structure member and fill with random data // tailored to the member data type. MyStructureClass myClass = new MyStructureClass(); // int myClass.a = rnd.Next(Int32.MinValue, Int32.MaxValue); // float myClass.b = (float)rnd.NextDouble(); // string string[] randomStrings = new string[] { "banana", "tomatoe", "apple", "pineapple", "apricot", "pepper", "olive", "grapefruit" }; int index = rnd.Next(randomStrings.Length); myClass.c = randomStrings[index]; // bool int randomInt = rnd.Next(0, 2); myClass.d = randomInt == 1 ? true : false; myClass.e = rnd.Next(Int32.MinValue, Int32.MaxValue); myClass.f = rnd.Next(Int32.MinValue, Int32.MaxValue); myClass.xyz[0] = (float)rnd.NextDouble(); myClass.xyz[1] = (float)rnd.NextDouble(); myClass.xyz[2] = (float)rnd.NextDouble(); newStream[m] = myClass; } newChannel.setDataStream(newStream); newMetadata.setChannel(newChannel); // Note: the following will not work if "obj" is a shape constructed by a source object // You need to delete the history of the shape before calling this... fDGModifier.setMetadata(fObj, newMetadata); fDGModifier.doIt(); Associations meshMetadata = fMesh.metadata; // This code is for debugging only { Channel chn = meshMetadata["vertex"]; Console.WriteLine("Channel : type = {0}, nbStreams = {1}", chn.nameProperty, chn.dataStreamCount); Stream chnStream = chn[fStreamName]; Structure strct = chnStream.structure; var strm = new StreamForType <MyStructureClass>(chnStream); Console.WriteLine("Stream : name = {0}, nbElements = {1}", chnStream.name, chnStream.Count); var tomatoes = strm.Where((KeyValuePair <Index, MyStructureClass> keyvalue) => keyvalue.Value.c == "tomatoe"); foreach (var keyvalue in tomatoes) // foreach (MyStructureClass myClass in strm.Values ) { Console.WriteLine("Vertex #{0}, a = {1}", keyvalue.Key.asString, keyvalue.Value.a.ToString()); Console.WriteLine("Vertex #{0}, b = {1}", keyvalue.Key.asString, keyvalue.Value.b.ToString()); Console.WriteLine("Vertex #{0}, c = {1}", keyvalue.Key.asString, keyvalue.Value.c.ToString()); Console.WriteLine("Vertex #{0}, d = {1}", keyvalue.Key.asString, keyvalue.Value.d.ToString()); Console.WriteLine("Vertex #{0}, e = {1}", keyvalue.Key.asString, keyvalue.Value.e.ToString()); Console.WriteLine("Vertex #{0}, f = {1}", keyvalue.Key.asString, keyvalue.Value.f.ToString()); Console.WriteLine("Vertex #{0}, xyz = {1},{2},{3}", keyvalue.Key.asString, keyvalue.Value.xyz[0].ToString(), keyvalue.Value.xyz[1].ToString(), keyvalue.Value.xyz[2].ToString()); Console.WriteLine("Vertex #{0}, abc = {1},{2}", keyvalue.Key.asString, keyvalue.Value.abc[0], keyvalue.Value.abc[1]); } } }
private static Dictionary <string, MayaM2Bone> ExtractJoints(List <MayaM2Sequence> seqList) { var jointMap = new Dictionary <string, MayaM2Bone>(); //Goal of iteration : Extract raw joint data and store it in intermediate object, MayaM2Bone var processedJoints = new HashSet <string>(); for (var jointIter = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kJoint); !jointIter.isDone; jointIter.next()) { var jointPath = new MDagPath(); jointIter.getPath(jointPath); if (processedJoints.Contains(jointPath.fullPathName)) { continue; } MGlobal.displayInfo("Extracting raw data of " + jointPath.fullPathName); var joint = new MFnIkJoint(jointPath); var mayaBone = new MayaM2Bone(); jointMap[jointPath.fullPathName] = mayaBone; // Hierarchy var isRoot = joint.parentCount == 0 || !joint.parent(0).hasFn(MFn.Type.kJoint); if (!isRoot) { var parentPath = new MDagPath(); MDagPath.getAPathTo(joint.parent(0), parentPath); if (!jointMap.ContainsKey(parentPath.fullPathName)) { MGlobal.displayError("\tParent is not referenced. Crash incoming. Path : " + parentPath.fullPathName); } jointMap[jointPath.fullPathName].Parent = jointMap[parentPath.fullPathName]; } //Note : M2Bone.submesh_id is wrong in the wiki. Do not try to compute it. // Label jointMap[jointPath.fullPathName].Type = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".type"); jointMap[jointPath.fullPathName].OtherType = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".otherType"); jointMap[jointPath.fullPathName].Side = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".side"); // Base translation is used to compute position MAnimControl.currentTime = 0; jointMap[jointPath.fullPathName].BaseTranslation = joint.getTranslation(MSpace.Space.kTransform); foreach (var seq in seqList) { var transData = new List <Tuple <uint, MVector> >(); var rotData = new List <Tuple <uint, MQuaternion> >(); var scaleData = new List <Tuple <uint, MVector> >(); for (var i = seq.Start; i < seq.End; i += 33) //TODO FIXME What if not multiple of 33 ? { //Get data for this joint for this frame MAnimControl.currentTime = new MTime(i, MTime.Unit.kMilliseconds); var translation = joint.getTranslation(MSpace.Space.kTransform); var rotation = new MQuaternion(); joint.getRotation(rotation, MSpace.Space.kTransform); var scaleArray = new double[3]; joint.getScale(scaleArray); var scale = new MVector(scaleArray); if (!translation.isEquivalent(MVector.zero, Epsilon)) { var previousIsTheSame = transData.Count > 0 && transData.Last().Item2.isEquivalent(translation, Epsilon); if (!previousIsTheSame) { transData.Add(new Tuple <uint, MVector>((uint)(i - seq.Start), translation)); } } if (!rotation.isEquivalent(MQuaternion.identity, Epsilon)) { var previousIsTheSame = rotData.Count > 0 && rotData.Last().Item2.isEquivalent(rotation, Epsilon); if (!previousIsTheSame) { rotData.Add(new Tuple <uint, MQuaternion>((uint)(i - seq.Start), rotation)); } } if (!scale.isEquivalent(MVector.one, Epsilon)) { var previousIsTheSame = scaleData.Count > 0 && scaleData.Last().Item2.isEquivalent(scale, Epsilon); if (!previousIsTheSame) { scaleData.Add(new Tuple <uint, MVector>((uint)(i - seq.Start), scale)); } } } if (transData.Count > 0) { jointMap[joint.fullPathName].Translation.Add(transData); } if (rotData.Count > 0) { jointMap[joint.fullPathName].Rotation.Add(rotData); } if (scaleData.Count > 0) { jointMap[joint.fullPathName].Scale.Add(scaleData); } } processedJoints.Add(jointPath.fullPathName); } //Goal of iteration : apply transformations to joint data & their children processedJoints.Clear(); for (var jointIter = new MItDag(MItDag.TraversalType.kBreadthFirst, MFn.Type.kJoint); !jointIter.isDone; jointIter.next()) { var jointPath = new MDagPath(); jointIter.getPath(jointPath); if (processedJoints.Contains(jointPath.fullPathName)) { continue; } MGlobal.displayInfo("Applying joint orient of " + jointPath.fullPathName); var joint = new MFnIkJoint(jointPath); var jointOrient = new MQuaternion(); joint.getOrientation(jointOrient); for (uint i = 0; i < joint.childCount; i++) { if (!joint.child(i).hasFn(MFn.Type.kJoint)) { continue; } var childFn = new MFnIkJoint(joint.child(i)); MGlobal.displayInfo("\tto " + childFn.fullPathName + ";"); jointMap[childFn.fullPathName].RotateTranslation(jointOrient); } processedJoints.Add(jointPath.fullPathName); } return(jointMap); }
//====================================================================== // // Do the metadata creation. The metadata will be randomly initialized // based on the channel type and the structure specified. For recognized // components the number of metadata elements will correspond to the count // of components in the selected mesh, otherwise a random number of metadata // elements between 1 and 100 will be created (at consecutive indices). // // The previously existing metadata is preserved for later undo. // override public void doIt(MArgList args) { MArgDatabase argsDb = new MArgDatabase(syntax, args); checkArgs(ref argsDb); clearResult(); uint numNodes = fNodes.length; int i; for (i = 0; i < numNodes; ++i) { // fNodes[i] is the transform not the shape itself MFnDagNode dagNode = new MFnDagNode(fNodes[i]); MObject obj = dagNode.child(0); // obj is the shape, which is where we can add the meta data MFnDependencyNode node = new MFnDependencyNode(obj); // Get the current metadata (empty if none yet) Associations newMetadata = new Associations(node.metadata); Channel newChannel = newMetadata.channel(fChannelType); // Check to see if the requested stream name already exists Stream oldStream = newChannel.dataStream(fStreamName); if (oldStream != null) { string fmt = MStringResource.getString(MetaDataRegisterMStringResources.kCreateMetadataHasStream); string msg = String.Format(fmt, fStreamName); MGlobal.displayError(msg); continue; } Stream newStream = new Stream(fStructure, fStreamName); string strmName = newStream.name; int indexCount = 0; MFnMesh mesh = null; Random rndIndexCount = new Random(); // Treat the channel type initializations different for meshes if (obj.hasFn(MFn.Type.kMesh)) { mesh = new MFnMesh(obj); // Get mesh-specific channel type parameters if (fChannelType == "face") { indexCount = mesh.numPolygons; } else if (fChannelType == "edge") { indexCount = mesh.numEdges; } else if (fChannelType == "vertex") { indexCount = mesh.numVertices; } else if (fChannelType == "vertexFace") { indexCount = mesh.numFaceVertices; } else { // Set a random number between 1 to 100 indexCount = rndIndexCount.Next(1, 100); } } else { // Create generic channel type information indexCount = rndIndexCount.Next(1, 100); } // Fill specified stream ranges with random data int structureMemberCount = fStructure.memberCount; uint m, n, d; Random rnd = new Random(); for (m = 0; m < indexCount; ++m) { // Walk each structure member and fill with random data // tailored to the member data type. Handle handle = new Handle(fStructure); for (n = 0; n < structureMemberCount; ++n) { handle.setPositionByMemberIndex(n); switch (handle.dataType) { case Member.eDataType.kBoolean: { bool[] data = new bool[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int randomInt = rnd.Next(0, 2); bool randomBool = randomInt == 1 ? true : false; data[d] = randomBool; } handle.asBooleanArray = data; break; } case Member.eDataType.kDouble: { double[] data = new double[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000000.0.0 and 2000000000.0.0 data[d] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; } handle.asDoubleArray = data; break; } case Member.eDataType.kDoubleMatrix4x4: { double[] data = new double[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { data[d * 16 + 0] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 1] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 2] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 3] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 4] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 5] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 6] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 7] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 8] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 9] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 10] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 11] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 12] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 13] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 14] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; data[d * 16 + 15] = rnd.NextDouble() * 4000000000.0 - 2000000000.0; } handle.asDoubleMatrix4x4 = data; break; } case Member.eDataType.kFloat: { float[] data = new float[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; } handle.asFloatArray = data; break; } case Member.eDataType.kFloatMatrix4x4: { float[] data = new float[handle.dataLength * 16]; for (d = 0; d < handle.dataLength; ++d) { // Set a random number between -2000000.0 and 2000000.0 data[d * 16 + 0] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 1] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 2] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 3] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 4] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 5] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 6] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 7] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 8] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 9] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 10] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 11] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 12] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 13] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 14] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; data[d * 16 + 15] = (float)rnd.NextDouble() * 4000000.0f - 2000000.0f; } handle.asFloatMatrix4x4 = data; break; } case Member.eDataType.kInt8: { sbyte[] data = new sbyte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (sbyte)rnd.Next(SByte.MinValue, SByte.MaxValue + 1); } handle.asInt8Array = data; break; } case Member.eDataType.kInt16: { short[] data = new short[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (short)rnd.Next(Int16.MinValue, Int16.MaxValue + 1); } handle.asInt16Array = data; break; } case Member.eDataType.kInt32: { int[] data = new int[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next returns a number between [arg1,arg2[ // but unfortunately I can't pass Int32.MaxValue+1 here.... data[d] = rnd.Next(Int32.MinValue, Int32.MaxValue); } handle.asInt32Array = data; break; } case Member.eDataType.kInt64: { long[] data = new long[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { // rnd.Next() gives a number between [0,Int32 data[d] = (long)rnd.Next(Int32.MinValue, Int32.MaxValue); if (data[d] >= 0) { data[d] *= Int64.MaxValue / Int32.MaxValue; } else { data[d] *= Int64.MinValue / Int32.MinValue; } } handle.asInt64Array = data; break; } case Member.eDataType.kUInt8: { byte[] data = new byte[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (byte)rnd.Next(0, Byte.MaxValue + 1); } handle.asUInt8Array = data; break; } case Member.eDataType.kUInt16: { ushort[] data = new ushort[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (ushort)rnd.Next(0, UInt16.MaxValue + 1); } handle.asUInt16Array = data; break; } case Member.eDataType.kUInt32: { uint[] data = new uint[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = (uint)rnd.Next(); } handle.asUInt32Array = data; break; } case Member.eDataType.kUInt64: { ulong[] data = new ulong[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { data[d] = ((ulong)rnd.Next()) * UInt64.MaxValue / UInt32.MaxValue; } handle.asUInt64Array = data; break; } case Member.eDataType.kString: { string[] randomStrings = new string[] { "banana", "tomatoe", "apple", "pineapple", "apricot", "pepper", "olive", "grapefruit" }; string[] data = new string[handle.dataLength]; for (d = 0; d < handle.dataLength; ++d) { int index = rnd.Next(randomStrings.Length); data[d] = randomStrings[index]; } handle.asStringArray = data; break; } default: { Debug.Assert(false, "This should never happen"); break; } } } newStream.setElement(new Index(m), handle); } newChannel.setDataStream(newStream); newMetadata.setChannel(newChannel); // Note: the following will not work if "obj" is a shape constructed by a source object // You need to delete the history of the shape before calling this... fDGModifier.setMetadata(obj, newMetadata); fDGModifier.doIt(); // Set the result to the number of actual metadata values set as a // triple value: // (# nodes, # metadata elements, # members per element) // MIntArray theResult = new MIntArray(); theResult.append((int)fNodes.length); theResult.append((int)indexCount); theResult.append((int)structureMemberCount); setResult(theResult); } }