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); }
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); }
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 ); }
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; }
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); }