/// <summary> /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. /// </summary> /// <param name="m">The m.</param> /// <param name="angle">The angle.</param> /// <param name="v">The v.</param> /// <returns></returns> public static mat4 rotate(mat4 m, float angle, vec3 v) { float c = cos(angle); float s = sin(angle); vec3 axis = v; axis.Normalize();// normalize(v); vec3 temp = (1.0f - c) * axis; mat4 rotate = mat4.identity(); rotate[0, 0] = c + temp[0] * axis[0]; rotate[0, 1] = 0 + temp[0] * axis[1] + s * axis[2]; rotate[0, 2] = 0 + temp[0] * axis[2] - s * axis[1]; rotate[1, 0] = 0 + temp[1] * axis[0] - s * axis[2]; rotate[1, 1] = c + temp[1] * axis[1]; rotate[1, 2] = 0 + temp[1] * axis[2] + s * axis[0]; rotate[2, 0] = 0 + temp[2] * axis[0] + s * axis[1]; rotate[2, 1] = 0 + temp[2] * axis[1] - s * axis[0]; rotate[2, 2] = c + temp[2] * axis[2]; mat4 result = mat4.identity(); result[0] = m[0] * rotate[0][0] + m[1] * rotate[0][1] + m[2] * rotate[0][2]; result[1] = m[0] * rotate[1][0] + m[1] * rotate[1][1] + m[2] * rotate[1][2]; result[2] = m[0] * rotate[2][0] + m[1] * rotate[2][1] + m[2] * rotate[2][2]; result[3] = m[3]; return(result); }
public void MouseMove(int x, int y) { if (this.mouseDownFlag) { IViewCamera camera = this.Camera; if (camera == null) { return; } vec3 back = this.back; vec3 right = this.right; vec3 up = this.up; Size bound = this.bound; Point downPosition = this.downPosition; { float deltaX = -horizontalRotationFactor * (x - downPosition.X) / bound.Width; float cos = (float)Math.Cos(deltaX); float sin = (float)Math.Sin(deltaX); vec3 newBack = new vec3( back.x * cos + right.x * sin, back.y * cos + right.y * sin, back.z * cos + right.z * sin); back = newBack; right = up.cross(back); back.Normalize(); right.Normalize(); } { float deltaY = verticalRotationFactor * (y - downPosition.Y) / bound.Height; float cos = (float)Math.Cos(deltaY); float sin = (float)Math.Sin(deltaY); vec3 newBack = new vec3( back.x * cos + up.x * sin, back.y * cos + up.y * sin, back.z * cos + up.z * sin); back = newBack; up = back.cross(right); back.Normalize(); up.Normalize(); } camera.Position = camera.Target + back * (float)((camera.Position - camera.Target).Magnitude()); camera.UpVector = up; this.back = back; this.right = right; this.up = up; this.downPosition.X = x; this.downPosition.Y = y; } }
/// <summary> /// Build a look at view matrix. /// </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 f = (center - eye); f.Normalize(); vec3 s = f.cross(up); s.Normalize(); vec3 u = s.cross(f); mat4 Result = new mat4(1); Result[0, 0] = s.x; Result[1, 0] = s.y; Result[2, 0] = s.z; Result[0, 1] = u.x; Result[1, 1] = u.y; Result[2, 1] = u.z; Result[0, 2] = -f.x; Result[1, 2] = -f.y; Result[2, 2] = -f.z; Result[3, 0] = -s.dot(eye); // dot(s, eye); Result[3, 1] = -u.dot(eye); // dot(u, eye); Result[3, 2] = f.dot(eye); // dot(f, eye); return(Result); }
private static void GenNormals(ObjModel model) { if (model.normalList.Count > 0) { return; } var faceNormals = new vec3[model.innerFaceList.Count]; model.normalList.AddRange(new vec3[model.positionList.Count]); for (int i = 0; i < model.innerFaceList.Count; i++) { var face = model.innerFaceList[i]; vec3 vertex0 = model.positionList[face.vertex0.position - 1]; vec3 vertex1 = model.positionList[face.vertex1.position - 1]; vec3 vertex2 = model.positionList[face.vertex2.position - 1]; vec3 v1 = vertex0 - vertex2; vec3 v2 = vertex2 - vertex1; faceNormals[i] = v1.cross(v2); } for (int i = 0; i < model.positionList.Count; i++) { vec3 sum = new vec3(); int shared = 0; for (int j = 0; j < model.innerFaceList.Count; j++) { var face = model.innerFaceList[j]; if (face.vertex0.position - 1 == i || face.vertex1.position - 1 == i || face.vertex2.position - 1 == i) { sum = sum + faceNormals[i]; shared++; } } if (shared > 0) { sum = sum / shared; sum.Normalize(); } model.normalList[i] = sum; } }
private static void GetBackAndUp(out vec3 target2Position, out vec3 upVector, ViewTypes viewType) { switch (viewType) { case ViewTypes.UserView: //UserView 定义为从顶视图开始,绕X 轴旋转30 度,在绕Z 轴45 度,并且能看到整个模型的虚拟模型空间。 target2Position = new vec3((float)Math.Sqrt(3), (float)Math.Sqrt(3), -1); target2Position.Normalize(); upVector = new vec3(0, 0, -1); break; case ViewTypes.Top: target2Position = new vec3(0, 0, -1); upVector = new vec3(0, -1, 0); break; case ViewTypes.Bottom: target2Position = new vec3(0, 0, 1); upVector = new vec3(0, -1, 0); break; case ViewTypes.Left: target2Position = new vec3(-1, 0, 0); upVector = new vec3(0, 0, -1); break; case ViewTypes.Right: target2Position = new vec3(1, 0, 0); upVector = new vec3(0, 0, -1); break; case ViewTypes.Front: target2Position = new vec3(0, 1, 0); upVector = new vec3(0, 0, -1); break; case ViewTypes.Back: target2Position = new vec3(0, -1, 0); upVector = new vec3(0, 0, -1); break; default: throw new NotImplementedException(string.Format("new value({0}) of EViewType is not implemented!", viewType)); //break; } }
private static void GenNormals(TeapotModel model) { var faceNormals = new vec3[model.faces.Count]; model.normals.AddRange(new vec3[model.positions.Count]); for (int i = 0; i < model.faces.Count; i++) { var face = model.faces[i]; vec3 vertex0 = model.positions[face.Item1 - 1]; vec3 vertex1 = model.positions[face.Item2 - 1]; vec3 vertex2 = model.positions[face.Item3 - 1]; vec3 v1 = vertex0 - vertex2; vec3 v2 = vertex2 - vertex1; faceNormals[i] = v1.cross(v2); } for (int i = 0; i < model.positions.Count; i++) { vec3 sum = new vec3(); int shared = 0; for (int j = 0; j < model.faces.Count; j++) { var face = model.faces[j]; if (face.Item1 - 1 == i || face.Item2 - 1 == i || face.Item3 - 1 == i) { sum = sum + faceNormals[i]; shared++; } } if (shared > 0) { sum = sum / shared; sum.Normalize(); } model.normals[i] = sum; } }