public override void deform(MDataBlock block, MItGeometry iter, MMatrix m, uint multiIndex) { MDataHandle angleData = block.inputValue(angle); MDataHandle envData = block.inputValue(envelope); double magnitude = angleData.asDouble; float env = envData.asFloat; for (; !iter.isDone; iter.next()) { MPoint pt = iter.position(); // do the twist // double ff = magnitude * pt.y * env; if (ff != 0.0) { double cct = Math.Cos(ff); double cst = Math.Sin(ff); double tt = pt.x * cct - pt.z * cst; pt.z = pt.x * cst + pt.z * cct; pt.x = tt; ; } iter.setPosition(pt); } }
public ModelVisual3D MakeVisualModel(MDagPath path) { var mesh = new MFnMesh(path); var r = new ModelVisual3D(); r.Content = MakeModel(mesh); r.Transform = new Transform3DGroup(); Transform3DGroup transformGroup = r.Transform as Transform3DGroup; MTransformationMatrix matrix = new MTransformationMatrix(path.inclusiveMatrix); //MVector tr =matrix.getTranslation (MSpace.Space.kWorld) ; //TranslateTransform3D translation =new TranslateTransform3D (tr.x, tr.y, tr.z) ; //transformGroup.Children.Add (translation) ; //double x =0, y =0, z =0, w =0 ; //matrix.getRotationQuaternion (ref x, ref y, ref z, ref w, MSpace.Space.kWorld) ; //QuaternionRotation3D rotation =new QuaternionRotation3D (new Quaternion (x, y, z, w)) ; //transformGroup.Children.Add (new RotateTransform3D (rotation)) ; //double [] scales =new double [3] ; //matrix.getScale (scales, MSpace.Space.kWorld) ; //ScaleTransform3D scale =new ScaleTransform3D (scales [0], scales [1], scales [2]) ; //transformGroup.Children.Add (scale) ; MMatrix mat = matrix.asMatrixProperty; Matrix3D matrix3d = new Matrix3D(mat [0, 0], mat [0, 1], mat [0, 2], mat [0, 3], mat [1, 0], mat [1, 1], mat [1, 2], mat [1, 3], mat [2, 0], mat [2, 1], mat [2, 2], mat [2, 3], mat [3, 0], mat [3, 1], mat [3, 2], mat [3, 3]); MatrixTransform3D matrixTransform = new MatrixTransform3D(matrix3d); transformGroup.Children.Add(matrixTransform); return(r); }
private BabylonMatrix ConvertMayaToBabylonMatrix(MMatrix mMatrix) { var transformationMatrix = new MTransformationMatrix(mMatrix); // Retreive TRS vectors from matrix float[] position = transformationMatrix.getTranslation(); float[] rotationQuaternion = transformationMatrix.getRotationQuaternion(); float[] scaling = transformationMatrix.getScale(); // Switch coordinate system at object level position[2] *= -1; rotationQuaternion[0] *= -1; rotationQuaternion[1] *= -1; // Apply unit conversion factor to meter position[0] *= scaleFactorToMeters; position[1] *= scaleFactorToMeters; position[2] *= scaleFactorToMeters; // The composed matrix return(BabylonMatrix.Compose(new BabylonVector3(scaling[0], scaling[1], scaling[2]), // scaling new BabylonQuaternion(rotationQuaternion[0], rotationQuaternion[1], rotationQuaternion[2], rotationQuaternion[3]), // rotation new BabylonVector3(position[0], position[1], position[2]) // position )); }
override public void deform(MDataBlock block, MItGeometry iter, MMatrix m, uint multiIndex) { MDataHandle angleData = block.inputValue(angle); MDataHandle envData = block.inputValue(envelope); double magnitude = angleData.asDouble; float env = envData.asFloat; for (; !iter.isDone; iter.next()) { MPoint pt = iter.position(); // do the twist // double ff = magnitude * pt.y * env; if (ff != 0.0) { double cct = Math.Cos(ff); double cst = Math.Sin(ff); double tt = pt.x * cct - pt.z * cst; pt.z = pt.x * cst + pt.z * cct; pt.x = tt;; } iter.setPosition(pt); } }
private static double[] TransferMatrixToDouble(MMatrix mm) { double[] res = new double[16] { mm[0, 0], mm[0, 1], mm[0, 2], mm[0, 3], mm[1, 0], mm[1, 1], mm[1, 2], mm[1, 3], mm[2, 0], mm[2, 1], mm[2, 2], mm[2, 3], mm[3, 0], mm[3, 1], mm[3, 2], mm[3, 3] }; return(res); }
private void getXformData(MayaXform xform) { // Get the maya transform node to get data from. MFnTransform mayaXform = new MFnTransform(xform.mayaObjectPath); // Get the matrix. MMatrix mayaMatrix = mayaXform.transformationMatrix; mayaMatrix.get(xform.matrix); }
public static float[] toArray(this MMatrix mMatrix, uint nbRow = 4, uint nbCol = 4) { float[] array = new float[nbRow * nbCol]; for (uint row = 0; row < nbRow; row++) { for (uint col = 0; col < nbCol; col++) { array[row * nbCol + col] = (float)mMatrix[row, col]; } } return(array); }
public override MMatrix asMatrix() { // Get the current transform matrix MMatrix m = base.asMatrix(); // Initialize the new matrix we will calculate MTransformationMatrix tm = new MTransformationMatrix(m); // Find the current rotation as a quaternion MQuaternion quat = rotation(); // Convert the rocking value in degrees to radians DegreeRadianConverter conv = new DegreeRadianConverter(); double newTheta = conv.degreesToRadians(getRockInX()); quat.setToXAxis(newTheta); // Apply the rocking rotation to the existing rotation tm.addRotationQuaternion(quat.x, quat.y, quat.z, quat.w, MSpace.Space.kTransform); // Let Maya know what the matrix should be return(tm.asMatrixProperty); }
public void setMatrix(MMatrix m) { matrix[0, 0] = m[0, 0]; matrix[0, 1] = m[0, 1]; matrix[0, 2] = m[0, 2]; matrix[0, 3] = m[0, 3]; matrix[1, 0] = m[1, 0]; matrix[1, 1] = m[1, 1]; matrix[1, 2] = m[1, 2]; matrix[1, 3] = m[1, 3]; matrix[2, 0] = m[2, 0]; matrix[2, 1] = m[2, 1]; matrix[2, 2] = m[2, 2]; matrix[2, 3] = m[2, 3]; matrix[3, 0] = m[3, 0]; matrix[3, 1] = m[3, 1]; matrix[3, 2] = m[3, 2]; matrix[3, 3] = m[3, 3]; }
public void setMatrix( MMatrix m) { matrix[0, 0] = m[0,0]; matrix[0, 1] = m[0,1]; matrix[0, 2] = m[0,2]; matrix[0, 3] = m[0,3]; matrix[1, 0] = m[1,0]; matrix[1, 1] = m[1,1]; matrix[1, 2] = m[1,2]; matrix[1, 3] = m[1,3]; matrix[2, 0] = m[2,0]; matrix[2, 1] = m[2,1]; matrix[2, 2] = m[2,2]; matrix[2, 3] = m[2,3]; matrix[3, 0] = m[3,0]; matrix[3, 1] = m[3,1]; matrix[3, 2] = m[3,2]; matrix[3, 3] = m[3,3]; }
override public void deform(MDataBlock block, MItGeometry iter, MMatrix m, uint multiIndex) { MDataHandle angleData = block.inputValue(angle); MDataHandle envData = block.inputValue(envelope); double magnitude = angleData.asDouble; float env = envData.asFloat; var startTime = DateTime.Now; var poses = new MPointArray(); iter.allPositions(poses); //var newPos = VulankCompute.ComputeData(poses, (float)magnitude, env); VulankCompute.ComputeData(poses, (float)magnitude, env); iter.setAllPositions(poses); var timeSpand = DateTime.Now - startTime; MGlobal.displayInfo(string.Format("---------- total time : {0}", timeSpand.TotalSeconds)); //for (; !iter.isDone; iter.next()) //{ //MPoint pt = iter.position(); //// do the twist //// //double ff = magnitude * pt.y * env; //if (ff != 0.0) //{ // double cct = Math.Cos(ff); // double cst = Math.Sin(ff); // double tt = pt.x * cct - pt.z * cst; // pt.z = pt.x * cst + pt.z * cct; // pt.x = tt; ; //} //iter.setPosition(pt); //} }
internal static CoordinateSystem mLocatorFromName(string dagName, string space) { MDagPath dagPath = DMInterop.getDagNode(dagName); MSpace.Space mspace = MSpace.Space.kWorld; Enum.TryParse(space, out mspace); // MObject obj = DMInterop.getDependNode(dagName); MMatrix worldPos = dagPath.inclusiveMatrix; double x = worldPos[3, 0]; double y = worldPos[3, 1]; double z = worldPos[3, 2]; MEulerRotation rot = new MEulerRotation(); double xr = worldPos[3, 0]; double yr = worldPos[3, 1]; double zr = worldPos[3, 2]; //MFnTransform loc = new MFnTransform(dagShape.node); //var vec = loc.transformation.getTranslation(mspace); //return Point.ByCoordinates(vec.x, vec.y, vec.z); ; CoordinateSystem cs; if (MGlobal.isZAxisUp) { cs = CoordinateSystem.ByOrigin(x, y, z); cs.Rotate(cs.Origin, Vector.XAxis(), x); cs.Rotate(cs.Origin, Vector.YAxis(), y); cs.Rotate(cs.Origin, Vector.ZAxis(), z); return(cs); } else { cs = CoordinateSystem.ByOrigin(x, -z, y); cs.Rotate(cs.Origin, Vector.XAxis(), x); cs.Rotate(cs.Origin, Vector.YAxis(), y); cs.Rotate(cs.Origin, Vector.ZAxis(), z); return(cs); } }
private List <BabylonAnimation> GetAnimationsFrameByFrame(MFnTransform mFnTransform) { int start = GetMinTime()[0]; int end = GetMaxTime()[0]; // Animations List <BabylonAnimation> animations = new List <BabylonAnimation>(); string[] babylonAnimationProperties = new string[] { "scaling", "rotationQuaternion", "position" }; Dictionary <string, List <BabylonAnimationKey> > keysPerProperty = new Dictionary <string, List <BabylonAnimationKey> >(); keysPerProperty.Add("scaling", new List <BabylonAnimationKey>()); keysPerProperty.Add("rotationQuaternion", new List <BabylonAnimationKey>()); keysPerProperty.Add("position", new List <BabylonAnimationKey>()); // get keys for (int currentFrame = start; currentFrame <= end; currentFrame++) { // get transformation matrix at this frame MDoubleArray mDoubleMatrix = new MDoubleArray(); MGlobal.executeCommand($"getAttr -t {currentFrame} {mFnTransform.fullPathName}.matrix", mDoubleMatrix); mDoubleMatrix.get(out float[] localMatrix); MMatrix matrix = new MMatrix(localMatrix); var transformationMatrix = new MTransformationMatrix(matrix); // Retreive TRS vectors from matrix var position = transformationMatrix.getTranslation(); var rotationQuaternion = transformationMatrix.getRotationQuaternion(); var scaling = transformationMatrix.getScale(); // Switch coordinate system at object level position[2] *= -1; rotationQuaternion[0] *= -1; rotationQuaternion[1] *= -1; // create animation key for each property for (int indexAnimation = 0; indexAnimation < babylonAnimationProperties.Length; indexAnimation++) { string babylonAnimationProperty = babylonAnimationProperties[indexAnimation]; BabylonAnimationKey key = new BabylonAnimationKey(); key.frame = currentFrame; switch (indexAnimation) { case 0: // scaling key.values = scaling.ToArray(); break; case 1: // rotationQuaternion key.values = rotationQuaternion.ToArray(); break; case 2: // position key.values = position.ToArray(); break; } keysPerProperty[babylonAnimationProperty].Add(key); } } // create animation for each property for (int indexAnimation = 0; indexAnimation < babylonAnimationProperties.Length; indexAnimation++) { string babylonAnimationProperty = babylonAnimationProperties[indexAnimation]; List <BabylonAnimationKey> keys = keysPerProperty[babylonAnimationProperty]; // Optimization OptimizeAnimations(keys, true); // Ensure animation has at least 2 frames if (keys.Count > 1) { var animationPresent = true; // Ensure animation has at least 2 non equal frames if (keys.Count == 2) { if (keys[0].values.IsEqualTo(keys[1].values)) { animationPresent = false; } } if (animationPresent) { // Create BabylonAnimation animations.Add(new BabylonAnimation() { dataType = indexAnimation == 1 ? (int)BabylonAnimation.DataType.Quaternion : (int)BabylonAnimation.DataType.Vector3, name = babylonAnimationProperty + " animation", framePerSecond = GetFPS(), loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle, property = babylonAnimationProperty, keys = keys.ToArray() }); } } } return(animations); }
public void setMatrix(MMatrix wvMatrix, MMatrix projMatrix) { mWorldViewMatrix = wvMatrix; mProjectionMatrix = projMatrix; }
public static string toString(this MMatrix mMatrix) { return(mMatrix == null ? "" : mMatrix.toArray().toString()); }
public override void tweakUsing( MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache, MArrayDataHandle handle ) // // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode when the // tweaks for the shape are stored on a separate tweak node. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // handle - handle to the attribute on the tweak node where the // tweaks should be stored // { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); bool updatePoints = (cachingMode == MVertexCachingMode.kUpdatePoints); MArrayDataBuilder builder = handle.builder(); MPoint delta = new MPoint(); MPoint currPt = new MPoint(); MPoint newPt = new MPoint(); int i=0; uint len = componentList.length; int cacheIndex = 0; uint cacheLen = (null != pointCache) ? pointCache.length : 0; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore points from the pointCache // if (len > 0) { // traverse the component list // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) { MDataHandle hdl = builder.addElement(idx); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // Tweak the points. If savePoints is true, also save the tweaks in the // pointCache. If updatePoints is true, add the new tweaks to the existing // data in the pointCache. // if (len > 0) { for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; if (savePoints) { pointCache.sizeIncrement = (uint)elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[elemIndex]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*(-1.0)); } else if (updatePoints && cacheIndex < cacheLen) { MPoint cachePt = pointCache[cacheIndex]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; cacheIndex++; } } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { MDataHandle hdl = builder.addElement((uint)idx); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[idx]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*-1.0); } else if (updatePoints && idx < cacheLen) { MPoint cachePt = pointCache[idx]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; } } } } // Set the builder into the handle. // handle.set(builder); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }
private static double[] TransferMatrixToDouble(MMatrix mm) { double[] res = new double[16] { mm[0, 0], mm[0, 1], mm[0, 2], mm[0, 3], mm[1, 0], mm[1, 1], mm[1, 2], mm[1, 3], mm[2, 0], mm[2, 1], mm[2, 2], mm[2, 3], mm[3, 0], mm[3, 1], mm[3, 2], mm[3, 3] }; return res; }
// // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // public override void transformUsing(MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache) { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); int i = 0, j = 0; uint len = componentList.length; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore the points based on the data provided in the pointCache attribute // uint cacheLen = pointCache.length; if (len > 0) { // traverse the component list // for ( i = 0; i < len && j < cacheLen; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && j < cacheLen; idx++, ++j ) { int elemIndex = fnComp.element( idx ); geomPtr.vertices[elemIndex] = pointCache[j]; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( int idx = 0; idx < len && j < cacheLen; ++idx, ++j ) { geomPtr.vertices[idx] = pointCache[j]; } } } else { // Transform the surface vertices with the matrix. // If savePoints is true, save the points to the pointCache. // if (len > 0) { // Traverse the componentList // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); uint elemCount = (uint)fnComp.elementCount; if (savePoints && 0 == i) { pointCache.sizeIncrement = elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( (int)idx ); if (savePoints) { pointCache.append(geomPtr.vertices[elemIndex]); } geomPtr.vertices[elemIndex].multiplyEqual( mat ); geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat ); } } } else { // If the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { if (savePoints) { pointCache.append(geomPtr.vertices[idx]); } geomPtr.vertices[idx].multiplyEqual( mat ); geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat ); } } } // Retrieve the value of the cached surface attribute. // We will set the new geometry data into the cached surface attribute // // Access the datablock directly. This code has to be efficient // and so we bypass the compute mechanism completely. // NOTE: In general we should always go though compute for getting // and setting attributes. // MDataBlock datablock = _forceCache(); MDataHandle cachedHandle = datablock.outputValue( cachedSurface ); apiMeshData cached = cachedHandle.asPluginData as apiMeshData; MDataHandle dHandle = datablock.outputValue( mControlPoints ); // If there is history then calculate the tweaks necessary for // setting the final positions of the vertices. // if ( hasHistory() && (null != cached) ) { // Since the shape has history, we need to store the tweaks (deltas) // between the input shape and the tweaked shape in the control points // attribute. // buildControlPoints( datablock, (int)geomPtr.vertices.length ); MArrayDataHandle cpHandle = new MArrayDataHandle( dHandle ); // Loop through the component list and transform each vertex. // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); cpHandle.jumpToElement( (uint)elemIndex ); MDataHandle pntHandle = cpHandle.outputValue(); double[] pnt = pntHandle.Double3; MPoint oldPnt = cached.fGeometry.vertices[elemIndex]; MPoint newPnt = geomPtr.vertices[elemIndex]; MVector offset = newPnt.minus( oldPnt ); pnt[0] += offset[0]; pnt[1] += offset[1]; pnt[2] += offset[2]; pntHandle.Double3 = pnt; } } } // Copy outputSurface to cachedSurface // if ( null == cached ) { MGlobal.displayInfo("NULL cachedSurface data found"); } else { cached.fGeometry = geomPtr; } MPlug pCPs = new MPlug( thisMObject(), mControlPoints ); pCPs.setValue(dHandle); // Moving vertices will likely change the bounding box. // computeBoundingBox( datablock ); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }
public bool selectVertices(MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) // // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create(MFn.Type.kMeshVertComponent); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if (singleSelection) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for (vertexIndex = 0; vertexIndex < numVertices; vertexIndex++) { MPoint currentPoint = geom.vertices[(int)vertexIndex]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2]); OpenGL.glEnd(); if (view.endSelect() > 0) // Hit count > 0 { selected = true; if (singleSelection) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual(alignmentMatrix); z = xformedPoint.z; if (closestPointVertexIndex < 0 || z > previousZ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement((int)vertexIndex); } } } // If single selection, insert the closest point into the array // if (selected && selectInfo.singleSelection) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual(path.inclusiveMatrix); } // Add the selected component to the selection list // if (selected) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add(path, surfaceComponent); MSelectionMask mask = new MSelectionMask(MSelectionMask.SelectionType.kSelectComponentsMask); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true); } return(selected); }
public static void draw(MDrawContext context, MUserData userData) { // This function is called by maya internal, .Net SDK has transfered MUserData to the derived one // Users don't need do the MUserData.getData(oldData) by themselves FootPrintData footData = MUserData.getData(userData) as FootPrintData; if (footData == null) { return; } MDAGDrawOverrideInfo objectOverrideInfo = footData.fDrawOV; if (objectOverrideInfo.fOverrideEnabled && !objectOverrideInfo.fEnableVisible) { return; } uint displayStyle = context.getDisplayStyle(); bool drawAsBoundingBox = (displayStyle & (uint)MFrameContext.DisplayStyle.kBoundingBox) != 0 || (footData.fDrawOV.fLOD == MDAGDrawOverrideInfo.DrawOverrideLOD.kLODBoundingBox); if (drawAsBoundingBox && !footData.fCustomBoxDraw) { return; } // get renderer Autodesk.Maya.OpenMayaRender.MHWRender.MRenderer theRenderer = Autodesk.Maya.OpenMayaRender.MHWRender.MRenderer.theRenderer(); if (theRenderer == null) { return; } // get state data MMatrix transform = context.getMatrix(MDrawContext.MatrixType.kWorldViewMtx); MMatrix projection = context.getMatrix(MDrawContext.MatrixType.kProjectionMtx); // Check to see if we are drawing in a shadow pass. // If so then we keep the shading simple which in this // example means to disable any extra blending state changes // MPassContext passCtx = context.passContext; MStringArray passSem = passCtx.passSemantics; bool castingShadows = false; for (int i = 0; i < passSem.length; i++) { if (passSem[i] == MPassContext.kShadowPassSemantic) { castingShadows = true; } } bool debugPassInformation = false; if (debugPassInformation) { string passId = passCtx.passIdentifier; MGlobal.displayInfo("footprint node drawing in pass[" + passId + "], semantic["); for (int i = 0; i < passSem.length; i++) { MGlobal.displayInfo(passSem[i]); } MGlobal.displayInfo("\n"); } // get cached data float multiplier = footData.fMultiplier; float[] color = new float[4] { footData.fColor[0], footData.fColor[1], footData.fColor[2], 1.0f }; bool requireBlending = false; // If we're not casting shadows then do extra work // for display styles if (!castingShadows) { // Use some monotone version of color to show "default material mode" // if ((displayStyle & (uint)MFrameContext.DisplayStyle.kDefaultMaterial) != 0) { color[0] = color[1] = color[2] = (color[0] + color[1] + color[2]) / 3.0f; } // Do some alpha blending if in x-ray mode // else if ((displayStyle & (uint)MFrameContext.DisplayStyle.kXray) != 0) { requireBlending = true; color[3] = 0.3f; } } // Set blend and raster state // MStateManager stateMgr = context.stateManager; MBlendState pOldBlendState = null; MRasterizerState pOldRasterState = null; bool rasterStateModified = false; if ((stateMgr != null) && ((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0)) { // draw filled, and with blending if required if (requireBlending) { if (blendState == null) { MBlendStateDesc desc = new MBlendStateDesc(); desc.targetBlends.blendEnable = true; desc.targetBlends.destinationBlend = MBlendState.BlendOption.kInvSourceAlpha; desc.targetBlends.alphaDestinationBlend = MBlendState.BlendOption.kInvSourceAlpha; blendState = MStateManager.acquireBlendState(desc); } if (blendState != null) { pOldBlendState = stateMgr.blendState; stateMgr.blendState = blendState; } } // Override culling mode since we always want double-sided // pOldRasterState = (stateMgr != null) ? stateMgr.rasterizerState : null; if (pOldRasterState != null) { MRasterizerStateDesc desc = new MRasterizerStateDesc(pOldRasterState.desc); // It's also possible to change this to kCullFront or kCullBack if we // wanted to set it to that. MRasterizerState.CullMode cullMode = MRasterizerState.CullMode.kCullNone; if (desc.cullMode != cullMode) { if (rasterState != null) { // Just override the cullmode desc.cullMode = cullMode; rasterState = MStateManager.acquireRasterizerState(desc); } if (rasterState == null) { rasterStateModified = true; stateMgr.rasterizerState = rasterState; } } } } //======================== // Start the draw work //======================== // Prepare draw agent, default using OpenGL FootPrintDrawAgentGL drawAgentRef = FootPrintDrawAgentGL.getDrawAgent(); FootPrintDrawAgent drawAgentPtr = drawAgentRef; if (drawAgentPtr != null) { // Set color drawAgentPtr.setColor(new MColor(color[0], color[1], color[2], color[3])); // Set matrix drawAgentPtr.setMatrix(transform, projection); drawAgentPtr.beginDraw(); if (drawAsBoundingBox) { // If it is in bounding bode, draw only bounding box wireframe, nothing else MPoint min = footData.fCurrentBoundingBox.min; MPoint max = footData.fCurrentBoundingBox.max; drawAgentPtr.drawBoundingBox(min, max); } else { // Templated, only draw wirefame and it is not selectale bool overideTemplated = objectOverrideInfo.fOverrideEnabled && (objectOverrideInfo.fDisplayType == MDAGDrawOverrideInfo.DrawOverrideDisplayType.kDisplayTypeTemplate); // Override no shaded, only show wireframe bool overrideNoShaded = objectOverrideInfo.fOverrideEnabled && !objectOverrideInfo.fEnableShading; if (overideTemplated || overrideNoShaded) { drawAgentPtr.drawWireframe(multiplier); } else { if (((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0) || ((displayStyle & (uint)MFrameContext.DisplayStyle.kTextured)) != 0) { drawAgentPtr.drawShaded(multiplier); } if ((displayStyle & (uint)MFrameContext.DisplayStyle.kWireFrame) != 0) { drawAgentPtr.drawWireframe(multiplier); } } } drawAgentPtr.endDraw(); } //======================== // End the draw work //======================== // Restore old blend state and old raster state if ((stateMgr != null) && ((displayStyle & (uint)MFrameContext.DisplayStyle.kGouraudShaded) != 0)) { if ((stateMgr != null) && (pOldBlendState != null)) { stateMgr.setBlendState(pOldBlendState); } if (rasterStateModified && (pOldBlendState != null)) { stateMgr.setRasterizerState(pOldRasterState); } } }
// // Description: // // Vertex selection. // // Arguments: // // selectInfo - the selection state information // selectionList - the list of selected items to add to // worldSpaceSelectPts - // public bool selectVertices( MSelectInfo selectInfo, MSelectionList selectionList, MPointArray worldSpaceSelectPts) { bool selected = false; M3dView view = selectInfo.view; MPoint xformedPoint = new MPoint(); MPoint selectionPoint = new MPoint(); double z = 0.0; double previousZ = 0.0; int closestPointVertexIndex = -1; MDagPath path = selectInfo.multiPath; // Create a component that will store the selected vertices // MFnSingleIndexedComponent fnComponent = new MFnSingleIndexedComponent(); MObject surfaceComponent = fnComponent.create( MFn.Type.kMeshVertComponent ); uint vertexIndex; // if the user did a single mouse click and we find > 1 selection // we will use the alignmentMatrix to find out which is the closest // MMatrix alignmentMatrix = new MMatrix(); MPoint singlePoint = new MPoint(); bool singleSelection = selectInfo.singleSelection; if( singleSelection ) { alignmentMatrix = selectInfo.alignmentMatrix; } // Get the geometry information // apiMesh meshNode = (apiMesh)surfaceShape; apiMeshGeom geom = meshNode.meshGeom(); // Loop through all vertices of the mesh and // see if they lie withing the selection area // uint numVertices = geom.vertices.length; for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ ) { MPoint currentPoint = geom.vertices[ (int)vertexIndex ]; // Sets OpenGL's render mode to select and stores // selected items in a pick buffer // view.beginSelect(); OpenGL.glBegin(OpenGL.GL_POINTS); OpenGL.glVertex3f((float)currentPoint[0], (float)currentPoint[1], (float)currentPoint[2] ); OpenGL.glEnd(); if ( view.endSelect() > 0 ) // Hit count > 0 { selected = true; if ( singleSelection ) { xformedPoint = currentPoint; xformedPoint.homogenize(); xformedPoint.multiplyEqual( alignmentMatrix ); z = xformedPoint.z; if ( closestPointVertexIndex < 0 || z > previousZ ) { closestPointVertexIndex = (int)vertexIndex; singlePoint = currentPoint; previousZ = z; } } else { // multiple selection, store all elements // fnComponent.addElement( (int)vertexIndex ); } } } // If single selection, insert the closest point into the array // if ( selected && selectInfo.singleSelection ) { fnComponent.addElement(closestPointVertexIndex); // need to get world space position for this vertex // selectionPoint = singlePoint; selectionPoint.multiplyEqual( path.inclusiveMatrix ); } // Add the selected component to the selection list // if ( selected ) { MSelectionList selectionItem = new MSelectionList(); selectionItem.add( path, surfaceComponent ); MSelectionMask mask = new MSelectionMask( MSelectionMask.SelectionType.kSelectComponentsMask ); selectInfo.addSelection( selectionItem, selectionPoint, selectionList, worldSpaceSelectPts, mask, true ); } return selected; }
private List <BabylonAnimation> GetAnimationsFrameByFrame(MFnTransform mFnTransform) { int start = Loader.GetMinTime(); int end = Loader.GetMaxTime(); // Animations List <BabylonAnimation> animations = new List <BabylonAnimation>(); string[] babylonAnimationProperties = new string[] { "scaling", "rotationQuaternion", "position", "visibility" }; Dictionary <string, List <BabylonAnimationKey> > keysPerProperty = new Dictionary <string, List <BabylonAnimationKey> >(); keysPerProperty.Add("scaling", new List <BabylonAnimationKey>()); keysPerProperty.Add("rotationQuaternion", new List <BabylonAnimationKey>()); keysPerProperty.Add("position", new List <BabylonAnimationKey>()); keysPerProperty.Add("visibility", new List <BabylonAnimationKey>()); // get keys for (int currentFrame = start; currentFrame <= end; currentFrame++) { // get transformation matrix at this frame MDoubleArray mDoubleMatrix = new MDoubleArray(); MGlobal.executeCommand($"getAttr -t {currentFrame} {mFnTransform.fullPathName}.matrix", mDoubleMatrix); mDoubleMatrix.get(out float[] localMatrix); MMatrix matrix = new MMatrix(localMatrix); var transformationMatrix = new MTransformationMatrix(matrix); // Retreive TRS vectors from matrix var position = transformationMatrix.getTranslation(); var rotationQuaternion = transformationMatrix.getRotationQuaternion(); var scaling = transformationMatrix.getScale(); // Switch coordinate system at object level position[2] *= -1; rotationQuaternion[0] *= -1; rotationQuaternion[1] *= -1; // create animation key for each property for (int indexAnimation = 0; indexAnimation < babylonAnimationProperties.Length; indexAnimation++) { string babylonAnimationProperty = babylonAnimationProperties[indexAnimation]; BabylonAnimationKey key = new BabylonAnimationKey(); key.frame = currentFrame; switch (indexAnimation) { case 0: // scaling key.values = scaling.ToArray(); break; case 1: // rotationQuaternion key.values = rotationQuaternion.ToArray(); break; case 2: // position key.values = position.ToArray(); break; case 3: // visibility key.values = new float[] { Loader.GetVisibility(mFnTransform.fullPathName, currentFrame) }; break; } keysPerProperty[babylonAnimationProperty].Add(key); } } // create animation for each property for (int indexAnimation = 0; indexAnimation < babylonAnimationProperties.Length; indexAnimation++) { string babylonAnimationProperty = babylonAnimationProperties[indexAnimation]; List <BabylonAnimationKey> keys = keysPerProperty[babylonAnimationProperty]; var keysFull = new List <BabylonAnimationKey>(keys); // Optimization OptimizeAnimations(keys, true); // Ensure animation has at least 2 frames if (IsAnimationKeysRelevant(keys)) { int dataType = 0; // "scaling", "rotationQuaternion", "position", "visibility" if (indexAnimation == 0 || indexAnimation == 2) // scaling and position { dataType = (int)BabylonAnimation.DataType.Vector3; } else if (indexAnimation == 1) // rotationQuaternion { dataType = (int)BabylonAnimation.DataType.Quaternion; } else // visibility { dataType = (int)BabylonAnimation.DataType.Float; } // Create BabylonAnimation animations.Add(new BabylonAnimation() { dataType = dataType, name = babylonAnimationProperty + " animation", framePerSecond = Loader.GetFPS(), loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle, property = babylonAnimationProperty, keys = keys.ToArray(), keysFull = keysFull }); } } return(animations); }
public PartFrame() { // Defaults this.Offset = new MVector(MVector.zero); this.RotationMatrix = new MMatrix(MMatrix.identity); }
public override void resetTransformation(MMatrix matrix) { base.resetTransformation(matrix); }
// Support the translate/rotate/scale tool (components) // public override void transformUsing(MMatrix mat, MObjectArray componentList) // // Description // // Transforms by the matrix the given components, or the entire shape // if the componentList is empty. This method is used by the freezeTransforms command. // // Arguments // // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // { // Let the other version of transformUsing do the work for us. // transformUsing( mat, componentList, MVertexCachingMode.kNoPointCaching, null); }
// // Description // // Transforms by the matrix the given components, or the entire shape // if the componentList is empty. This method is used by the freezeTransforms command. // // Arguments // // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // // Support the translate/rotate/scale tool (components) // public override void transformUsing(MMatrix mat, MObjectArray componentList) { // Let the other version of transformUsing do the work for us. // transformUsing( mat, componentList, MVertexCachingMode.kNoPointCaching, null); }
public override void doSolve() { MIkHandleGroup handle_group = handleGroup; if (handle_group == null) { throw new InvalidOperationException("Invalid handle group"); } MObject handle = handle_group.handle(0); MDagPath handlePath = MDagPath.getAPathTo(handle); MFnIkHandle handleFn = new MFnIkHandle(handlePath); //Effector // MDagPath effectorPath = new MDagPath(); handleFn.getEffector(effectorPath); MFnIkEffector effectorFn = new MFnIkEffector(effectorPath); effectorPath.pop(); MFnIkJoint midJoinFn = new MFnIkJoint(effectorPath); // Start Joint // MDagPath startJointPath = new MDagPath(); handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn = new MFnIkJoint(startJointPath); // Preferred angles // double [] startJointPrefAngle = new double[3]; double[] midJointPrefAngle = new double[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJoinFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder); midJoinFn.setRotation(midJointPrefAngle, midJoinFn.rotationOrder); MPoint handlePos = handleFn.rotatePivot(MSpace.Space.kWorld); AwPoint awHandlePos = new AwPoint(handlePos.x, handlePos.y, handlePos.z, handlePos.w); MPoint effectorPos = effectorFn.rotatePivot(MSpace.Space.kWorld); AwPoint awEffectorPos = new AwPoint(effectorPos.x, effectorPos.y, effectorPos.z, effectorPos.w); MPoint midJoinPos = midJoinFn.rotatePivot(MSpace.Space.kWorld); AwPoint awMidJoinPos = new AwPoint(midJoinPos.x, midJoinPos.y, midJoinPos.z, midJoinPos.w); MPoint startJointPos = startJointFn.rotatePivot(MSpace.Space.kWorld); AwPoint awStartJointPos = new AwPoint(startJointPos.x, startJointPos.y, startJointPos.z, startJointPos.w); AwVector poleVector = poleVectorFromHandle(handlePath); MMatrix m = handlePath.exclusiveMatrix; AwMatrix awM = new AwMatrix(); awM.setMatrix(m); poleVector = poleVector.mulMatrix(awM); double twistValue = twistFromHandle(handlePath); AwQuaternion qStart = new AwQuaternion(); AwQuaternion qMid = new AwQuaternion(); solveIK(awStartJointPos, awMidJoinPos, awEffectorPos, awHandlePos, poleVector, twistValue, qStart, qMid); MQuaternion mid = new MQuaternion(qMid.x, qMid.y, qMid.z, qMid.w); MQuaternion start = new MQuaternion(qStart.x, qStart.y, qStart.z, qStart.w); midJoinFn.rotateBy(mid, MSpace.Space.kWorld); startJointFn.rotateBy(start, MSpace.Space.kWorld); return; }
// // Description // // Transforms the given components. This method is used by // the move, rotate, and scale tools in component mode when the // tweaks for the shape are stored on a separate tweak node. // The bounding box has to be updated here, so do the normals and // any other attributes that depend on vertex positions. // // Arguments // mat - matrix to transform the components by // componentList - list of components to be transformed, // or an empty list to indicate the whole surface // cachingMode - how to use the supplied pointCache // pointCache - if non-null, save or restore points from this list base // on the cachingMode // handle - handle to the attribute on the tweak node where the // tweaks should be stored // public override void tweakUsing( MMatrix mat, MObjectArray componentList, MVertexCachingMode cachingMode, MPointArray pointCache, MArrayDataHandle handle) { apiMeshGeom geomPtr = meshGeom(); bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints); bool updatePoints = (cachingMode == MVertexCachingMode.kUpdatePoints); MArrayDataBuilder builder = handle.builder(); MPoint delta = new MPoint(); MPoint currPt = new MPoint(); MPoint newPt = new MPoint(); int i=0; uint len = componentList.length; int cacheIndex = 0; uint cacheLen = (null != pointCache) ? pointCache.length : 0; if (cachingMode == MVertexCachingMode.kRestorePoints) { // restore points from the pointCache // if (len > 0) { // traverse the component list // for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) { MDataHandle hdl = builder.addElement(idx); double[] pt = hdl.Double3; MPoint cachePt = pointCache[cacheIndex]; pt[0] += cachePt.x; pt[1] += cachePt.y; pt[2] += cachePt.z; hdl.Double3 = pt; } } } else { // Tweak the points. If savePoints is true, also save the tweaks in the // pointCache. If updatePoints is true, add the new tweaks to the existing // data in the pointCache. // if (len > 0) { for ( i=0; i<len; i++ ) { MObject comp = componentList[i]; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp ); int elemCount = fnComp.elementCount; if (savePoints) { pointCache.sizeIncrement = (uint)elemCount; } for ( int idx=0; idx<elemCount; idx++ ) { int elemIndex = fnComp.element( idx ); MDataHandle hdl = builder.addElement((uint)elemIndex); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[elemIndex]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*(-1.0)); } else if (updatePoints && cacheIndex < cacheLen) { MPoint cachePt = pointCache[cacheIndex]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; cacheIndex++; } } } } else { // if the component list is of zero-length, it indicates that we // should transform the entire surface // len = geomPtr.vertices.length; if (savePoints) { pointCache.sizeIncrement = len; } for ( int idx = 0; idx < len; ++idx ) { MDataHandle hdl = builder.addElement((uint)idx); double[] pt = hdl.Double3; currPt = newPt = geomPtr.vertices[idx]; newPt.multiplyEqual( mat ); delta.x = newPt.x - currPt.x; delta.y = newPt.y - currPt.y; delta.z = newPt.z - currPt.z; pt[0] += delta.x; pt[1] += delta.y; pt[2] += delta.z; hdl.Double3 = pt; if (savePoints) { // store the points in the pointCache for undo // pointCache.append(delta*-1.0); } else if (updatePoints && idx < cacheLen) { MPoint cachePt = pointCache[idx]; cachePt[0] -= delta.x; cachePt[1] -= delta.y; cachePt[2] -= delta.z; } } } } // Set the builder into the handle. // handle.set(builder); // Tell Maya the bounding box for this object has changed // and thus "boundingBox()" needs to be called. // childChanged( MChildChanged.kBoundingBoxChanged ); }