Пример #1
0
 public Camera(float near = 0.1f, float far = 2000)
 {
     matrixWorldInverse = Matrix4.Identity;
     projectionMatrix = Matrix4.Identity;
     this.near = near;
     this.far = far;
 }
Пример #2
0
 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;
 }
Пример #3
0
 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];
 }
Пример #4
0
        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;
        }
Пример #5
0
        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;
        }
Пример #6
0
        //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;
        }
Пример #7
0
        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);

        }
Пример #8
0
        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();
	}
Пример #9
0
 public void Apply(Matrix4 matrix)
 {
     Center.Apply(matrix);
     Radius *= matrix.GetMaxScaleOnAxis();
 }
Пример #10
0
 public void Apply(Matrix4 m) 
 {
     matrix.MultiplyMatrices(m, matrix);
     matrix.Decompose(ref Position, ref quaternion, ref Scale);
 }
Пример #11
0
        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;
        }
Пример #12
0
 public void UpdateMatrix() 
 {
     matrix = Matrix4.Compose(Position, Quaternion, Scale );
     matrixWorldNeedsUpdate = true;
 }
Пример #13
0
        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;
        }
Пример #14
0
        //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;
        }
Пример #15
0
        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];
        }
Пример #16
0
 //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;
 }
Пример #17
0
 public Object3D()
 {
     matrixWorld = Matrix4.Identity;
 }
Пример #18
0
 public void Multiply(Matrix4 m)
 {
     MultiplyMatrices(this, m);
 }