public static void Multiply(ref SphericalDirection d, ref Quaternion q, out SphericalDirection result)
        {
            Vector3 vector;

            d.GetVector(out vector);
            Vector3 vector2;

            Quaternion.Multiply(ref vector, ref q, out vector2);
            SphericalDirection.FromVector(ref vector2, out result);
        }
Beispiel #2
0
        public virtual Viewport.CameraSettingsClass GetCameraSettings(Viewport viewport, Component_Camera cameraDefault)
        {
            Viewport.CameraSettingsClass result = null;
            GetCameraSettingsEvent?.Invoke(this, viewport, cameraDefault, ref result);

            if (result == null)
            {
                if (FreeCamera)
                {
                    //free camera

                    result = new Viewport.CameraSettingsClass(viewport, cameraDefault.AspectRatio, cameraDefault.FieldOfView, cameraDefault.NearClipPlane, cameraDefault.FarClipPlane, freeCameraPosition, freeCameraDirection.GetVector(), Vector3.ZAxis, ProjectionType.Perspective, 1, cameraDefault.Exposure, cameraDefault.EmissiveFactor);
                }
                else if (UseBuiltInCamera.Value == BuiltInCameraEnum.FirstPerson)
                {
                    //first person camera

                    //Character
                    var character = ObjectControlledByPlayer.Value as Component_Character;
                    if (character != null)
                    {
                        character.GetFirstPersonCameraPosition(out var position, out var forward, out var up);

                        var eyePosition = character.TransformV * character.EyePosition.Value;
                        var direction   = character.LookToDirection.GetVector();

                        result = new Viewport.CameraSettingsClass(viewport, cameraDefault.AspectRatio, cameraDefault.FieldOfView, cameraDefault.NearClipPlane, cameraDefault.FarClipPlane, eyePosition, direction, up, ProjectionType.Perspective, 1, cameraDefault.Exposure, cameraDefault.EmissiveFactor);
                    }
                }
                else if (UseBuiltInCamera.Value == BuiltInCameraEnum.ThirdPerson)
                {
                    //third person camera

                    //Character
                    if (Scene.Mode.Value == Component_Scene.ModeEnum._3D)
                    {
                        var character = ObjectControlledByPlayer.Value as Component_Character;
                        if (character != null)
                        {
                            var lookAt = character.TransformV.Position;

                            var d         = new SphericalDirection(MathEx.DegreeToRadian(ThirdPersonCameraHorizontalAngle.Value), MathEx.DegreeToRadian(ThirdPersonCameraVerticalAngle.Value));
                            var direction = -d.GetVector();

                            var from = lookAt - direction * ThirdPersonCameraDistance.Value;

                            result = new Viewport.CameraSettingsClass(viewport, cameraDefault.AspectRatio, cameraDefault.FieldOfView, cameraDefault.NearClipPlane, cameraDefault.FarClipPlane, from, direction, Vector3.ZAxis, ProjectionType.Perspective, 1, cameraDefault.Exposure, cameraDefault.EmissiveFactor);
                        }
                    }

                    //Character2D
                    if (Scene.Mode.Value == Component_Scene.ModeEnum._2D)
                    {
                        var character = ObjectControlledByPlayer.Value as Component_Character2D;
                        if (character != null)
                        {
                            var lookAt = character.TransformV.Position;
                            var from   = lookAt + new Vector3(0, 0, 10);

                            result = new Viewport.CameraSettingsClass(viewport, cameraDefault.AspectRatio, cameraDefault.FieldOfView, cameraDefault.NearClipPlane, cameraDefault.FarClipPlane, from, -Vector3.ZAxis, Vector3.YAxis, ProjectionType.Orthographic, cameraDefault.Height, cameraDefault.Exposure, cameraDefault.EmissiveFactor);
                        }
                    }
                }
            }

            //Component_CameraManagement
            if (result == null)
            {
                var m = GetCurrentCameraManagement();
                if (m != null)
                {
                    result = m.GetCameraSettings(this, viewport, cameraDefault);
                }
            }

            return(result);
        }
Beispiel #3
0
        public static void GenerateCapsule(int axis, double radius, double height, int hSegments, int vSegments, out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            if (axis < 0 || axis > 2)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateCapsule: axis < 0 || axis > 2.");
            }
            //if( radius < 0 )
            //	Log.Fatal( "SimpleMeshGenerator: GenerateCapsule: radius < 0." );
            //if( height < 0 )
            //	Log.Fatal( "SimpleMeshGenerator: GenerateCapsule: height < 0." );
            if (hSegments < 3)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateCapsule: hSegments < 3.");
            }
            if (vSegments < 3)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateCapsule: vSegments < 3.");
            }
            if (vSegments % 2 != 1)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateCapsule: vSegments % 2 != 1.");
            }

            double[] cosTable = new double[hSegments];
            double[] sinTable = new double[hSegments];
            {
                double angleStep = Math.PI * 2 / hSegments;
                for (int n = 0; n < hSegments; n++)
                {
                    double angle = angleStep * n;
                    cosTable[n] = Math.Cos(angle);                        // *radius;
                    sinTable[n] = Math.Sin(angle);                        // *radius;
                }
            }

            //positions
            {
                int vertexCount = (hSegments + 1) * (vSegments + 1);
                positions = new Vector3[vertexCount];
                normals   = new Vector3[vertexCount];
                tangents  = new Vector4[vertexCount];
                texCoords = new Vector2[vertexCount];

                int currentPosition = 0;

                for (int v = 0; v < vSegments + 1; v++)
                {
                    for (int n = 0; n < hSegments + 1; n++)
                    {
                        bool up = v < (vSegments + 1) / 2;

                        double vCoef;
                        if (up)
                        {
                            vCoef = ((double)v / (double)(vSegments - 1));
                        }
                        else
                        {
                            vCoef = (double)(v - 1) / (double)(vSegments - 1);
                        }

                        SphericalDirection dir = new SphericalDirection(
                            (double)n / (double)hSegments * Math.PI * 2,
                            (vCoef - 0.5) * Math.PI);

                        var p           = dir.GetVector() * radius;
                        var posNoOffset = new Vector3(p.Z, p.Y, -p.X);
                        var posResult   = posNoOffset;
                        if (up)
                        {
                            posResult.X -= height / 2;
                        }
                        else
                        {
                            posResult.X += height / 2;
                        }
                        positions[currentPosition] = posResult;

                        //normals
                        normals[currentPosition] = posNoOffset.GetNormalize();
                        if (radius < 0)
                        {
                            normals[currentPosition] = -normals[currentPosition];
                        }

                        //tangents
                        {
                            Matrix3 rotationMatrix = Matrix3.FromRotateByX(-Math.PI / 2);

                            var dir2 = new SphericalDirection((double)n / (double)hSegments * Math.PI * 2, 0).GetVector();
                            dir2 = new Vector3(0, dir2.Y, -dir2.X);
                            tangents[currentPosition] = new Vector4((rotationMatrix * dir2).GetNormalize(), -1);
                        }

                        //texCoords
                        texCoords[currentPosition] = new Vector2(
                            dir.Horizontal / (MathEx.PI * 2) * 2,
                            -dir.Vertical / MathEx.PI + 0.5);
                        if (!up)
                        {
                            texCoords[currentPosition] = texCoords[currentPosition] - new Vector2(0, 1);
                        }

                        if (radius < 0 || height < 0)
                        {
                            texCoords[currentPosition] = -texCoords[currentPosition];
                        }

                        currentPosition++;
                    }
                }

                if (positions.Length != currentPosition)
                {
                    Log.Fatal("SimpleMeshGenerator: GenerateCapsule: positions.Length != currentPosition.");
                }
            }

            //indices
            {
                int indexCount = vSegments * hSegments * 6;
                indices = new int[indexCount];

                int currentIndex = 0;
                for (int v = 0; v < vSegments; v++)
                {
                    for (int n = 0; n < hSegments; n++)
                    {
                        int index = v * (hSegments + 1) + n;

                        indices[currentIndex++] = index;
                        indices[currentIndex++] = index + 1;
                        indices[currentIndex++] = index + hSegments + 1;

                        indices[currentIndex++] = index + hSegments + 1;
                        indices[currentIndex++] = index + 1;
                        indices[currentIndex++] = index + hSegments + 1 + 1;
                    }
                }

                if (indices.Length != currentIndex)
                {
                    Log.Fatal("SimpleMeshGenerator: GenerateCapsule: indices.Length != currentIndex.");
                }
            }

            positions = RotateByAxis(axis, positions);
            normals   = RotateByAxis(axis, normals);
            tangents  = RotateByAxis(axis, tangents);

            //??? Если нужно каждый фейс сделать прямоугольником то задать: rawVerticesInFace = rawVerticesInFaceForMiddle = 6
            faces = BuildFacesForGeoSphere(hSegments, vSegments, 3, 6, indices);

            ////positions
            //{
            //	int vertexCount = hSegments * ( vSegments - 1 ) + 2;

            //	positions = new Vec3[ vertexCount ];
            //	normals = new Vec3[ vertexCount ];
            //	tangents = new Vec4[ vertexCount ];
            //	texCoords = new Vec2[ vertexCount ];

            //	double[] cosTable = new double[ hSegments ];
            //	double[] sinTable = new double[ hSegments ];
            //	{
            //		double angleStep = Math.PI * 2 / hSegments;
            //		for( int n = 0; n < hSegments; n++ )
            //		{
            //			double angle = angleStep * n;
            //			cosTable[ n ] = Math.Cos( angle );
            //			sinTable[ n ] = Math.Sin( angle );
            //		}
            //	}

            //	int levelCount = vSegments + 1;

            //	int currentPosition = 0;
            //	for( int v = 0; v < levelCount; v++ )
            //	{
            //		if( v == 0 )
            //		{
            //			positions[ currentPosition ] = new Vec3( radius + height * .5, 0, 0 );
            //			normals[ currentPosition ] = new Vec3( 1, 0, 0 );
            //			currentPosition++;
            //		}
            //		else if( v == vSegments )
            //		{
            //			positions[ currentPosition ] = new Vec3( -radius - height * .5, 0, 0 );
            //			normals[ currentPosition ] = new Vec3( -1, 0, 0 );
            //			currentPosition++;
            //		}
            //		else
            //		{
            //			bool top = v <= vSegments / 2;

            //			double c;
            //			if( top )
            //				c = ( (double)v / (double)( vSegments - 1 ) );
            //			else
            //				c = ( (double)( v - 1 ) / (double)( vSegments - 1 ) );

            //			double angle = -( c * 2 - 1 ) * Math.PI / 2;
            //			double hRadius = Math.Cos( angle ) * radius;
            //			double h = Math.Sin( angle ) * radius + ( top ? height * .5 : -height * .5 );

            //			for( int n = 0; n < hSegments; n++ )
            //			{
            //				positions[ currentPosition ] = new Vec3( h, cosTable[ n ] * hRadius, sinTable[ n ] * hRadius );
            //				normals[ currentPosition ] = new Vec3(
            //					Math.Sin( angle ) * radius, cosTable[ n ] * hRadius, sinTable[ n ] * hRadius ).GetNormalize();
            //				if( radius < 0 )
            //					normals[ currentPosition ] = -normals[ currentPosition ];

            //				currentPosition++;
            //			}
            //		}
            //	}

            //	if( positions.Length != currentPosition )
            //		Log.Fatal( "SimpleMeshGenerator: GenerateCapsule: positions.Length != currentPosition." );
            //}

            ////indices
            //{
            //	int indexCount = hSegments * ( vSegments - 2 ) * 2 * 3 + hSegments * 3 + hSegments * 3;
            //	indices = new int[ indexCount ];
            //	int levelCount = vSegments + 1;

            //	int currentIndex = 0;
            //	for( int v = 0; v < levelCount - 1; v++ )
            //	{
            //		int index;
            //		int nextIndex;

            //		if( v != 0 )
            //		{
            //			index = 1 + ( v - 1 ) * hSegments;
            //			nextIndex = index + hSegments;
            //		}
            //		else
            //		{
            //			index = 0;
            //			nextIndex = 1;
            //		}

            //		for( int n = 0; n < hSegments; n++ )
            //		{
            //			int start = n;
            //			int end = ( n + 1 ) % hSegments;

            //			if( v == 0 )
            //			{
            //				indices[ currentIndex++ ] = index;
            //				indices[ currentIndex++ ] = nextIndex + start;
            //				indices[ currentIndex++ ] = nextIndex + end;
            //			}
            //			else if( v == vSegments - 1 )
            //			{
            //				indices[ currentIndex++ ] = index + end;
            //				indices[ currentIndex++ ] = index + start;
            //				indices[ currentIndex++ ] = nextIndex;
            //			}
            //			else
            //			{
            //				indices[ currentIndex++ ] = index + end;
            //				indices[ currentIndex++ ] = index + start;
            //				indices[ currentIndex++ ] = nextIndex + end;

            //				indices[ currentIndex++ ] = nextIndex + start;
            //				indices[ currentIndex++ ] = nextIndex + end;
            //				indices[ currentIndex++ ] = index + start;
            //			}
            //		}
            //	}

            //	if( indices.Length != currentIndex )
            //		Log.Fatal( "SimpleMeshGenerator: GenerateCapsule: indices.Length != currentIndex." );
            //}

            //positions = RotateByAxis( axis, positions );
            //normals = RotateByAxis( axis, normals );
            //tangents = RotateByAxis( axis, tangents );
        }
Beispiel #4
0
            protected virtual void Scene_ViewportUpdateGetCameraSettings(Component_Scene scene, Viewport viewport, ref bool processed)
            {
                //copy from Mesh document window code

                //var camera = scene.CameraEditor.Value;
                var bounds       = scene.CalculateTotalBoundsOfObjectsInSpace();
                var cameraLookTo = bounds.GetCenter();

                double maxGararite = Math.Max(Math.Max(bounds.GetSize().X, bounds.GetSize().Y), bounds.GetSize().Z);
                double distance    = maxGararite * 2;             // 2.3;

                if (distance < 2)
                {
                    distance = 2;
                }

                double             cameraZoomFactor = 1;
                SphericalDirection cameraDirection  = new SphericalDirection(-3.83, -.47);

                var cameraPosition = cameraLookTo - cameraDirection.GetVector() * distance * cameraZoomFactor;
                var center         = cameraLookTo; // GetSceneCenter();

                Vector3 from = cameraPosition;     //center + cameraDirection.GetVector() * cameraDistance;
                Vector3 to   = center;
                Degree  fov  = 65;                 // 75;

                var camera = new Component_Camera();

                //camera.AspectRatio = (double)ViewportControl.Viewport.SizeInPixels.X / (double)ViewportControl.Viewport.SizeInPixels.Y;
                camera.FieldOfView   = fov;
                camera.NearClipPlane = Math.Max(distance / 10000, 0.01);                  //.1;
                camera.FarClipPlane  = Math.Max(1000, distance * 2);

                if (mesh.EditorCameraTransform != null)
                {
                    camera.Transform = mesh.EditorCameraTransform;
                }
                else
                {
                    camera.Transform = new Transform(from, Quaternion.LookAt((to - from).GetNormalize(), Vector3.ZAxis));
                }
                camera.FixedUp = Vector3.ZAxis;

                viewport.CameraSettings = new Viewport.CameraSettingsClass(viewport, camera);


                //if( !cameraMode2D )
                //{

                //var cameraPosition = cameraLookTo - cameraDirection.GetVector() * cameraDistance;
                //var center = cameraLookTo;

                //Vector3 from = cameraPosition;//center + cameraDirection.GetVector() * cameraDistance;
                //Vector3 to = center;
                //Degree fov = 40;//!!!! 65;// 75;

                ////!!!!
                //Component_Camera camera = new Component_Camera();
                //camera.AspectRatio = (double)viewport.SizeInPixels.X / (double)viewport.SizeInPixels.Y;
                //camera.FieldOfView = fov;
                //camera.NearClipPlane = Math.Max( cameraDistance / 10000, 0.01 );//.1;
                //camera.FarClipPlane = Math.Max( 1000, cameraDistance * 2 );

                //camera.Transform = new Transform( from, Quaternion.LookAt( ( to - from ).GetNormalize(), Vector3.ZAxis ) );
                ////camera.Position = from;
                ////camera.Direction = ( to - from ).GetNormalize();

                //camera.FixedUp = Vector3.ZAxis;
                //viewport.CameraSettings = new Viewport.CameraSettingsClass( viewport, camera );

                ////!!!!в методе больше параметров
                //double aspect = (double)viewport.SizeInPixels.X / (double)viewport.SizeInPixels.Y;
                //var settings = new Viewport.CameraSettingsClass( viewport, aspect, fov, .1f, 1000, from, ( to - from ).GetNormalize(), Vec3.ZAxis );
                //viewport.CameraSettings = settings;

                //}
                //else
                //{
                //	var from = cameraLookTo + new Vector3( 0, 0, scene.CameraEditor2DPositionZ );
                //	var to = cameraLookTo;

                //	Component_Camera camera = new Component_Camera();
                //	camera.AspectRatio = (double)viewport.SizeInPixels.X / (double)viewport.SizeInPixels.Y;
                //	camera.NearClipPlane = 0.01;// Math.Max( cameraInitialDistance / 10000, 0.01 );//.1;
                //	camera.FarClipPlane = 1000;// Math.Max( 1000, cameraInitialDistance * 2 );
                //	camera.Transform = new Transform( from, Quaternion.LookAt( ( to - from ).GetNormalize(), Vector3.YAxis ) );
                //	camera.Projection = ProjectionType.Orthographic;
                //	camera.FixedUp = Vector3.YAxis;
                //	//!!!!need consider size by X
                //	camera.Height = cameraInitBounds.GetSize().Y * 1.4;

                //	viewport.CameraSettings = new Viewport.CameraSettingsClass( viewport, camera );
                //}

                processed = true;
            }
Beispiel #5
0
        public static void GenerateSphere(double radius, int hSegments, int vSegments, bool insideOut,
                                          out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            var radius2 = radius;

            if (insideOut)
            {
                radius2 = -radius2;
            }

            //if( radius < 0 )
            //	Log.Fatal( "SimpleMeshGenerator: GenerateSphere: radius < 0." );
            if (hSegments < 3)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateSphere: hSegments < 3.");
            }
            if (vSegments < 2)
            {
                Log.Fatal("SimpleMeshGenerator: GenerateSphere: vSegments < 2.");
            }

            //positions
            {
                int vertexCount = (hSegments + 1) * (vSegments + 1);
                positions = new Vector3[vertexCount];
                normals   = new Vector3[vertexCount];
                tangents  = new Vector4[vertexCount];
                texCoords = new Vector2[vertexCount];

                int currentPosition = 0;

                for (int v = 0; v < vSegments + 1; v++)
                {
                    for (int n = 0; n < hSegments + 1; n++)
                    {
                        SphericalDirection dir = new SphericalDirection(
                            (double)n / (double)hSegments * Math.PI * 2,
                            ((double)v / (double)vSegments - 0.5) * Math.PI);
                        positions[currentPosition] = dir.GetVector() * radius2;

                        texCoords[currentPosition] = new Vector2(
                            dir.Horizontal / (MathEx.PI * 2) * 2,
                            -dir.Vertical / MathEx.PI + 0.5);

                        if (radius2 < 0)
                        {
                            texCoords[currentPosition] = new Vector2(1.0f - texCoords[currentPosition].X, 1.0f - texCoords[currentPosition].Y);
                        }

                        currentPosition++;
                    }
                }

                if (positions.Length != currentPosition)
                {
                    Log.Fatal("SimpleMeshGenerator: GenerateSphere: positions.Length != currentPosition.");
                }
            }

            //normals
            {
                for (int n = 0; n < positions.Length; n++)
                {
                    normals[n] = positions[n].GetNormalize();
                    if (radius2 < 0)
                    {
                        normals[n] = -normals[n];
                    }
                }
            }

            //tangents
            {
                Matrix3 rotationMatrix = new Matrix3(0, -1, 0, 1, 0, 0, 0, 0, 1);

                for (int n = 0; n < positions.Length; n++)
                {
                    var p   = positions[n];
                    var rot = Quaternion.FromDirectionZAxisUp(p.GetNormalize()).ToMatrix3() * rotationMatrix;
                    if (radius2 < 0)
                    {
                        tangents[n] = new Vector4(rot * Vector3.XAxis, -1);
                    }
                    else
                    {
                        tangents[n] = new Vector4(rot * -Vector3.XAxis, -1);
                    }
                }
            }

            //indices
            {
                int indexCount = vSegments * hSegments * 6;
                indices = new int[indexCount];

                int currentIndex = 0;
                for (int v = 0; v < vSegments; v++)
                {
                    for (int n = 0; n < hSegments; n++)
                    {
                        int index = v * (hSegments + 1) + n;

                        indices[currentIndex++] = index;
                        indices[currentIndex++] = index + 1;
                        indices[currentIndex++] = index + hSegments + 1;

                        indices[currentIndex++] = index + hSegments + 1;
                        indices[currentIndex++] = index + 1;
                        indices[currentIndex++] = index + hSegments + 1 + 1;
                    }
                }

                if (indices.Length != currentIndex)
                {
                    Log.Fatal("SimpleMeshGenerator: GenerateSphere: indices.Length != currentIndex.");
                }
            }

            //??? Если нужно каждый фейс сделать прямоугольником то задать: rawVerticesInFace = rawVerticesInFaceForMiddle = 6
            faces = BuildFacesForGeoSphere(hSegments, vSegments, 3, 3, indices);
        }