Beispiel #1
0
        public override Matrix4x4d LocalToDeformedDifferential(Vector3d localPoint, bool clamp = false)
        {
            if (!Functions.IsFinite(localPoint.x) || !Functions.IsFinite(localPoint.y) || !Functions.IsFinite(localPoint.z))
            {
                return(Matrix4x4d.identity);
            }

            var point = new Vector2d(localPoint);

            if (clamp)
            {
                point.x = point.x - Math.Floor((point.x + R) / (2.0 * R)) * 2.0 * R;
                point.y = point.y - Math.Floor((point.y + R) / (2.0 * R)) * 2.0 * R;
            }

            var r2 = R * R;
            var l  = point.x * point.x + point.y * point.y + r2;
            var c0 = 1.0 / Math.Sqrt(l);
            var c1 = c0 * R / l;

            return(new Matrix4x4d((point.y * point.y + r2) * c1, -point.x * point.y * c1, point.x * c0, R * point.x * c0,
                                  -point.x * point.y * c1, (point.x * point.x + r2) * c1, point.y * c0, R * point.y * c0,
                                  -point.x * R * c1, -point.y * R * c1, R * c0, (r2) * c0, 0.0, 0.0, 0.0, 1.0));
        }
Beispiel #2
0
        public override void UpdateNode()
        {
            TerrainMaterial.renderQueue = (int)ParentBody.RenderQueue + ParentBody.RenderQueueOffset;

            // NOTE : Body shape dependent...
            LocalToWorld = Matrix4x4d.ToMatrix4x4d(ParentBody.transform.localToWorldMatrix) * FaceToLocal;

            TangentFrameToWorld = new Matrix3x3d(LocalToWorld.m[0, 0], LocalToWorld.m[0, 1], LocalToWorld.m[0, 2],
                                                 LocalToWorld.m[1, 0], LocalToWorld.m[1, 1], LocalToWorld.m[1, 2],
                                                 LocalToWorld.m[2, 0], LocalToWorld.m[2, 1], LocalToWorld.m[2, 2]);

            LocalToCamera = GodManager.Instance.View.WorldToCameraMatrix * LocalToWorld;
            LocalToScreen = GodManager.Instance.View.CameraToScreenMatrix * LocalToCamera;

            var invLocalToCamera = LocalToCamera.Inverse();

            DeformedCameraPosition = invLocalToCamera * Vector3d.zero;
            DeformedFrustumPlanes  = Frustum3d.GetFrustumPlanes(LocalToScreen); // NOTE : Extract frustum planes from LocalToScreen matrix...

            LocalCameraPosition = Deformation.DeformedToLocal(DeformedCameraPosition);

            DeformedLocalToTangent = Deformation.DeformedToTangentFrame(GodManager.Instance.View.WorldCameraPosition) * LocalToWorld * Deformation.LocalToDeformedDifferential(LocalCameraPosition);

            var m = Deformation.LocalToDeformedDifferential(LocalCameraPosition, true);

            var left  = DeformedFrustumPlanes[0].xyz.Normalized();
            var right = DeformedFrustumPlanes[1].xyz.Normalized();

            var fov = (float)Functions.Safe_Acos(-left.Dot(right));

            SplitDistance  = SplitFactor * Screen.width / 1024.0f * Mathf.Tan(40.0f * Mathf.Deg2Rad) / Mathf.Tan(fov / 2.0f);
            DistanceFactor = (float)Math.Max(new Vector3d(m.m[0, 0], m.m[1, 0], m.m[2, 0]).Magnitude(), new Vector3d(m.m[0, 1], m.m[1, 1], m.m[2, 1]).Magnitude());

            if (SplitDistance < 1.1f || SplitDistance > 128.0f || !Functions.IsFinite(SplitDistance))
            {
                SplitDistance = 1.1f;
            }

            var splitDistanceBlending = SplitDistance + 1.0f;

            DistanceBlending = new Vector2(splitDistanceBlending, 2.0f * SplitDistance - splitDistanceBlending);

            // Initializes data structures for horizon occlusion culling
            if (UseHorizonCulling && LocalCameraPosition.z <= TerrainQuadRoot.ZMax)
            {
                var deformedDirection = invLocalToCamera * Vector3d.forward;
                var localDirection    = (Deformation.DeformedToLocal(deformedDirection) - LocalCameraPosition).Normalized();

                LocalCameraDirection = new Matrix2x2d(localDirection.y, -localDirection.x, -localDirection.x, -localDirection.y);

                for (var i = 0; i < HORIZON_SIZE; ++i)
                {
                    Horizon[i] = float.NegativeInfinity;
                }
            }

            if (ParentBody.UpdateLOD)
            {
                TerrainQuadRoot.UpdateLOD();
            }

            SetUniforms(TerrainMaterial);
        }