Beispiel #1
0
			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;
			}
Beispiel #2
0
            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);
            }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        //
        // Description
        //
        //    Returns offsets for the given components to be used my the
        //    move tool in normal/u/v mode.
        //
        // Arguments
        //
        //    component - components to calculate offsets for
        //    direction - array of offsets to be filled
        //    mode      - the type of offset to be calculated
        //    normalize - specifies whether the offsets should be normalized
        //
        // Returns
        //
        //    true if the offsets could be calculated, false otherwise
        //
        // Support the move tools normal/u/v mode (components)
        //
        public override bool vertexOffsetDirection( MObject component,
            MVectorArray direction,
            MVertexOffsetMode mode,
            bool normalize)
        {
            bool offsetOkay = false ;

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

            offsetOkay = true ;

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

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

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

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

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

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

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

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

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

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

            return offsetOkay;
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
		// Support the move tools normal/u/v mode (components)
		//
		public override bool vertexOffsetDirection( MObject component,
													MVectorArray direction,
													MVertexOffsetMode mode,
													bool normalize )
		//
		// Description
		//
		//    Returns offsets for the given components to be used my the
		//    move tool in normal/u/v mode.
		//
		// Arguments
		//
		//    component - components to calculate offsets for
		//    direction - array of offsets to be filled
		//    mode      - the type of offset to be calculated
		//    normalize - specifies whether the offsets should be normalized
		//
		// Returns
		//
		//    true if the offsets could be calculated, false otherwise
		//
		{
			bool offsetOkay = false ;

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

			offsetOkay = true ;

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

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

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

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

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

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

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

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

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

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

			return offsetOkay;
		}
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        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);
        }