/// <summary> /// Quaternion constructor from euler rotation axis and rotation angle. /// </summary> /// <param name="rVector"> /// A <see cref="Vertex3f"/> representing the rotation axis. /// </param> /// <param name="rAngle"> /// A <see cref="System.Single"/> representing the rotation angle (in degrees). /// </param> /// <remarks> /// This constructor is the base implementation for each other constructor. /// </remarks> public Quaternion(Vertex3f rVector, float rAngle) { // Set the default rotation axis mDefaultVector = (Vertex3d)rVector; // Make compiler happy mVector = new Vertex3d(); mCosAngle = 0.0f; // Set quaternion SetEuler(rVector, rAngle); }
public static void translate(Vertex3f translation, Matrix4f src, out Matrix4f des) { Matrix4f translationMatrix = new Matrix4f(); translationMatrix.SetIdentity(); float[] matbuffer = translationMatrix.Buffer; matbuffer[12] = translation.x; matbuffer[13] = translation.y; matbuffer[14] = translation.z; Matrix tempmat = (Matrix) new Matrix(matbuffer, 4, 4).Multiply(src); des = new Matrix4f(tempmat.Buffer); }
public void Render(Camera camera, Vertex3f fogColor, float frameTimeSec) { this.shader.Start(); this.shader.LoadViewMatrix(camera, frameTimeSec); this.shader.LoadFogColor(fogColor); Gl.BindVertexArray(this.cube.VaoID); Gl.EnableVertexAttribArray(0); BindTextures(frameTimeSec); Gl.DrawArrays(PrimitiveType.Triangles, 0, this.cube.VertexCount); Gl.DisableVertexAttribArray(0); Gl.BindVertexArray(0); this.shader.Stop(); }
private void UpdateGlobalLight() { float az = Angle.ToRadians(_GlobalLightAz); float el = Angle.ToRadians(_GlobalLightEl); float xAz = (float)Math.Cos(az), yAz = (float)Math.Sin(az); float xEl = (float)Math.Cos(el), yEl = (float)Math.Sin(el); Vertex3f dir = new Vertex3f( xAz, yEl, yAz ); // _GlobalLightObject.Direction = dir.Normalized; }
/// <summary> /// Set quaternion using rotation axis and rotation angle. /// </summary> /// <param name="rVector"> /// A <see cref="Vertex3f"/> representing the rotation axis. It will be normalized. /// </param> /// <param name="rAngle"> /// A <see cref="float"/> representing the rotation angle (in degrees). /// </param> /// <remarks> /// This quaternion will result normalized. /// </remarks> public void SetEuler(Vertex3f rVector, float rAngle) { double qAngle = Angle.ToRadians(rAngle / 2.0f); double qAngleSin = Math.Sin(qAngle); _Vector.x = qAngleSin * rVector.x; _Vector.y = qAngleSin * rVector.y; _Vector.z = qAngleSin * rVector.z; _CosAngle = Math.Cos(qAngle); // Ensure normalized quaternion Normalize(); }
public void UpdateMove(Vertex3f targetPosition, float targetRotationY, InputManager input) { if (input.IsMouseLeftDown) { UpdatePitch(input.MouseDeltaY); } if (input.IsMouseRightDown) { UpdateAngleAroundPlayer(input.MouseDeltaX); } UpdatePosition(targetPosition, targetRotationY); }
/// <summary> /// Set uniform state variable (vec3 variable). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="v"> /// A <see cref="Vertex3f"/> holding the uniform variabile data. /// </param> public void SetUniform(string uniformName, Vertex3f v) { UniformSegment uniform = GetUniform(uniformName); if (uniform == null) { return; } uniform.CheckType(Gl.FLOAT_VEC3, Gl.BOOL_VEC3); Set(v, (ulong)uniform.Offset); }
public void ColorRGBF_CastToVertex4() { float r = (float)NextComponent(1.0f); float g = (float)NextComponent(1.0f); float b = (float)NextComponent(1.0f); ColorRGBF v = new ColorRGBF(r, g, b); Vertex3f vArray = v; Assert.AreEqual(r, vArray.x); Assert.AreEqual(g, vArray.y); Assert.AreEqual(b, vArray.z); }
public static void scale(Vertex3f vector, Matrix4f src, ref Matrix4f dest) { Matrix4f scalerMatrix = new Matrix4f(); scalerMatrix.SetIdentity(); float[] matbuffer = scalerMatrix.Buffer; matbuffer[0] = vector.x; matbuffer[5] = vector.y; matbuffer[10] = vector.z; Matrix tempmat = (Matrix) new Matrix(matbuffer, 4, 4).Multiply(src); dest = new Matrix4f(tempmat.Buffer); }
public void TestUniform3f() { if (!HasVersion(2, 0) && !HasEsVersion(2, 0) && !IsGlExtensionSupported("GL_ARB_shader_objects")) { Assert.Inconclusive("required features not implemented"); } uint program = CreateProgramUniform3f(); try { Vertex3f uniformStruct; float[] uniformValue; int uniformLoc = Gl.GetUniformLocation(program, "uVec"); if (uniformLoc < 0) { throw new InvalidOperationException("no uniform variable"); } // glGetUniformfv uniformValue = Array3(1.0f); Gl.GetUniform(program, uniformLoc, uniformValue); CollectionAssert.AreEqual(Array3(0.0f), uniformValue); // glGetUniformfv (ref) uniformStruct = new Vertex3f(1.0f); Gl.GetUniformf(program, uniformLoc, ref uniformStruct); Assert.AreEqual(Vertex3f.Zero, uniformStruct); // glUniform3f uniformValue = Array3(0.0f); Gl.Uniform3(uniformLoc, Array3(1.0f)); Gl.GetUniform(program, uniformLoc, uniformValue); CollectionAssert.AreEqual(Array3(1.0f), uniformValue); // glUniform3fv uniformValue = Array3(0.0f); Gl.Uniform3(uniformLoc, Array3(9.0f)); Gl.GetUniform(program, uniformLoc, uniformValue); CollectionAssert.AreEqual(Array3(9.0f), uniformValue); // glUniform3fv (ref) uniformValue = Array3(0.0f); uniformStruct = new Vertex3f(5.0f); Gl.Uniform3f(uniformLoc, 1, ref uniformStruct); Gl.GetUniform(program, uniformLoc, uniformValue); CollectionAssert.AreEqual(Array3(5.0f), uniformValue); } finally { Gl.DeleteProgram(program); } }
/// <summary> /// Generate the texture coordinate for the specified vertex. /// </summary> /// <param name="v"></param> /// <returns></returns> public override Vertex2f Generate(Vertex3f v) { v.Normalize(); float x = (float)(Math.Atan2(v.z, v.x) / Math.PI) * 0.5f + 0.5f; float y = (float)(Math.Asin(v.y) / (Math.PI / 2.0)) * 0.5f + 0.5f; Debug.Assert(x >= 0.0f && x <= 1.0f); Debug.Assert(y >= 0.0f && y <= 1.0f); return(new Vertex2f(x, y)); return(new Vertex2f(x * Repeat.x, y * Repeat.y)); }
public void ColorBGRF_CastToVertex4() { Random random = new Random(); float r = (float)NextComponent(random, 1.0f); float g = (float)NextComponent(random, 1.0f); float b = (float)NextComponent(random, 1.0f); ColorBGRF v = new ColorBGRF(r, g, b); Vertex3f vArray = v; Assert.AreEqual(b, vArray.x); Assert.AreEqual(g, vArray.y); Assert.AreEqual(r, vArray.z); }
public static Matrix4f createViewMatrix(Camera camera) { Matrix4f viewMatrix = new Matrix4f(); viewMatrix.SetIdentity(); Matrix4f.rotate(math.toRadians(camera.pitch), new Vertex3f(1, 0, 0), viewMatrix, ref viewMatrix); Matrix4f.rotate(math.toRadians(camera.yaw), new Vertex3f(0, 1, 0), viewMatrix, ref viewMatrix); Vertex3f cameraPos = camera.positin; Vertex3f negativeCameraPos = new Vertex3f(-cameraPos.x, -cameraPos.y, -cameraPos.z); Matrix4f.translate(negativeCameraPos, viewMatrix, out viewMatrix); return(viewMatrix); }
public static Matrix4f createTransformationMatrix(Vertex3f translation, float rx, float ry, float rz, float scale) { Matrix4f matrix = new Matrix4f(); matrix.SetIdentity(); Matrix4f.scale(new Vertex3f(scale, scale, scale), matrix, ref matrix); Matrix4f.rotate(math.toRadians(rx), new Vertex3f(1, 0, 0), matrix, ref matrix); Matrix4f.rotate(math.toRadians(ry), new Vertex3f(0, 1, 0), matrix, ref matrix); Matrix4f.rotate(math.toRadians(rz), new Vertex3f(0, 0, 1), matrix, ref matrix); Matrix4f.translate(translation, matrix, out matrix); return(matrix); }
private bool IsInRangeRay(float start, float finish, Vertex3f ray) { Vertex3f startPoint = GetPointOnRay(ray, start); Vertex3f endPoint = GetPointOnRay(ray, finish); if (IsUnderGround(startPoint) == false && IsUnderGround(endPoint)) { return(true); } else { return(false); } }
/// <summary> /// Determine whether this bound volume is clipped by all specified planes. /// </summary> /// <param name="clippingPlanes"> /// A <see cref="IEnumerable{Plane}"/> that are used to perform geometry clipping. /// </param> /// <returns> /// It returns a boolean value indicating whether this bound volume is entirely /// clipped by <paramref name="clippingPlanes"/>. /// </returns> public bool IsClipped(IEnumerable <Plane> clippingPlanes, State.TransformStateBase objectModel) { Vertex3f sphereOrigin = (Vertex3f)objectModel.ModelView.Position; foreach (Plane plane in clippingPlanes) { if (plane.GetDistance(sphereOrigin) < _Radius) { return(true); } } return(false); }
/// <summary> /// Set an element to this mapped BufferObject. /// </summary> /// <param name="value"> /// A <see cref="Vertex3f"/> that specify the mapped BufferObject element. /// </param> /// <param name="offset"> /// A <see cref="UInt64"/> that specify the offset applied to the mapped BufferObject where <paramref name="value"/> /// is stored. This value is expressed in basic machine units (bytes). /// </param> /// <exception cref="InvalidOperationException"> /// Exception thrown if this BufferObject is not mapped (<see cref="IsMapped"/>). /// </exception> public void Set(Vertex3f value, UInt64 offset) { if (IsMapped == false) { throw new InvalidOperationException("not mapped"); } unsafe { byte * bufferPtr = (byte *)MappedBuffer.ToPointer(); Vertex3f *bufferItemPtr = (Vertex3f *)(bufferPtr + offset); bufferItemPtr[0] = value; } }
private static void processVertex(ref string[] vertexData, ref List <uint> indices, ref List <Vertex2f> textures, ref List <Vertex3f> normals, ref float[] textureArray, ref float[] normalsArray) { uint currentVertexPointer = uint.Parse(vertexData[0]) - 1; indices.Add(currentVertexPointer); Vertex2f currentTex = textures[int.Parse(vertexData[1]) - 1]; textureArray[currentVertexPointer * 2] = currentTex.x; textureArray[currentVertexPointer * 2 + 1] = 1 - currentTex.y; Vertex3f currentNorm = normals[int.Parse(vertexData[2]) - 1]; normalsArray[currentVertexPointer * 3] = currentNorm.x; normalsArray[currentVertexPointer * 3 + 1] = currentNorm.y; normalsArray[currentVertexPointer * 3 + 2] = currentNorm.z; }
public void TestPerspectiveFrustumNoModelView() { PerspectiveProjectionMatrix projectionMatrix = new PerspectiveProjectionMatrix(60.0f, 1.0f, 1.0f, 10.0f); BoundingBox boundingBox; Vertex3f bboxPosition; IEnumerable <Plane> planes = Plane.GetFrustumPlanes(projectionMatrix); bboxPosition = new Vertex3f(-0.5f, -0.5f, -3.0f); boundingBox = new BoundingBox(bboxPosition, bboxPosition + Vertex3f.One); Assert.IsFalse(boundingBox.IsClipped(planes)); bboxPosition = new Vertex3f(-10.5f, -10.5f, -3.0f); boundingBox = new BoundingBox(bboxPosition, bboxPosition + Vertex3f.One); Assert.IsTrue(boundingBox.IsClipped(planes)); }
private void GenerateNormalsTriangle3f(IVertexArray positionArray, IVertexArray normalArray) { uint count = (ElementCount != 0 ? ElementCount : _VertexArrayObject.ArrayLength) / 3; for (uint i = 0, v = ElementOffset; i < count; i++) { Vertex3f v0 = positionArray.GetElement <Vertex3f>(v++); Vertex3f v1 = positionArray.GetElement <Vertex3f>(v++); Vertex3f v2 = positionArray.GetElement <Vertex3f>(v++); Vertex3f n = ((v2 - v0) ^ (v1 - v0)).Normalized; normalArray.SetElement <Vertex3f>(n, v - 2); normalArray.SetElement <Vertex3f>(n, v - 1); normalArray.SetElement <Vertex3f>(n, v - 0); } }
protected static void EstimateBoundingSphare(MeshVertex[] vertices, out Vertex3f center, out float radious) { float x0 = float.MaxValue, y0 = float.MaxValue, z0 = float.MaxValue; float x9 = float.MinValue, y9 = float.MinValue, z9 = float.MinValue; for (int i = 0; i < vertices.Length; i++) { var v = vertices[i].Coord; if (v.x < x0) { x0 = v.x; } if (v.x > x9) { x9 = v.x; } if (v.y < y0) { y0 = v.y; } if (v.y > y9) { y9 = v.y; } if (v.z < z0) { z0 = v.z; } if (v.z > z9) { z9 = v.z; } } var p = center = new Vertex3f((x0 + x9) / 2, (y0 + y9) / 2, (z0 + z9) / 2); float r9 = 0; for (int i = 0; i < vertices.Length; i++) { var r = (vertices[i].Coord - p).ModuleSquared(); if (r > r9) { r9 = r; } } radious = (float)Math.Sqrt(r9); }
private static void SetBoundingVolumeState(BoundingBox boundingVolume, GraphicsStateSet volumeState) { // Set transform state TransformStateBase transformState = (TransformStateBase)volumeState[TransformStateBase.StateSetIndex]; if (transformState == null) { return; } Vertex3f min = boundingVolume.MinPosition, max = boundingVolume.MaxPosition; Vertex3f size = boundingVolume.Size; // Scale model matrix in order to represent the bounding box with the correct size and barycenter transformState.LocalModelViewProjection.Translate((max + min) / 2.0f); transformState.LocalModelViewProjection.Scale(size); }
private Vertex3f GetMovement(Keys keys) { var movement = new Vertex3f(); if (keys == Keys.NumPad8 || keys == Keys.NumPad7 || keys == Keys.NumPad9) { movement.y = 1; } else if (keys == Keys.NumPad2 || keys == Keys.NumPad1 || keys == Keys.NumPad3) { movement.y = -1; } else { movement.y = 0; } if (keys == Keys.NumPad4 || keys == Keys.NumPad7 || keys == Keys.NumPad1) { movement.x = -1; } else if (keys == Keys.NumPad6 || keys == Keys.NumPad3 || keys == Keys.NumPad9) { movement.x = 1; } else { movement.x = 0; } if (keys == Keys.Subtract) { movement.z = -1; } else if (keys == Keys.Add) { movement.z = 1; } else { movement.z = 0; } return(movement); }
/// <summary> /// Get a list of <see cref="GlyphModelType"/> for a specific string and model-view-projection matrix. /// </summary> /// <param name="modelview"></param> /// <param name="s"></param> /// <returns></returns> private List <GlyphModelType> GetGlyphsInstances(Matrix4x4 modelview, string s) { ModelMatrix charModel = new ModelMatrix(modelview); List <GlyphModelType> glyphsInstances = new List <GlyphModelType>(); char[] fontChars = s.ToCharArray(); for (int i = 0; i < fontChars.Length; i++) { Glyph glyph; if (_GlyphMetadata.TryGetValue(fontChars[i], out glyph) == false) { continue; } // Set instance information Matrix4x4f modelViewProjection = new Matrix4x4f( new Vertex4f(charModel.GetColumn(0)), new Vertex4f(charModel.GetColumn(1)), new Vertex4f(charModel.GetColumn(2)), new Vertex4f(charModel.GetColumn(3)) ); Vertex3f glyphVertexParams = new Vertex3f( glyph.GlyphSize.Width, glyph.GlyphSize.Height, glyph.Layer ); Vertex2f glyphTexParams = new Vertex2f( glyph.TexScale.Width, glyph.TexScale.Height ); GlyphModelType glyphModel = new GlyphModelType(); glyphModel.ModelViewProjection = modelViewProjection; glyphModel.VertexParams = glyphVertexParams; glyphModel.TexParams = glyphTexParams; glyphsInstances.Add(glyphModel); // Move next charModel.Translate(glyph.GlyphSize.Width, 0.0f); } return(glyphsInstances); }
private bool IsUnderGround(Vertex3f testPoint) { Terrain terrain = GetTerrain(testPoint.x, testPoint.z); float height = 0; if (terrain != null) { height = terrain.GetHeightOfTerrain(testPoint.x, testPoint.z); } if (testPoint.y < height) { return(true); } else { return(false); } }
/// <summary> /// Determine whether this bound volume is clipped by all specified planes. /// </summary> /// <param name="clippingPlanes"> /// A <see cref="IEnumerable{Plane}"/> that are used to perform geometry clipping. /// </param> /// <returns> /// It returns a boolean value indicating whether this bound volume is entirely /// clipped by <paramref name="clippingPlanes"/>. /// </returns> public bool IsClipped(IEnumerable <Plane> clippingPlanes, Matrix4x4f viewModel) { if (clippingPlanes == null) { throw new ArgumentNullException("clippingPlanes"); } Vertex3f[] boundVertices = new Vertex3f[8]; Vertex3f[] viewVertices = new Vertex3f[2]; for (int i = 0; i < 2; i++) { viewVertices[i] = (Vertex3f)(viewModel * _Bounds[i]); } // Lower box vertices boundVertices[0] = new Vertex3f(viewVertices[1].x, viewVertices[0].y, viewVertices[1].z); boundVertices[1] = new Vertex3f(viewVertices[0].x, viewVertices[0].y, viewVertices[1].z); boundVertices[2] = new Vertex3f(viewVertices[0].x, viewVertices[0].y, viewVertices[0].z); boundVertices[3] = new Vertex3f(viewVertices[1].x, viewVertices[0].y, viewVertices[0].z); // Higher box vertices boundVertices[4] = new Vertex3f(viewVertices[1].x, viewVertices[1].y, viewVertices[1].z); boundVertices[5] = new Vertex3f(viewVertices[0].x, viewVertices[1].y, viewVertices[1].z); boundVertices[6] = new Vertex3f(viewVertices[0].x, viewVertices[1].y, viewVertices[0].z); boundVertices[7] = new Vertex3f(viewVertices[1].x, viewVertices[1].y, viewVertices[0].z); foreach (Plane clipPlane in clippingPlanes) { bool outsidePlane = true; for (int i = 0; i < boundVertices.Length && outsidePlane; i++) { outsidePlane &= clipPlane.GetDistance(boundVertices[i]) < 0.0f; } if (outsidePlane) { return(true); } } return(false); }
public void TestPosYPlane() { Plane plane = new Plane("Y", Vertex3f.UnitY, 0.0f); // Positive half-space Vertex3f[] pointsPosY = new Vertex3f[] { new Vertex3f(+1.0f, 1.0f, +1.0f), new Vertex3f(+1.0f, 1.0f, -1.0f), new Vertex3f(-1.0f, 1.0f, +1.0f), new Vertex3f(-1.0f, 1.0f, -1.0f), }; foreach (Vertex3f v in pointsPosY) { Assert.IsTrue(plane.GetDistance(v) > 0.0f); } // Negative half-space Vertex3f[] pointsNegY = new Vertex3f[] { new Vertex3f(+1.0f, -1.0f, +1.0f), new Vertex3f(+1.0f, -1.0f, -1.0f), new Vertex3f(-1.0f, -1.0f, +1.0f), new Vertex3f(-1.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsNegY) { Assert.IsTrue(plane.GetDistance(v) < 0.0f); } // On-plane Vertex3f[] pointsZero = new Vertex3f[] { new Vertex3f(+1.0f, 0.0f, +1.0f), new Vertex3f(+1.0f, 0.0f, -1.0f), new Vertex3f(-1.0f, 0.0f, +1.0f), new Vertex3f(-1.0f, 0.0f, -1.0f), }; foreach (Vertex3f v in pointsZero) { Assert.AreEqual(0.0f, plane.GetDistance(v)); } }
public void TestNegXPlane() { Plane plane = new Plane("-X", -Vertex3f.UnitX, 0.0f); // Positive half-space Vertex3f[] pointsPosX = new Vertex3f[] { new Vertex3f(1.0f, +1.0f, +1.0f), new Vertex3f(1.0f, +1.0f, -1.0f), new Vertex3f(1.0f, -1.0f, +1.0f), new Vertex3f(1.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsPosX) { Assert.IsTrue(plane.GetDistance(v) < 0.0f); } // Negative half-space Vertex3f[] pointsNegX = new Vertex3f[] { new Vertex3f(-1.0f, +1.0f, +1.0f), new Vertex3f(-1.0f, +1.0f, -1.0f), new Vertex3f(-1.0f, -1.0f, +1.0f), new Vertex3f(-1.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsNegX) { Assert.IsTrue(plane.GetDistance(v) > 0.0f); } // On-plane Vertex3f[] pointsZero = new Vertex3f[] { new Vertex3f(0.0f, +1.0f, +1.0f), new Vertex3f(0.0f, +1.0f, -1.0f), new Vertex3f(0.0f, -1.0f, +1.0f), new Vertex3f(0.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsZero) { Assert.AreEqual(0.0f, plane.GetDistance(v)); } }
public void TestNegZPlane() { Plane plane = new Plane("-Z", -Vertex3f.UnitZ, 0.0f); // Positive half-space Vertex3f[] pointsPosZ = new Vertex3f[] { new Vertex3f(+1.0f, +1.0f, 1.0f), new Vertex3f(+1.0f, -1.0f, 1.0f), new Vertex3f(-1.0f, +1.0f, 1.0f), new Vertex3f(-1.0f, -1.0f, 1.0f), }; foreach (Vertex3f v in pointsPosZ) { Assert.Less(plane.GetDistance(v), 0.0f); } // Negative half-space Vertex3f[] pointsNegZ = new Vertex3f[] { new Vertex3f(+1.0f, +1.0f, -1.0f), new Vertex3f(+1.0f, -1.0f, -1.0f), new Vertex3f(-1.0f, +1.0f, -1.0f), new Vertex3f(-1.0f, -1.0f, -1.0f), }; foreach (Vertex3f v in pointsNegZ) { Assert.Greater(plane.GetDistance(v), 0.0f); } // On-plane Vertex3f[] pointsZero = new Vertex3f[] { new Vertex3f(+1.0f, +1.0f, 0.0f), new Vertex3f(+1.0f, -1.0f, 0.0f), new Vertex3f(-1.0f, +1.0f, 0.0f), new Vertex3f(-1.0f, -1.0f, 0.0f), }; foreach (Vertex3f v in pointsZero) { Assert.AreEqual(0.0f, plane.GetDistance(v)); } }
private static void SetBoundingVolumeState(BoundingBox boundingVolume, GraphicsStateSet volumeState) { // Set transform state TransformState transformState = (TransformState)volumeState[TransformState.StateSetIndex]; if (transformState == null) { return; } Vertex3f min = boundingVolume.MinPosition, max = boundingVolume.MaxPosition; Vertex3f size = boundingVolume.Size; Vertex3f avg = (max + min) / 2.0f; // Scale model matrix in order to represent the bounding box with the correct size and barycenter transformState.ModelViewProjection = transformState.ModelViewProjection * Matrix4x4f.Translated(avg.x, avg.y, avg.z) * Matrix4x4f.Scaled(size.x, size.y, size.z); }
/// <summary> /// /// </summary> /// <param name="o"></param> /// <param name="w"></param> /// <param name="h"></param> /// <param name="d"></param> public BoundingBox(Vertex3f o, float w, float h, float d) { float w2 = w / 2.0f, h2 = h / 2.0f, d2 = d / 2.0f; if (w2 < Single.Epsilon) { w2 = 0.2f; } if (h2 < Single.Epsilon) { h2 = 0.2f; } if (d2 < Single.Epsilon) { d2 = 0.2f; } _Bounds[0] = new Vertex3f(o.x - w2, o.y - h2, o.z - d2); _Bounds[1] = new Vertex3f(o.x + w2, o.y + h2, o.z + d2); }
/// <summary> /// Set quaternion using rotation axis and rotation angle. /// </summary> /// <param name="rVector"> /// A <see cref="Vertex3f"/> representing the rotation axis. It will be normalized. /// </param> /// <param name="rAngle"> /// A <see cref="System.Single"/> representing the rotation angle (in degrees). /// </param> /// <remarks> /// This quaternion will result normalized. /// </remarks> public void SetEuler(Vertex3f rVector, float rAngle) { double qAngle = rAngle * Angle.DegreeToRadian / 2.0; double qAngleSin = Math.Sin(qAngle); mVector.x = qAngleSin * rVector.x; mVector.y = qAngleSin * rVector.y; mVector.z = qAngleSin * rVector.z; mCosAngle = Math.Cos(qAngle); // Ensure normalized quaternion Normalize(); }
/// <summary> /// Set uniform state variable (variant type variable). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="v"> /// A <see cref="Vertex3f"/> holding the uniform variabile data. /// </param> public void SetVariantUniform(GraphicsContext ctx, string uniformName, Vertex3f v) { SetVariantUniform(ctx, uniformName, v.x, v.y, v.z); }
/// <summary> /// Accumulate a scaling to this model matrix. /// </summary> /// <param name="s"> /// A <see cref="Vertex3f"/> holding the scaling factors on three dimensions. /// </param> public void Scale(Vertex3f s) { ModelMatrix scaleModel = new ModelMatrix(); scaleModel.SetScale(s); Set(this * scaleModel); }
/// <summary> /// Scale this ModelMatrix. /// </summary> /// <param name="s"> /// A <see cref="Vertex3f"/> holding the scaling factors on three dimensions. /// </param> public void SetScale(Vertex3f s) { SetScale(s.x, s.y, s.z); }
/// <summary> /// Accumulate a translation on this ModelMatrix. /// </summary> /// <param name="p"> /// A <see cref="Vertex3f"/> that specifies the translation. /// </param> public void Translate(Vertex3f p) { ModelMatrix translationMatrix = new ModelMatrix(); translationMatrix[3, 0] = p.x; translationMatrix[3, 1] = p.y; translationMatrix[3, 2] = p.z; Set(this * translationMatrix); }
/// <summary> /// Setup this matrix to view the universe in a certain direction. /// </summary> /// <param name="eyePosition"> /// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates. /// </param> /// <param name="forwardVector"> /// A <see cref="Vertex3f"/> that specify the direction of the view. It will be normalized. /// </param> /// <param name="upVector"> /// A <see cref="Vertex3f"/> that specify the up vector of the view camera abstraction. It will be normalized /// </param> /// <returns> /// It returns a view transformation matrix used to transform the world coordinate, in order to view /// the world from <paramref name="eyePosition"/>, looking at <paramref name="forwardVector"/> having /// an up direction equal to <paramref name="upVector"/>. /// </returns> public void LookAtDirection(Vertex3f eyePosition, Vertex3f forwardVector, Vertex3f upVector) { Vertex3f rightVector; // Normalize forward vector forwardVector.Normalize(); // Normalize up vector upVector.Normalize(); // Compute the right vector (cross-product between forward and up vectors; right is perperndicular to the plane) rightVector = forwardVector ^ upVector; rightVector.Normalize(); // Derive up vector upVector = rightVector ^ forwardVector; upVector.Normalize(); // Compute view matrix ModelMatrix lookatMatrix = new ModelMatrix(), positionMatrix = new ModelMatrix(); // Row 0: right vector lookatMatrix[0, 0] = rightVector.x; lookatMatrix[1, 0] = rightVector.y; lookatMatrix[2, 0] = rightVector.z; // Row 1: up vector lookatMatrix[0, 1] = upVector.x; lookatMatrix[1, 1] = upVector.y; lookatMatrix[2, 1] = upVector.z; // Row 2: opposite of forward vector lookatMatrix[0, 2] = forwardVector.x; lookatMatrix[1, 2] = forwardVector.y; lookatMatrix[2, 2] = forwardVector.z; // Eye position positionMatrix.Translate(-eyePosition); // Complete look-at matrix Set(lookatMatrix * positionMatrix); Set(GetInverseMatrix()); }
/// <summary> /// Compute a model-view matrix in order to simulate the gluLookAt mithical GLU routine. /// </summary> /// <param name="eyePosition"> /// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates. /// </param> /// <param name="targetPosition"> /// A <see cref="Vertex3f"/> that specify the eye target position, in local coordinates. /// </param> /// <param name="upVector"> /// A <see cref="Vertex3f"/> that specify the up vector of the view camera abstraction. /// </param> /// <returns> /// It returns a view transformation matrix used to transform the world coordinate, in order to view /// the world from <paramref name="eyePosition"/>, looking at <paramref name="targetPosition"/> having /// an up direction equal to <paramref name="upVector"/>. /// </returns> public void LookAtTarget(Vertex3f eyePosition, Vertex3f targetPosition, Vertex3f upVector) { LookAtDirection(eyePosition, eyePosition - targetPosition, upVector); }
/// <summary> /// Compute a model-view matrix in order to simulate the gluLookAt mithical GLU routine. /// </summary> /// <param name="eyePosition"> /// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates. /// </param> /// <param name="targetPosition"> /// A <see cref="Vertex3f"/> that specify the eye target position, in local coordinates. /// </param> /// <remarks> /// It returns a view transformation matrix used to transform the world coordinate, in order to view /// the world from <paramref name="eyePosition"/>, looking at <paramref name="targetPosition"/> having /// an up direction equal to the current up vector. /// </remarks> public void LookAtTarget(Vertex3f eyePosition, Vertex3f targetPosition) { LookAtTarget(eyePosition, targetPosition, Vertex3f.UnitY); }
/// <summary> /// Compute a model-view matrix in order to simulate the gluLookAt mithical GLU routine. /// </summary> /// <param name="targetPosition"> /// A <see cref="Vertex3f"/> that specify the eye target position, in local coordinates. /// </param> /// <remarks> /// It returns a view transformation matrix used to transform the world coordinate, in order to view /// the world from current position, looking at <paramref name="targetPosition"/> having /// an up direction equal to the current up vector. /// </remarks> public void LookAtTarget(Vertex3f targetPosition) { LookAtTarget(Position, targetPosition); }