Пример #1
2
 public Terrain(Device device, String texture, int pitch, Renderer renderer)
 {
     HeightMap = new System.Drawing.Bitmap(@"Data/Textures/"+texture);
     WaterShader = new WaterShader(device);
     TerrainShader = new TerrainShader(device);
     _width = HeightMap.Width-1;
     _height = HeightMap.Height-1;
     _pitch = pitch;
     _terrainTextures = new ShaderResourceView[4];
     _terrainTextures[0] = new Texture(device, "Sand.png").TextureResource;
     _terrainTextures[1] = new Texture(device, "Grass.png").TextureResource;
     _terrainTextures[2] = new Texture(device, "Ground.png").TextureResource;
     _terrainTextures[3] = new Texture(device, "Rock.png").TextureResource;
     _reflectionClippingPlane = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
     _refractionClippingPlane = new Vector4(0.0f, -1.0f, 0.0f, 0.0f);
     _noClippingPlane = new Vector4(0.0f, 1.0f, 0.0f, 10000);
     _reflectionTexture = new RenderTexture(device, renderer.ScreenSize);
     _refractionTexture = new RenderTexture(device, renderer.ScreenSize);
     _renderer = renderer;
     _bitmap = new Bitmap(device,_refractionTexture.ShaderResourceView,renderer.ScreenSize, new Vector2I(100, 100), 0);
     _bitmap.Position = new Vector2I(renderer.ScreenSize.X - 100, 0);
     _bitmap2 = new Bitmap(device, _reflectionTexture.ShaderResourceView, renderer.ScreenSize, new Vector2I(100, 100), 0);
     _bitmap2.Position = new Vector2I(renderer.ScreenSize.X - 100, 120);
     _bumpMap = _renderer.TextureManager.Create("OceanWater.png");
     _skydome = new ObjModel(device, "skydome.obj", renderer.TextureManager.Create("Sky.png"));
     BuildBuffers(device);
     WaveTranslation = new Vector2(0,0);
 }
        public override void RecreateControls(bool constructor)
        {
            base.RecreateControls(constructor);
            BackgroundColor = new Vector4(1f, 1f, 1f, 0.5f);

            m_instance = this;

            m_currentPosition = -m_size.Value / 2.0f + new Vector2(0.02f, 0.13f);
            //AddCheckBox("Enable frozen seas ", null, MemberHelper.GetMember(() => MyFakes.ENABLE_PLANET_FROZEN_SEA));
            //AddSlider("Sea level : ", 0f, 200f, null, MemberHelper.GetMember(() => MyCsgHeightmapHelpers.FROZEN_OCEAN_LEVEL));
            AddCheckBox("Debug draw areas: ", null, MemberHelper.GetMember(() => MyDebugDrawSettings.DEBUG_DRAW_FLORA_BOXES));

            AddCheckBox("Massive", this, MemberHelper.GetMember(() => m_massive));


            m_lodRanges = new float[MyRenderConstants.RenderQualityProfile.LodClipmapRanges[(int)ScaleGroup].Length];

            for (int i = 0; i < m_lodRanges.Length; i++)
            {
                m_lodRanges[i] = MyClipmap.LodRangeGroups[(int)ScaleGroup][i];
            }

            for (int i = 0; i < m_lodRanges.Length; i++)
            {
                int lod = i;
                AddSlider("LOD " + i, m_lodRanges[i], 0, (i < 4 ? 1000 : i < 7 ? 10000 : 300000), (s) => { ChangeValue(s.Value, lod); });
            }

        }
Пример #3
1
 public Vertex(Vertex vertex)
 {
     this.position = vertex.position;
     this.color = vertex.color;
     this.texture = vertex.texture;
     this.normal = vertex.normal;
 }
Пример #4
1
 /// <summary>
 /// Compresses a position so that its components are between 0 and 1.
 /// </summary>
 /// <param name="pos">The position to compress.</param>
 /// <returns>The compressed position.</returns>
 public Vector4 CompressPosition(Vector4 pos)
 {
     var newX = (pos.X - _info.PositionMinX) / _xScale;
     var newY = (pos.Y - _info.PositionMinY) / _yScale;
     var newZ = (pos.Z - _info.PositionMinZ) / _zScale;
     return new Vector4(newX, newY, newZ, pos.W);
 }
        public static double Compare(JointRotation firstJoint, JointRotation secondJoint)
        {
            Vector4 mainQuaternion = new Vector4();
            mainQuaternion.X = firstJoint.X;
            mainQuaternion.Y = firstJoint.Y;
            mainQuaternion.Z = firstJoint.Z;
            mainQuaternion.W = firstJoint.W;

            Vector4 secondaryQuaternion = new Vector4();
            secondaryQuaternion.X = secondJoint.X;
            secondaryQuaternion.Y = secondJoint.Y;
            secondaryQuaternion.Z = secondJoint.Z;
            secondaryQuaternion.W = secondJoint.W;

            double distanceX = mainQuaternion.X - secondaryQuaternion.X;
            double distanceY = mainQuaternion.Y - secondaryQuaternion.Y;
            double distanceZ = mainQuaternion.Z - secondaryQuaternion.Z;
            double distanceW = mainQuaternion.W - secondaryQuaternion.W;

            double similarity = distanceX*distanceX +
                distanceY * distanceY +
                distanceZ * distanceZ +
                distanceW * distanceW;

            return similarity;
        }
Пример #6
1
 /// <summary>
 /// Initializes a new instance of the <see cref="Trame.Implementation.Skeleton.OrientedJoint"/> class.
 /// </summary>
 /// <param name="type">Type.</param>
 /// <param name="valid">If set to <c>true</c> valid.</param>
 public OrientedJoint(JointType type, bool valid)
 {
     this.type = type;
     this.isValid = valid;
     orientation = new Vector4();
     point = new Vector3();
 }
Пример #7
1
 public LightManager(ProjectGame game)
 {
     packedLights = new PackedLight[MAX_LIGHTS];
     // Set the ambient color equal to the Cosmic latte
     ambientCol = new Vector4(1, 0.9725f, 0.9059f, 1.0f);
     this.game = game;
 }
Пример #8
1
        public static object ConvertToFromVector4(ITypeDescriptorContext context, CultureInfo culture, Vector4 value, Type destinationType)
        {
            if (destinationType == typeof(float))
            {
                return value.X;
            }
            if (destinationType == typeof(Vector2))
            {
                return new Vector2(value.X, value.Y);
            }
            if (destinationType == typeof(Vector3))
            {
                return new Vector3(value.X, value.Y, value.Z);
            }
            if (destinationType == typeof(Vector4))
            {
                return new Vector4(value.X, value.Y, value.Z, value.W);
            }
            if (destinationType.GetInterface("IPackedVector") != null)
            {
                IPackedVector packedVec = (IPackedVector) Activator.CreateInstance(destinationType);
                packedVec.PackFromVector4(value);
                return packedVec;
            }

            return null;
        }
Пример #9
1
        public static Vector4 UnProject(ref Matrix4 projection, Matrix4 view, Size viewport, MouseDevice mouse)
        {
            Vector4 vec;

            if (mouse.X > 0)
            {
                vec = new Vector4();
            }
            vec.X = 2.0f * mouse.X / (float)viewport.Width -1;
            vec.Y = -(2.0f * mouse.Y / (float)viewport.Height -1);
            vec.Z = 0;
            vec.W = 1.0f;

            Matrix4 viewInv = Matrix4.Invert(view);
            Matrix4 projInv = Matrix4.Invert(projection);

            Vector4.Transform(ref vec, ref projInv, out vec);
            Vector4.Transform(ref vec, ref viewInv, out vec);

            if (vec.W > float.Epsilon || vec.W < float.Epsilon)
            {
                vec.X /= vec.W;
                vec.Y /= vec.W;
                vec.Z /= vec.W;
            }

            return (vec);
        }
Пример #10
1
 public static void CalcPlane(ref Vector3 v1, ref Vector3 v2, ref Vector3 v3, out Vector4 outv)
 {
     outv.X = (v1.Y * (v2.Z - v3.Z)) + (v2.Y * (v3.Z - v1.Z)) + (v3.Y * (v1.Z - v2.Z));
     outv.Y = (v1.Z * (v2.X - v3.X)) + (v2.Z * (v3.X - v1.X)) + (v3.Z * (v1.X - v2.X));
     outv.Z = (v1.X * (v2.Y - v3.Y)) + (v2.X * (v3.Y - v1.Y)) + (v3.X * (v1.Y - v2.Y));
     outv.W = -((v1.X * ((v2.Y * v3.Z) - (v3.Y * v2.Z))) + (v2.X * ((v3.Y * v1.Z) - (v1.Y * v3.Z))) + (v3.X * ((v1.Y * v2.Z) - (v2.Y * v1.Z))));
 }
Пример #11
1
 public void AddQuad(Vector2 min, Vector2 max, Vector2 tmin, Vector2 tmax, Vector4 color, int tex)
 {
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmin.X, tmin.Y, tex));
     Vecs.Add(new Vector3(min.X, min.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmax.X, tmin.Y, tex));
     Vecs.Add(new Vector3(max.X, min.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmax.X, tmax.Y, tex));
     Vecs.Add(new Vector3(max.X, max.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmin.X, tmin.Y, tex));
     Vecs.Add(new Vector3(min.X, min.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmax.X, tmax.Y, tex));
     Vecs.Add(new Vector3(max.X, max.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
     Norms.Add(new Vector3(0, 0, 1));
     Texs.Add(new Vector3(tmin.X, tmax.Y, tex));
     Vecs.Add(new Vector3(min.X, max.Y, 0));
     Inds.Add((uint)(Vecs.Count - 1));
     Cols.Add(color);
 }
Пример #12
1
        public Vector4 apply(Vector4 v)
        {
            Matrix mt = _matrix; mt.Transpose();
            Vector4 v4 = Vector4.Transform(v, mt);

            return new Vector4(v4.X+_vector.X, v4.Y+_vector.Y, v4.Z+_vector.Z, 1);
        }
        public static void Run()
        {
            // ExStart:SetupNormalsOnCube
            // Raw normal data
            Vector4[] normals = new Vector4[]
            {
                new Vector4(-0.577350258,-0.577350258, 0.577350258, 1.0),
                new Vector4( 0.577350258,-0.577350258, 0.577350258, 1.0),
                new Vector4( 0.577350258, 0.577350258, 0.577350258, 1.0),
                new Vector4(-0.577350258, 0.577350258, 0.577350258, 1.0),
                new Vector4(-0.577350258,-0.577350258,-0.577350258, 1.0),
                new Vector4( 0.577350258,-0.577350258,-0.577350258, 1.0),
                new Vector4( 0.577350258, 0.577350258,-0.577350258, 1.0),
                new Vector4(-0.577350258, 0.577350258,-0.577350258, 1.0)
            };

            // Call Common class create mesh using polygon builder method to set mesh instance 
            Mesh mesh = Common.CreateMeshUsingPolygonBuilder(); 

            VertexElementNormal elementNormal = mesh.CreateElement(VertexElementType.Normal, MappingMode.ControlPoint, ReferenceMode.Direct) as VertexElementNormal;
            // Copy the data to the vertex element
            elementNormal.Data.AddRange(normals);
            // ExEnd:SetupNormalsOnCube

            Console.WriteLine("\nNormals has been setup successfully on cube.");
        }
Пример #14
1
        public override void BeginRenderObject( Gas.Graphics.Material material )
        {
            effect.SetValue( "world", renderer.WorldMatrix );
            effect.SetValue( "worldViewProj", renderer.WorldViewProjectionMatrix );
            effect.SetValue( "diffuseMap", material.Textures[ 0 ] );

            Vector4[] lightPos = new Vector4[ 4 ];
            Vector4[] lightColor = new Vector4[ 4 ];
            float[] range = new float[ 4 ];

            for ( int i = 0; i < renderer.Lights.Count && i < 4; ++i )
            {
                lightPos[ i ] = new Vector4( renderer.Lights[ i ].Position.X,
                    renderer.Lights[ i ].Position.Y, 1.0f, 1.0f );
                lightColor[ i ] = new Vector4( ( float )renderer.Lights[ i ].Color.R / 255.0f,
                    ( float )renderer.Lights[ i ].Color.G / 255.0f,
                    ( float )renderer.Lights[ i ].Color.B / 255.0f,
                    ( float )renderer.Lights[ i ].Color.A / 255.0f );
                range[ i ] = renderer.Lights[ i ].Range;
            }

            effect.SetValue( "lightPos", lightPos );
            effect.SetValue( "lightColor", lightColor );
            effect.SetValue( "range", range );
            effect.SetValue( "numActiveLights", renderer.Lights.Count );

            effect.CommitChanges();
        }
Пример #15
1
 public void Write(Vector4 value)
 {
     this.Write(value.X);
     this.Write(value.Y);
     this.Write(value.Z);
     this.Write(value.W);
 }
Пример #16
1
 /// <summary>
 /// 
 /// </summary>
 /// <param name="game"></param>
 public GraphSystem( Game game )
     : base(game)
 {
     Config = new ParticleConfig();
     HighlightNodeColor = new Vector4(0, 1, 0, 1);
     HighlightEdgeColor = new Vector4(0, 1, 0, 1);
 }
        /// <summary>
        /// Update the joint orientation based on the referenced <c>IJointOrientation</c>.
        /// </summary>
        public virtual void Update(IJointOrientation jointOrientation)
        {
            if (this.JointType != jointOrientation.JointType)
                throw new Exception("Cannot Update with Joint of a different Type");

            _orientation = jointOrientation.Orientation;
        }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var materialBuilder = builder as MyObjectBuilder_TransparentMaterialDefinition;
            MyDebug.AssertDebug(materialBuilder != null, "Initializing transparent material definition using wrong object builder.");

            Texture = materialBuilder.Texture;
            TextureType = materialBuilder.TextureType;
            CanBeAffectedByLights = materialBuilder.CanBeAffectedByOtherLights;
            AlphaMistingEnable = materialBuilder.AlphaMistingEnable;
            IgnoreDepth = materialBuilder.IgnoreDepth;
            NeedSort = materialBuilder.NeedSort;
            UseAtlas = materialBuilder.UseAtlas;
            AlphaMistingStart = materialBuilder.AlphaMistingStart;
            AlphaMistingEnd = materialBuilder.AlphaMistingEnd;
            SoftParticleDistanceScale = materialBuilder.SoftParticleDistanceScale;
            Emissivity = materialBuilder.Emissivity;
            AlphaSaturation = materialBuilder.AlphaSaturation;
            Reflection = materialBuilder.Reflection;
            Reflectivity = materialBuilder.Reflectivity;
            Color = materialBuilder.Color;
            AlphaCutout = materialBuilder.AlphaCutout;
            TargetSize = materialBuilder.TargetSize;
        }   
        public void Start(MyDistantObjectImpostorTypeEnum type)
        {
            float angleHorizontal = MathHelper.ToRadians(MyUtils.GetRandomFloat(0, 360));
            float angleVertical = MathHelper.ToRadians(MyUtils.GetRandomFloat(0, 360));

            float LOW_PRIORITY_ANGLE = MathHelper.ToRadians(45);
            if (((angleVertical >= (MathHelper.PiOver2 - LOW_PRIORITY_ANGLE)) && (angleVertical <= (MathHelper.PiOver2 + LOW_PRIORITY_ANGLE))) ||
                ((angleVertical >= (3 * MathHelper.PiOver2 - LOW_PRIORITY_ANGLE)) && (angleVertical <= (3 * MathHelper.PiOver2 + LOW_PRIORITY_ANGLE))))
            {
                angleVertical = MathHelper.ToRadians(MyUtils.GetRandomFloat(0, 360));
            }
            
            int typeEnum = MyUtils.GetRandomInt(0, 3);
            m_angleHorizontal = angleHorizontal;
            m_angleVertical = angleVertical;           
            Angle = 0;
            Color = new Vector4(1f, 1f, 1f, 1f);
            Type = type;
            m_fading = true;
            m_glowTime = 0;

            //  We make a random starting alpha and a random blink multiplier
            //  so they don't all blink at the same time
            if (Type == MyDistantObjectImpostorTypeEnum.Blinker)
            {
                Radius = MyUtils.GetRandomFloat(3000, 5000f);
                m_blinkMultiplierUp = MyUtils.GetRandomFloat(70f, 90.0f);
                m_blinkMultiplierDown = MyUtils.GetRandomFloat(70f, 90.0f);
                m_startingRadius = Radius;
            }

            //  Moving objects are initialized with a random destination
            if (Type == MyDistantObjectImpostorTypeEnum.Mover)
            {
                
                Radius = MyUtils.GetRandomFloat(4000, 6000f);
                m_targetHorizontal = MathHelper.ToRadians(MyUtils.GetRandomFloat(0, 360));
                m_moverSpeed = MyUtils.GetRandomFloat(MyDistantObjectsImpostorsConstants.MAX_MOVE_DISTANCE*0.3f, MyDistantObjectsImpostorsConstants.MAX_MOVE_DISTANCE);
            }

            //  Explosions also have a blink multiplier to make flashes more random.
            //  Explosions will appear around their targer angles, but
            //  will stay in the same general area
            if (Type == MyDistantObjectImpostorTypeEnum.Explosion)
            {
                Radius = MyUtils.GetRandomFloat(4000f, 6000f);
                Color.X = MyUtils.GetRandomFloat(170.0f / 255f, 1.0f);
                Color.Y = MyUtils.GetRandomFloat(100.0f / 255f, Color.X);
                Color.Z = MyUtils.GetRandomFloat(0.0f, 40.0f / 255f);
                Color.W = MyUtils.GetRandomFloat(0.0f, 1.0f);
                m_blinkMultiplierUp = MyUtils.GetRandomFloat(11f, 16f);
                m_blinkMultiplierDown = MyUtils.GetRandomFloat(0.5f, 2f);
                m_targetHorizontal = m_angleHorizontal;
                m_targetVertical = m_angleVertical;
                m_startingRadius = Radius;
                m_IsWaiting = false;
                m_exploding = Convert.ToBoolean(MyUtils.GetRandomInt(0,1));
                m_explosionDelay = MyUtils.GetRandomInt((int)(MyDistantObjectsImpostorsConstants.EXPLOSION_WAIT_MILLISECONDS / 2.0f), (int)(MyDistantObjectsImpostorsConstants.EXPLOSION_WAIT_MILLISECONDS * 3f));
            }
        }
Пример #20
1
 public void Write(Vector4 value)
 {
     Write(value.X);
     Write(value.Y);
     Write(value.Z);
     Write(value.W);
 }
 public static void Serialize(this BitStream stream, ref Vector4 vec)
 {
     stream.Serialize(ref vec.X);
     stream.Serialize(ref vec.Y);
     stream.Serialize(ref vec.Z);
     stream.Serialize(ref vec.W);
 }
Пример #22
0
 protected MyGuiScreenDebugBase(Vector2 position, Vector2? size, Vector4? backgroundColor, bool isTopMostScreen) :
     base(position, backgroundColor, size, isTopMostScreen, null)
 {
     m_screenCanHide = false;
     m_canCloseInCloseAllScreenCalls = false;
     m_canShareInput = true;
 }
Пример #23
0
 /// <summary>
 /// Decompresses a position so that its components are in model space.
 /// </summary>
 /// <param name="pos">The position to decompress.</param>
 /// <returns>The decompressed position.</returns>
 public Vector4 DecompressPosition(Vector4 pos)
 {
     var newX = pos.X * _xScale + _info.PositionMinX;
     var newY = pos.Y * _yScale + _info.PositionMinY;
     var newZ = pos.Z * _zScale + _info.PositionMinZ;
     return new Vector4(newX, newY, newZ, pos.W);
 }
Пример #24
0
        protected MyGuiControlCheckbox addCheckBox(StringBuilder text, bool enabled = true, List<MyGuiControlBase> controlGroup = null, Vector4? color = null)
        {
            MyGuiControlLabel label = new MyGuiControlLabel(this, m_currentPosition, null, text, color ?? m_defaultColor, MyGuiConstants.LABEL_TEXT_SCALE * MyGuiConstants.DEBUG_LABEL_TEXT_SCALE * m_scale,
                                                            MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER);

            float labelWidth = label.GetTextSize().Size.X + 0.02f;
            m_maxWidth = Math.Max(m_maxWidth, labelWidth);
            label.Enabled = enabled;
            Controls.Add(label);


            Vector2? m = this.GetSize();

            Vector2 checkBoxSize = MyGuiConstants.CHECKBOX_SIZE * m_scale;
            MyGuiControlCheckbox checkBox = new MyGuiControlCheckbox(this, m_currentPosition + new Vector2(m.Value.X - 2 * checkBoxSize.X - m_checkBoxOffset, 0),
                checkBoxSize, false, 0.8f * (color ?? m_defaultColor));
            checkBox.Enabled = enabled;

            Controls.Add(checkBox);

            m_currentPosition.Y += 0.04f * m_scale;

            if (controlGroup != null)
            {
                controlGroup.Add(label);
                controlGroup.Add(checkBox);
            }

            return checkBox;
        }
Пример #25
0
 public PSAQuad(Vector4 v)
 {
     w = v.W;
     x = v.X;
     y = v.Y;
     z = v.Z;
 }
Пример #26
0
        protected MyGuiControlCheckbox AddCheckBox(StringBuilder text, MyGuiScreenDebugBase screen, List<MyGuiControlBase> controlGroup = null, Vector4? color = null)
        {
            MyGuiControlCheckbox checkBox = addCheckBox(text, true, controlGroup, color);

            checkBox.Checked = screen.GetState() == MyGuiScreenState.OPENED;
            checkBox.UserData = screen;

            checkBox.OnCheck = delegate(MyGuiControlCheckbox sender)
            {
                MyGuiScreenDebugBase screenSender = sender.UserData as MyGuiScreenDebugBase;
                if (sender.Checked)
                {
                    MyGuiManager.AddScreen(screenSender);
                    screenSender.SetState(MyGuiScreenState.OPENING);
                    screenSender.LoadContent();
                    screenSender.RecreateControls(false);
                }
                else
                {
                    screenSender.CloseScreen();
                }
            };

            return checkBox;
        }
Пример #27
0
 public Vertex(Vector4 position, Vector4 normal, Vector4 color, Vector4 texture)
 {
     this.position = position;
     this.color = color;
     this.texture = texture;
     this.normal = normal;
 }
Пример #28
0
 public void move(float d_pos)
 {
     Matrix4 translation = Matrix4.CreateTranslation((d_pos * heading).Xyz);
     position += new Vector4((d_pos * heading).Xyz);
     transformation *= translation;
     notifyCameras();
 }
Пример #29
0
 public MyRichLabelText()
 {
     m_text = new StringBuilder(512);
     m_font = MyFontEnum.Blue;
     m_scale = 0;
     m_color = Vector4.Zero;
 }
Пример #30
0
        public double RayIntersection(Vector3 RPos, Vector3 RDir)
        {
            Vector4 rpos = new Vector4(RPos - _pos, 1);
            Vector4 rdir = new Vector4(RDir, 1);
            rpos = Vector4.Transform(rpos, _invAxes);
            rdir = Vector4.Transform(rdir, _invAxes);

            //Quadractic Formula
            double A = Vector3.Dot(rdir.Xyz, rdir.Xyz);
            double B = 2 * (Vector3.Dot(rdir.Xyz, rpos.Xyz));
            double C = Vector3.Dot(rpos.Xyz, rpos.Xyz) - 1;
            double disc = (B * B) - (4 * A * C);
            if (disc < 0) {
                return Double.NaN;
            }
            double q = 0;
            if (B < 0)
                q = -B + Math.Sqrt(disc);
            else
                q = -B - Math.Sqrt(disc);
            q /= 2;
            double t0 = q / A;
            double t1 = C / q;
            if (Math.Abs(t0) < Math.Abs(t1))
                return t0;
            else
                return t1;
        }