public Camera(float near = 0.1f, float far = 2000) { matrixWorldInverse = Matrix4.Identity; projectionMatrix = Matrix4.Identity; this.near = near; this.far = far; }
public static Vector3 UnprojectVector(Vector3 vector, Matrix4 projectionMatrix, Matrix4 matrixWorld) { var projectionMatrixInverse = Matrix4.GetInverse(projectionMatrix); viewProjectionMatrix.MultiplyMatrices(matrixWorld, projectionMatrixInverse); var v = vector; v.ApplyProjection(viewProjectionMatrix); return v; }
public void CopyPosition(Matrix4 m) { var te = this.elements; var me = m.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; }
public static Frustum FromMatrix(Matrix4 projectionScreen) { var me = projectionScreen.elements; float me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3]; float me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7]; float me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11]; float me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15]; var f = new Frustum( new Plane(me3 - me0, me7 - me4, me11 - me8, me15 - me12), new Plane(me3 + me0, me7 + me4, me11 + me8, me15 + me12), new Plane(me3 + me1, me7 + me5, me11 + me9, me15 + me13), new Plane(me3 - me1, me7 - me5, me11 - me9, me15 - me13), new Plane(me3 - me2, me7 - me6, me11 - me10, me15 - me14), new Plane(me3 + me2, me7 + me6, me11 + me10, me15 + me14)); foreach(var p in f.planes) p.Normalize(); return f; }
public static Matrix4 ExtractRotation(Matrix4 m) { var res = Matrix4.Identity; var te = res.elements; var me = m.elements; var scaleX = 1 / new Vector3(me[0], me[1], me[2]).Length(); var scaleY = 1 / new Vector3(me[4], me[5], me[6]).Length(); var scaleZ = 1 / new Vector3(me[8], me[9], me[10]).Length(); te[0] = me[0] * scaleX; te[1] = me[1] * scaleX; te[2] = me[2] * scaleX; te[4] = me[4] * scaleY; te[5] = me[5] * scaleY; te[6] = me[6] * scaleY; te[8] = me[8] * scaleZ; te[9] = me[9] * scaleZ; te[10] = me[10] * scaleZ; return res; }
//Set this matrix to the inverse of the passed matrix. public static Matrix3 GetInverse(Matrix4 matrix) { // ( based on http://code.google.com/p/webgl-mjs/ ) var me = matrix.elements; var res = Matrix3.Identity; var te = res.elements; te[0] = me[10] * me[5] - me[6] * me[9]; te[1] = -me[10] * me[1] + me[2] * me[9]; te[2] = me[6] * me[1] - me[2] * me[5]; te[3] = -me[10] * me[4] + me[6] * me[8]; te[4] = me[10] * me[0] - me[2] * me[8]; te[5] = -me[6] * me[0] + me[2] * me[4]; te[6] = me[9] * me[4] - me[5] * me[8]; te[7] = -me[9] * me[0] + me[1] * me[8]; te[8] = me[5] * me[0] - me[1] * me[4]; var det = me[0] * te[0] + me[1] * te[3] + me[2] * te[6]; if (det == 0) throw new InvalidOperationException("Can't invert matrix, determinant is 0"); res.Multiply(1 / det); return res; }
private void Update(Scene scene, Camera camera) { // set GL state for depth map GL.ClearColor(1, 1, 1, 1); GL.Disable(EnableCap.Blend); GL.Enable(EnableCap.CullFace); GL.FrontFace(FrontFaceDirection.Ccw); GL.CullFace(renderer.shadowMapCullFace); renderer.DepthTest = true; var lights = new List<Light>(); // preprocess lights // - skip lights that are not casting shadows // - create virtual lights for cascaded shadow maps foreach (var light in scene.lights) { if (!light.DoesCastShadow) continue; var shadowLight = light as HasShadow; if (shadowLight != null && shadowLight.ShadowCascade) { for (var n = 0; n < shadowLight.ShadowCascadeCount; n++) { VirtualLight virtualLight; if (shadowLight.ShadowCascadeArray[n] == null) { virtualLight = CreateVirtualLight(light, n); virtualLight.OriginalCamera = camera; var gyro = new Gyroscope(); gyro.Position = shadowLight.ShadowCascadeOffset; gyro.Add(virtualLight); //gyro.Add(virtualLight.Target); camera.Add(gyro); shadowLight.ShadowCascadeArray[n] = virtualLight; Debug.WriteLine("Created virtualLight {0}", virtualLight); } else { virtualLight = shadowLight.ShadowCascadeArray[n]; } UpdateVirtualLight(light, n); lights.Add(virtualLight); } } else { lights.Add(light); } } // render depth map foreach (var light in lights) { var hasShadow = light as HasShadow; if (hasShadow.shadowMap == null) { var isSoftShadow = renderer.shadowMapType == ShadowType.PCFSoftShadowMap; hasShadow.shadowMap = new RenderTarget(hasShadow.ShadowMapWidth, hasShadow.ShadowMapHeight); hasShadow.shadowMap.MinFilter = isSoftShadow ? TextureMinFilter.Nearest : TextureMinFilter.Linear; hasShadow.shadowMap.MagFilter = isSoftShadow ? TextureMagFilter.Nearest : TextureMagFilter.Linear; ; hasShadow.shadowMap.Format = Three.Net.Renderers.PixelFormat.RGBA; hasShadow.ShadowMapSize = new Vector2(hasShadow.ShadowMapWidth, hasShadow.ShadowMapHeight); hasShadow.ShadowMatrix = Matrix4.Identity; } if (hasShadow.ShadowCamera == null) { if (hasShadow is SpotLight) hasShadow.ShadowCamera = new PerspectiveCamera(renderer, hasShadow.ShadowCameraFov, hasShadow.ShadowCameraNear, hasShadow.ShadowCameraFar); else if (hasShadow is DirectionalLight) hasShadow.ShadowCamera = new OrthographicCamera(hasShadow.ShadowCameraLeft, hasShadow.ShadowCameraRight, hasShadow.ShadowCameraTop, hasShadow.ShadowCameraBottom, hasShadow.ShadowCameraNear, hasShadow.ShadowCameraFar); else throw new Exception("Unsupported light type for shadow"); scene.Add(hasShadow.ShadowCamera); if (scene.AutoUpdate) scene.UpdateMatrixWorld(); } if (hasShadow.ShadowCameraVisible /* && light.CameraHelper == null*/) { throw new NotImplementedException(); //light.CameraHelper = new CameraHelper( hasShadow.ShadowCamera ); //hasShadow.ShadowCamera.Add( light.CameraHelper ); } var virtualLight = light as VirtualLight; if (virtualLight != null && virtualLight.OriginalCamera == camera) { UpdateShadowCamera(camera, light); } var shadowMap = hasShadow.shadowMap; var shadowMatrix = hasShadow.ShadowMatrix; var shadowCamera = hasShadow.ShadowCamera; shadowCamera.Position = Vector3.FromPosition(light.matrixWorld); matrixPosition = (light as HasTarget).Target; shadowCamera.LookAt(matrixPosition); shadowCamera.UpdateMatrixWorld(); shadowCamera.matrixWorldInverse = Matrix4.GetInverse(shadowCamera.matrixWorld); //TODO : Creating helpers if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible; //if (hasShadow.ShadowCameraVisible) light.cameraHelper.update(); // compute shadow matrix shadowMatrix = new Matrix4(0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f); shadowMatrix.Multiply(shadowCamera.projectionMatrix); shadowMatrix.Multiply(shadowCamera.matrixWorldInverse); // update camera matrices and frustum projectionScreenMatrix.MultiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); frustum = Frustum.FromMatrix(projectionScreenMatrix); // render shadow map renderer.SetRenderTarget(shadowMap); renderer.Clear(); // set object matrices & frustum culling renderList.Clear(); ProjectObject(scene, scene, shadowCamera); // render regular objects foreach (var glObject in renderList) { var o = glObject.Object; var buffer = glObject.Buffer; throw new NotImplementedException(); } } // restore GL state var clearColor = renderer.ClearColor; GL.ClearColor(clearColor.R, clearColor.G, clearColor.B, 1); GL.Enable(EnableCap.Blend); if (renderer.shadowMapCullFace == CullFaceMode.Front) GL.CullFace(CullFaceMode.Back); }
public void Apply(Matrix4 matrix ) { var normalMatrix = Matrix3.GetNormalMatrix( matrix ); for(var i = 0; i < vertices.Count; i++) { var vertex = vertices[ i ]; vertex.Apply( matrix ); vertices[i] = vertex; } for ( var i = 0; i < faces.Count; i ++ ) { var face = faces[ i ]; var a = face.NormalA; a.Apply(normalMatrix); a.Normalize(); face.NormalA = a; var b = face.NormalB; b.Apply(normalMatrix); b.Normalize(); face.NormalB = b; var c = face.NormalC; c.Apply(normalMatrix); c.Normalize(); face.NormalC = c; } ComputeBoundingBox(); ComputeBoundingSphere(); }
public void Apply(Matrix4 matrix) { Center.Apply(matrix); Radius *= matrix.GetMaxScaleOnAxis(); }
public void Apply(Matrix4 m) { matrix.MultiplyMatrices(m, matrix); matrix.Decompose(ref Position, ref quaternion, ref Scale); }
public void MultiplyMatrices(Matrix4 a, Matrix4 b) { if (elements == null) elements = new float[16]; var ae = a.elements; var be = b.elements; float a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12]; float a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13]; float a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14]; float a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15]; float b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12]; float b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13]; float b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14]; float b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15]; elements[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; elements[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; elements[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; elements[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; elements[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; elements[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; elements[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; elements[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; elements[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; elements[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; elements[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; elements[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; elements[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; elements[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; elements[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; elements[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; }
public void UpdateMatrix() { matrix = Matrix4.Compose(Position, Quaternion, Scale ); matrixWorldNeedsUpdate = true; }
public void Decompose(ref Vector3 position, ref Quaternion quaternion, ref Vector3 scale) { var te = this.elements; var sx = new Vector3(te[0], te[1], te[2]).Length(); var sy = new Vector3(te[4], te[5], te[6]).Length(); var sz = new Vector3(te[8], te[9], te[10]).Length(); // if determine is negative, we need to invert one scale var det = Determinant(); if (det < 0) sx = -sx; position.x = te[12]; position.y = te[13]; position.z = te[14]; // scale the rotation part var matrix = new Matrix4(elements); var invSX = 1 / sx; var invSY = 1 / sy; var invSZ = 1 / sz; matrix.elements[0] *= invSX; matrix.elements[1] *= invSX; matrix.elements[2] *= invSX; matrix.elements[4] *= invSY; matrix.elements[5] *= invSY; matrix.elements[6] *= invSY; matrix.elements[8] *= invSZ; matrix.elements[9] *= invSZ; matrix.elements[10] *= invSZ; quaternion = Quaternion.FromRotation(matrix); scale.x = sx; scale.y = sy; scale.z = sz; }
//Sets this matrix to the inverse of matrix m. public static Matrix4 GetInverse(Matrix4 m) { // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm var res = Matrix4.Identity; var te = res.elements; var me = m.elements; float n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12]; float n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13]; float n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14]; float n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15]; te[0] = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; te[4] = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; te[8] = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; te[12] = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; te[1] = n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44; te[5] = n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44; te[9] = n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44; te[13] = n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34; te[2] = n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44; te[6] = n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44; te[10] = n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44; te[14] = n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34; te[3] = n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43; te[7] = n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43; te[11] = n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43; te[15] = n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33; var det = n11 * te[0] + n21 * te[4] + n31 * te[8] + n41 * te[12]; if (det == 0) throw new InvalidOperationException("Can't invert matrix, determinant is 0"); res.Multiply(1 / det); return res; }
public void MultiplyToArray(Matrix4 a, Matrix4 b, ref float[] r) { var te = this.elements; MultiplyMatrices(a, b); r[0] = te[0]; r[1] = te[1]; r[2] = te[2]; r[3] = te[3]; r[4] = te[4]; r[5] = te[5]; r[6] = te[6]; r[7] = te[7]; r[8] = te[8]; r[9] = te[9]; r[10] = te[10]; r[11] = te[11]; r[12] = te[12]; r[13] = te[13]; r[14] = te[14]; r[15] = te[15]; }
//Set this matrix as the normal matrix of the passed matrix4. The normal matrix is the inverse transpose of the matrix. public static Matrix3 GetNormalMatrix(Matrix4 m) { var res = Matrix3.GetInverse(m); res.Transpose(); return res; }
public Object3D() { matrixWorld = Matrix4.Identity; }
public void Multiply(Matrix4 m) { MultiplyMatrices(this, m); }