public bool setPlane(MPoint pointOnPlane, MVector normalToPlane) { MVector _normalToPlane = new MVector(normalToPlane); _normalToPlane.normalize(); // Calculate a,b,c,d based on input a = _normalToPlane.x; b = _normalToPlane.y; c = _normalToPlane.z; d = -(a * pointOnPlane.x + b * pointOnPlane.y + c * pointOnPlane.z); return true; }
public bool setPlane(MPoint pointOnPlane, MVector normalToPlane) { MVector _normalToPlane = new MVector(normalToPlane); _normalToPlane.normalize(); // Calculate a,b,c,d based on input a = _normalToPlane.x; b = _normalToPlane.y; c = _normalToPlane.z; d = -(a * pointOnPlane.x + b * pointOnPlane.y + c * pointOnPlane.z); return(true); }
public override void applySpringLaw(double stiffness, double damping, double restLength, double endMass1, double endMass2, MVector endP1, MVector endP2, MVector endV1, MVector endV2, MVector forceV1, MVector forceV2) { MVector distV = endP1 - endP2; double L = distV.length; distV.normalize(); double F = factor * (L - restLength); forceV1 = -F * distV; forceV2 = -forceV1; return; }
public lineManip() { plane = new planeMath(); mousePointGlName = new MPoint(); // Setup the plane with a point on the // plane along with a normal MPoint pointOnPlane = lineGeometry.topPoint(); // Normal = cross product of two vectors on the plane MVector _topPoint = new MVector(lineGeometry.topPoint()); MVector _bottomPoint = new MVector(lineGeometry.bottomPoint()); MVector _otherPoint = new MVector(lineGeometry.otherPoint()); MVector normalToPlane = (_topPoint - _otherPoint).crossProduct(_otherPoint - _bottomPoint); // Necessary to normalize normalToPlane.normalize(); // Plane defined by a point and a normal plane.setPlane(pointOnPlane, normalToPlane); }
// // Description // // Returns offsets for the given components to be used my the // move tool in normal/u/v mode. // // Arguments // // component - components to calculate offsets for // direction - array of offsets to be filled // mode - the type of offset to be calculated // normalize - specifies whether the offsets should be normalized // // Returns // // true if the offsets could be calculated, false otherwise // // Support the move tools normal/u/v mode (components) // public override bool vertexOffsetDirection( MObject component, MVectorArray direction, MVertexOffsetMode mode, bool normalize) { bool offsetOkay = false ; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( component ); if ( component.apiType != MFn.Type.kMeshVertComponent ) { return false; } offsetOkay = true ; apiMeshGeom geomPtr = meshGeom(); if ( null == geomPtr ) { return false; } // For each vertex add the appropriate offset // int count = fnComp.elementCount; for ( int idx=0; idx<count; idx++ ) { MVector normal = geomPtr.normals[ fnComp.element(idx) ]; if( mode == MVertexOffsetMode.kNormal ) { if( normalize ) normal.normalize() ; direction.append( normal ); } else { // Construct an orthonormal basis from the normal // uAxis, and vAxis are the new vectors. // MVector uAxis = new MVector(); MVector vAxis = new MVector(); uint i, j, k; double a; normal.normalize(); i = 0; a = Math.Abs( normal[0] ); if ( a < Math.Abs(normal[1]) ) { i = 1; a = Math.Abs(normal[1]); } if ( a < Math.Abs(normal[2]) ) { i = 2; } j = (i+1)%3; k = (j+1)%3; a = Math.Sqrt(normal[i]*normal[i] + normal[j]*normal[j]); uAxis[i] = -normal[j]/a; uAxis[j] = normal[i]/a; uAxis[k] = 0.0; vAxis = normal.crossProduct( uAxis ); if ( mode == MVertexOffsetMode.kUTangent || mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) uAxis.normalize() ; direction.append( uAxis ); } if ( mode == MVertexOffsetMode.kVTangent || mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) vAxis.normalize() ; direction.append( vAxis ); } if ( mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) normal.normalize() ; direction.append( normal ); } } } return offsetOkay; }
/// <summary> /// /// </summary> /// <param name="mDagPath">DAG path to the transform above light</param> /// <param name="babylonScene"></param> /// <returns></returns> private BabylonNode ExportLight(MDagPath mDagPath, BabylonScene babylonScene) { RaiseMessage(mDagPath.partialPathName, 1); // Transform above light MFnTransform mFnTransform = new MFnTransform(mDagPath); // Light direct child of the transform MFnLight mFnLight = null; for (uint i = 0; i < mFnTransform.childCount; i++) { MObject childObject = mFnTransform.child(i); if (childObject.hasFn(MFn.Type.kLight)) { var _mFnLight = new MFnLight(childObject); if (!_mFnLight.isIntermediateObject) { mFnLight = _mFnLight; } } } if (mFnLight == null) { RaiseError("No light found has child of " + mDagPath.fullPathName); return(null); } RaiseMessage("mFnLight.fullPathName=" + mFnLight.fullPathName, 2); // --- prints --- #region prints // MFnLight RaiseVerbose("BabylonExporter.Light | mFnLight data", 2); RaiseVerbose("BabylonExporter.Light | mFnLight.color.toString()=" + mFnLight.color.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.intensity=" + mFnLight.intensity, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.useRayTraceShadows=" + mFnLight.useRayTraceShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.shadowColor.toString()=" + mFnLight.shadowColor.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.centerOfIllumination=" + mFnLight.centerOfIllumination, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.numShadowSamples=" + mFnLight.numShadowSamples, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.rayDepthLimit=" + mFnLight.rayDepthLimit, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.opticalFXvisibility.toString()=" + mFnLight.opticalFXvisibility.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightIntensity.toString()=" + mFnLight.lightIntensity.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.instanceCount(true)=" + mFnLight.instanceCount(true), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightDirection(0).toString()=" + mFnLight.lightDirection(0).toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightAmbient=" + mFnLight.lightAmbient, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightDiffuse=" + mFnLight.lightDiffuse, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightSpecular=" + mFnLight.lightSpecular, 3); switch (mFnLight.objectProperty.apiType) { case MFn.Type.kSpotLight: MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty); // MFnNonAmbientLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.decayRate=" + mFnSpotLight.decayRate, 3); // dropdown enum value // MFnNonExtendedLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.shadowRadius=" + mFnSpotLight.shadowRadius, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.castSoftShadows=" + mFnSpotLight.castSoftShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDepthMapShadows=" + mFnSpotLight.useDepthMapShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapFilterSize()=" + mFnSpotLight.depthMapFilterSize(), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapResolution()=" + mFnSpotLight.depthMapResolution(), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapBias()=" + mFnSpotLight.depthMapBias(), 3); // MFnSpotLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.coneAngle=" + mFnSpotLight.coneAngle, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.penumbraAngle=" + mFnSpotLight.penumbraAngle, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.dropOff=" + mFnSpotLight.dropOff, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.barnDoors=" + mFnSpotLight.barnDoors, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDecayRegions=" + mFnSpotLight.useDecayRegions, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird), 3); break; } Print(mFnTransform, 2, "Print ExportLight mFnTransform"); Print(mFnLight, 2, "Print ExportLight mFnLight"); #endregion if (IsLightExportable(mFnLight, mDagPath) == false) { return(null); } var babylonLight = new BabylonLight { name = mFnTransform.name, id = mFnTransform.uuid().asString() }; // Hierarchy ExportHierarchy(babylonLight, mFnTransform); // User custom attributes babylonLight.metadata = ExportCustomAttributeFromTransform(mFnTransform); // Position //RaiseVerbose("BabylonExporter.Light | ExportTransform", 2); float[] position = null; GetTransform(mFnTransform, ref position); babylonLight.position = position; // Direction var vDir = new MVector(0, 0, -1); var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix); vDir = vDir.multiply(transformationMatrix.asMatrixProperty); vDir.normalize(); babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z }; // Common fields babylonLight.intensity = mFnLight.intensity; babylonLight.diffuse = mFnLight.lightDiffuse ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 }; babylonLight.specular = mFnLight.lightSpecular ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 }; // Type switch (mFnLight.objectProperty.apiType) { case MFn.Type.kPointLight: babylonLight.type = 0; break; case MFn.Type.kSpotLight: MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty); babylonLight.type = 2; babylonLight.angle = (float)mFnSpotLight.coneAngle; babylonLight.exponent = 1; if (mFnSpotLight.useDecayRegions) { babylonLight.range = mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird); // Max distance } break; case MFn.Type.kDirectionalLight: babylonLight.type = 1; break; case MFn.Type.kAmbientLight: babylonLight.type = 3; babylonLight.groundColor = new float[] { 0, 0, 0 }; // No emit diffuse /specular checkbox for ambient light babylonLight.diffuse = mFnLight.color.toArrayRGB(); babylonLight.specular = babylonLight.diffuse; // Direction vDir = new MVector(0, 1, 0); transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix); vDir = vDir.multiply(transformationMatrix.asMatrixProperty); vDir.normalize(); babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z }; break; case MFn.Type.kAreaLight: case MFn.Type.kVolumeLight: RaiseError("Unsupported light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored. Supported light types are: ambient, directional, point and spot.", 1); return(null); default: RaiseWarning("Unknown light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored.", 1); return(null); } // TODO - Shadows //Variable declaration MStringArray enlightedMeshesFullPathNames = new MStringArray(); List <string> includeMeshesIds = new List <string>(); MStringArray kTransMesh = new MStringArray(); String typeMesh = null; MStringArray UUIDMesh = new MStringArray(); //MEL Command that get the enlighted mesh for a given light MGlobal.executeCommand($@"lightlink -query -light {mFnTransform.fullPathName};", enlightedMeshesFullPathNames); //For each enlighted mesh foreach (String Mesh in enlightedMeshesFullPathNames) { //MEL Command use to get the type of each mesh typeMesh = MGlobal.executeCommandStringResult($@"nodeType -api {Mesh};"); //We are targeting the type kMesh and not kTransform (for parenting) if (typeMesh == "kMesh") { MGlobal.executeCommand($@"listRelatives -parent -fullPath {Mesh};", kTransMesh); //And finally the MEL Command for the uuid of each mesh MGlobal.executeCommand($@"ls -uuid {kTransMesh[0]};", UUIDMesh); includeMeshesIds.Add(UUIDMesh[0]); } } babylonLight.includedOnlyMeshesIds = includeMeshesIds.ToArray(); // Animations if (exportParameters.bakeAnimationFrames) { ExportNodeAnimationFrameByFrame(babylonLight, mFnTransform); } else { ExportNodeAnimation(babylonLight, mFnTransform); } babylonScene.LightsList.Add(babylonLight); return(babylonLight); }
// Support the move tools normal/u/v mode (components) // public override bool vertexOffsetDirection( MObject component, MVectorArray direction, MVertexOffsetMode mode, bool normalize ) // // Description // // Returns offsets for the given components to be used my the // move tool in normal/u/v mode. // // Arguments // // component - components to calculate offsets for // direction - array of offsets to be filled // mode - the type of offset to be calculated // normalize - specifies whether the offsets should be normalized // // Returns // // true if the offsets could be calculated, false otherwise // { bool offsetOkay = false ; MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( component ); if ( component.apiType != MFn.Type.kMeshVertComponent ) { return false; } offsetOkay = true ; apiMeshGeom geomPtr = meshGeom(); if ( null == geomPtr ) { return false; } // For each vertex add the appropriate offset // int count = fnComp.elementCount; for ( int idx=0; idx<count; idx++ ) { MVector normal = geomPtr.normals[ fnComp.element(idx) ]; if( mode == MVertexOffsetMode.kNormal ) { if( normalize ) normal.normalize() ; direction.append( normal ); } else { // Construct an orthonormal basis from the normal // uAxis, and vAxis are the new vectors. // MVector uAxis = new MVector(); MVector vAxis = new MVector(); uint i, j, k; double a; normal.normalize(); i = 0; a = Math.Abs( normal[0] ); if ( a < Math.Abs(normal[1]) ) { i = 1; a = Math.Abs(normal[1]); } if ( a < Math.Abs(normal[2]) ) { i = 2; } j = (i+1)%3; k = (j+1)%3; a = Math.Sqrt(normal[i]*normal[i] + normal[j]*normal[j]); uAxis[i] = -normal[j]/a; uAxis[j] = normal[i]/a; uAxis[k] = 0.0; vAxis = normal.crossProduct( uAxis ); if ( mode == MVertexOffsetMode.kUTangent || mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) uAxis.normalize() ; direction.append( uAxis ); } if ( mode == MVertexOffsetMode.kVTangent || mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) vAxis.normalize() ; direction.append( vAxis ); } if ( mode == MVertexOffsetMode.kUVNTriad ) { if( normalize ) normal.normalize() ; direction.append( normal ); } } } return offsetOkay; }
/// <summary> /// /// </summary> /// <param name="mDagPath">DAG path to the transform above light</param> /// <param name="babylonScene"></param> /// <returns></returns> private BabylonNode ExportLight(MDagPath mDagPath, BabylonScene babylonScene) { RaiseMessage(mDagPath.partialPathName, 1); // Transform above light MFnTransform mFnTransform = new MFnTransform(mDagPath); // Light direct child of the transform MFnLight mFnLight = null; for (uint i = 0; i < mFnTransform.childCount; i++) { MObject childObject = mFnTransform.child(i); if (childObject.hasFn(MFn.Type.kLight)) { mFnLight = new MFnLight(childObject); } } if (mFnLight == null) { RaiseError("No light found has child of " + mDagPath.fullPathName); return(null); } RaiseMessage("mFnLight.fullPathName=" + mFnLight.fullPathName, 2); // --- prints --- #region prints // MFnLight RaiseVerbose("BabylonExporter.Light | mFnLight data", 2); RaiseVerbose("BabylonExporter.Light | mFnLight.color.toString()=" + mFnLight.color.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.intensity=" + mFnLight.intensity, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.useRayTraceShadows=" + mFnLight.useRayTraceShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.shadowColor.toString()=" + mFnLight.shadowColor.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.centerOfIllumination=" + mFnLight.centerOfIllumination, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.numShadowSamples=" + mFnLight.numShadowSamples, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.rayDepthLimit=" + mFnLight.rayDepthLimit, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.opticalFXvisibility.toString()=" + mFnLight.opticalFXvisibility.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightIntensity.toString()=" + mFnLight.lightIntensity.toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.instanceCount(true)=" + mFnLight.instanceCount(true), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightDirection(0).toString()=" + mFnLight.lightDirection(0).toString(), 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightAmbient=" + mFnLight.lightAmbient, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightDiffuse=" + mFnLight.lightDiffuse, 3); RaiseVerbose("BabylonExporter.Light | mFnLight.lightSpecular=" + mFnLight.lightSpecular, 3); switch (mFnLight.objectProperty.apiType) { case MFn.Type.kSpotLight: MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty); // MFnNonAmbientLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.decayRate=" + mFnSpotLight.decayRate, 3); // dropdown enum value // MFnNonExtendedLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.shadowRadius=" + mFnSpotLight.shadowRadius, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.castSoftShadows=" + mFnSpotLight.castSoftShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDepthMapShadows=" + mFnSpotLight.useDepthMapShadows, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapFilterSize()=" + mFnSpotLight.depthMapFilterSize(), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapResolution()=" + mFnSpotLight.depthMapResolution(), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapBias()=" + mFnSpotLight.depthMapBias(), 3); // MFnSpotLight RaiseVerbose("BabylonExporter.Light | mFnSpotLight.coneAngle=" + mFnSpotLight.coneAngle, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.penumbraAngle=" + mFnSpotLight.penumbraAngle, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.dropOff=" + mFnSpotLight.dropOff, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.barnDoors=" + mFnSpotLight.barnDoors, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDecayRegions=" + mFnSpotLight.useDecayRegions, 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird), 3); RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird), 3); break; } #endregion if (IsLightExportable(mFnLight, mDagPath) == false) { return(null); } var babylonLight = new BabylonLight { name = mFnTransform.name, id = mFnTransform.uuid().asString() }; // Hierarchy ExportHierarchy(babylonLight, mFnTransform); // Position RaiseVerbose("BabylonExporter.Light | ExportTransform", 2); float[] position = null; GetTransform(mFnTransform, ref position); babylonLight.position = position; // Direction var vDir = new MVector(0, 0, -1); var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix); vDir = vDir.multiply(transformationMatrix.asMatrixProperty); vDir.normalize(); babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z }; // Common fields babylonLight.intensity = mFnLight.intensity; babylonLight.diffuse = mFnLight.lightDiffuse ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 }; babylonLight.specular = mFnLight.lightSpecular ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 }; // Type switch (mFnLight.objectProperty.apiType) { case MFn.Type.kPointLight: babylonLight.type = 0; break; case MFn.Type.kSpotLight: MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty); babylonLight.type = 2; babylonLight.angle = (float)mFnSpotLight.coneAngle; babylonLight.exponent = 1; if (mFnSpotLight.useDecayRegions) { babylonLight.range = mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird); // Max distance } break; case MFn.Type.kDirectionalLight: babylonLight.type = 1; break; case MFn.Type.kAmbientLight: babylonLight.type = 3; babylonLight.groundColor = new float[] { 0, 0, 0 }; break; case MFn.Type.kAreaLight: case MFn.Type.kVolumeLight: RaiseError("Unsupported light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored. Supported light types are: ambient, directional, point and spot."); return(null); default: RaiseWarning("Unknown light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored."); return(null); } // TODO - Shadows // TODO - Exclusion // TODO - Animations babylonScene.LightsList.Add(babylonLight); return(babylonLight); }
private void doSimpleSolver() // // Solve single joint in the x-y plane // // - first it calculates the angle between the handle and the end-effector. // - then it determines which way to rotate the joint. // { // Get the handle and create a function set for it // MIkHandleGroup handle_group = handleGroup; if (null == handle_group) { throw new System.InvalidOperationException("invalid handle group."); } MObject handle = handle_group.handle(0); MDagPath handlePath = MDagPath.getAPathTo(handle); MFnIkHandle fnHandle = new MFnIkHandle(handlePath); // Get the position of the end_effector // MDagPath end_effector = new MDagPath(); fnHandle.getEffector(end_effector); MFnTransform tran = new MFnTransform(end_effector); MPoint effector_position = tran.rotatePivot(MSpace.Space.kWorld); // Get the position of the handle // MPoint handle_position = fnHandle.rotatePivot(MSpace.Space.kWorld); // Get the start joint position // MDagPath start_joint = new MDagPath(); fnHandle.getStartJoint(start_joint); MFnTransform start_transform = new MFnTransform(start_joint); MPoint start_position = start_transform.rotatePivot(MSpace.Space.kWorld); // Calculate the rotation angle // MVector v1 = start_position.minus(effector_position); MVector v2 = start_position.minus(handle_position); double angle = v1.angle(v2); // -------- Figure out which way to rotate -------- // // define two vectors U and V as follows // U = EndEffector(E) - StartJoint(S) // N = Normal to U passing through EndEffector // // Clip handle_position to half-plane U to determine the region it // lies in. Use the region to determine the rotation direction. // // U // ^ Region Rotation // | B // (E)---N A C-C-W // A | B C-W // | B // | // (S) // double rot = 0.0; // Rotation about Z-axis // U and N define a half-plane to clip the handle against // MVector U = effector_position.minus(start_position); U.normalize(); // Get a normal to U // MVector zAxis = new MVector(0.0, 0.0, 1.0); MVector N = U.crossProduct(zAxis); // Cross product N.normalize(); // P is the handle position vector // MVector P = handle_position.minus(effector_position); // Determine the rotation direction // double PdotN = P[0] * N[0] + P[1] * N[1]; if (PdotN < 0) { // counter-clockwise rot = angle; } else { // clockwise rot = -1.0 * angle; } // get and set the Joint Angles // MDoubleArray jointAngles = new MDoubleArray(); getJointAngles(jointAngles); jointAngles.set(jointAngles[0] + rot, 0); setJointAngles(jointAngles); }