/// <summary> /// Build a look at view matrix. /// transform object's coordinate from world's space to camera's space. /// </summary> /// <param name="eye">The eye.</param> /// <param name="center">The center.</param> /// <param name="up">Up.</param> /// <returns></returns> public static mat4 lookAt(vec3 eye, vec3 center, vec3 up) { // camera's back in world space coordinate system vec3 back = (eye - center).normalize(); // camera's right in world space coordinate system vec3 right = up.cross(back).normalize(); // camera's up in world space coordinate system vec3 standardUp = back.cross(right); mat4 viewMat = new mat4(1); viewMat.col0.x = right.x; viewMat.col1.x = right.y; viewMat.col2.x = right.z; viewMat.col0.y = standardUp.x; viewMat.col1.y = standardUp.y; viewMat.col2.y = standardUp.z; viewMat.col0.z = back.x; viewMat.col1.z = back.y; viewMat.col2.z = back.z; // Translation in world space coordinate system viewMat.col3.x = -eye.dot(right); viewMat.col3.y = -eye.dot(standardUp); viewMat.col3.z = -eye.dot(back); return(viewMat); }
void IMouseHandler.canvas_MouseMove(object sender, MouseEventArgs e) { if (mouseDownFlag && ((e.Button & this.lastBindingMouseButtons) != MouseButtons.None)) { if (!cameraState.IsSameState(this.camera)) { SetCamera(this.camera.Position, this.camera.Target, this.camera.UpVector); } this._endPosition = GetArcBallPosition(e.X, e.Y); var cosAngle = _startPosition.dot(_endPosition) / (_startPosition.length() * _endPosition.length()); if (cosAngle > 1.0f) { cosAngle = 1.0f; } else if (cosAngle < -1) { cosAngle = -1.0f; } var angle = MouseSensitivity * (float)(Math.Acos(cosAngle) / Math.PI * 180); _normalVector = _startPosition.cross(_endPosition).normalize(); if (! ((_normalVector.x == 0 && _normalVector.y == 0 && _normalVector.z == 0) || float.IsNaN(_normalVector.x) || float.IsNaN(_normalVector.y) || float.IsNaN(_normalVector.z))) { _startPosition = _endPosition; mat4 newRotation = glm.rotate(angle, _normalVector); this.totalRotation = newRotation * totalRotation; } } }
/// <summary> /// Build a look at view matrix. /// transform object's coordinate from world's space to camera's space. /// </summary> /// <param name="eye">The eye.</param> /// <param name="center">The center.</param> /// <param name="up">Up.</param> /// <returns></returns> public static mat4 lookAt(vec3 eye, vec3 center, vec3 up) { vec3 forward = (center - eye).normalize(); vec3 right = forward.cross(up).normalize(); vec3 standardUp = right.cross(forward); mat4 Result = new mat4(1); // Left (X) Axis Result[0, 0] = right.x; Result[0, 1] = standardUp.x; Result[0, 2] = -forward.x; // Up (Y) Axis Result[1, 0] = right.y; Result[1, 1] = standardUp.y; Result[1, 2] = -forward.y; // Forward (Z) Axis Result[2, 0] = right.z; Result[2, 1] = standardUp.z; Result[2, 2] = -forward.z; // Translation Result[3, 0] = -right.dot(eye); // dot(s, eye); Result[3, 1] = -standardUp.dot(eye); // dot(u, eye); Result[3, 2] = forward.dot(eye); // dot(f, eye); return(Result); }
public void MouseMove(int x, int y) { if (MouseDownFlag) { Debug.WriteLine(" =================>MouseMove:", listenerName); if (!cameraState.IsSameState(this.Camera)) { SetCamera(this.Camera.Position, this.Camera.Target, this.Camera.UpVector); Debug.WriteLine(string.Format( " update camera state: {0}, {1}, {2}", this.cameraState.position, this.cameraState.target, this.cameraState.up), listenerName); } this._endPosition = GetArcBallPosition(x, y); Debug.WriteLine(string.Format( " End position: {0}", this._endPosition), listenerName); var cosAngle = _startPosition.dot(_endPosition) / (_startPosition.Magnitude() * _endPosition.Magnitude()); if (cosAngle > 1) { cosAngle = 1; } else if (cosAngle < -1) { cosAngle = -1; } Debug.Write(string.Format(" cos angle: {0}", cosAngle), listenerName); var angle = mouseSensitivity * (float)(Math.Acos(cosAngle) / Math.PI * 180); Debug.WriteLine(string.Format( ", angle: {0}", angle), listenerName); _normalVector = _startPosition.cross(_endPosition).normalize(); if ((_normalVector.x == 0 && _normalVector.y == 0 && _normalVector.z == 0) || float.IsNaN(_normalVector.x) || float.IsNaN(_normalVector.y) || float.IsNaN(_normalVector.z)) { Debug.WriteLine(" no movement recorded.", listenerName); } else { Debug.WriteLine(string.Format( " normal vector: {0}", _normalVector), listenerName); _startPosition = _endPosition; mat4 newRotation = glm.rotate(angle, _normalVector); Debug.WriteLine(string.Format( " new rotation matrix: {0}", newRotation), listenerName); this.totalRotation = newRotation * totalRotation; Debug.WriteLine(string.Format( " total rotation matrix: {0}", totalRotation), listenerName); } Debug.WriteLine(" -------------------MouseMove end.", listenerName); } }
// https://www.cnblogs.com/bitzhuwei/p/opengl-Computing-Tangent-Space-Basis-Vectors.html public override void Parse(ObjVNFContext context) { ObjVNFMesh mesh = context.Mesh; vec3[] vertexes = mesh.vertexes;// positions vec2[] texCoords = mesh.texCoords; vec3[] normals = mesh.normals; if (vertexes == null || texCoords == null || normals == null) { return; } if (vertexes.Length != texCoords.Length || vertexes.Length != normals.Length) { return; } ObjVNFFace[] faces = mesh.faces; if (faces == null || faces.Length == 0) { return; } // if (not triangles) { return; } if (faces[0].VertexIndexes().Count() != 3) { return; } var tangents = new vec3[normals.Length]; var biTangents = new vec3[normals.Length]; for (int i = 0; i < faces.Length; i++) { var face = faces[i] as ObjVNFTriangle; if (face == null) { return; } // no dealing with quad. uint[] vertexIndexes = face.VertexIndexes(); uint i0 = vertexIndexes[0]; uint i1 = vertexIndexes[1]; uint i2 = vertexIndexes[2]; vec3 p0 = vertexes[i0]; vec3 p1 = vertexes[i1]; vec3 p2 = vertexes[i2]; vec2 uv0 = texCoords[i0]; vec2 uv1 = texCoords[i1]; vec2 uv2 = texCoords[i2]; float x1 = p1.x - p0.x; float y1 = p1.y - p0.y; float z1 = p1.z - p0.z; float x2 = p2.x - p0.x; float y2 = p2.y - p0.y; float z2 = p2.z - p0.z; float s1 = uv1.x - uv0.x; float t1 = uv1.y - uv0.y; float s2 = uv2.x - uv0.x; float t2 = uv2.y - uv0.y; float r = 1.0F / (s1 * t2 - s2 * t1); var sdir = new vec3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); var tdir = new vec3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); //tangents[i0] += sdir; tangents[i0] = (float)i / (float)(i + 1) * tangents[i0] + sdir / (float)(i + 1); //tangents[i1] += sdir; tangents[i1] = (float)i / (float)(i + 1) * tangents[i1] + sdir / (float)(i + 1); //tangents[i2] += sdir; tangents[i2] = (float)i / (float)(i + 1) * tangents[i2] + sdir / (float)(i + 1); //biTangents[i0] += tdir; biTangents[i0] = (float)i / (float)(i + 1) * biTangents[i0] + sdir / (float)(i + 1); //biTangents[i1] += tdir; biTangents[i1] = (float)i / (float)(i + 1) * biTangents[i1] + sdir / (float)(i + 1); //biTangents[i2] += tdir; biTangents[i2] = (float)i / (float)(i + 1) * biTangents[i2] + sdir / (float)(i + 1); } var finalTangents = new vec4[normals.Length]; for (long a = 0; a < normals.Length; a++) { vec3 n = normals[a]; vec3 t = tangents[a]; // Calculate handedness float w = (n.cross(t).dot(biTangents[a]) < 0.0F) ? -1.0F : 1.0F; // Gram-Schmidt orthogonalize finalTangents[a] = new vec4((t - n * n.dot(t)).normalize(), w); } mesh.tangents = finalTangents; }