コード例 #1
0
        public void UpdateNode()
        {
            LocalToWorld = /*Matrix4x4d.ToMatrix4x4d(transform.localToWorldMatrix) * */ FaceToLocal;

            Matrix4x4d localToCamera    = View.WorldToCamera * LocalToWorld;
            Matrix4x4d localToScreen    = View.CameraToScreen * localToCamera;
            Matrix4x4d invLocalToCamera = localToCamera.Inverse;

            DeformedCameraPos = invLocalToCamera * (new Vector3d(0));

            Frustum3d.SetPlanes(DeformedFrustumPlanes, localToScreen);
            LocalCameraPos = Deform.DeformedToLocal(DeformedCameraPos);

            Matrix4x4d m = Deform.LocalToDeformedDifferential(LocalCameraPos, true);

            DistFactor = (float)Math.Max((new Vector3d(m[0, 0], m[1, 0], m[2, 0])).Magnitude, (new Vector3d(m[0, 1], m[1, 1], m[2, 1])).Magnitude);

            Vector3d left  = DeformedFrustumPlanes[0].xyz.Normalized;
            Vector3d right = DeformedFrustumPlanes[1].xyz.Normalized;

            float fov   = (float)MathUtility.Safe_Acos(-Vector3d.Dot(left, right));
            float width = (float)Screen.width;

            SplitDist = m_splitFactor * width / 1024.0f * Mathf.Tan(40.0f * Mathf.Deg2Rad) / Mathf.Tan(fov / 2.0f);

            if (SplitDist < 1.1f || !MathUtility.IsFinite(SplitDist))
            {
                SplitDist = 1.1f;
            }

            // initializes data structures for horizon occlusion culling
            if (HorizonCulling && LocalCameraPos.z <= Root.ZMax)
            {
                Vector3d deformedDir = invLocalToCamera * (new Vector3d(0, 0, 1));
                Vector2d localDir    = (Deform.DeformedToLocal(deformedDir) - LocalCameraPos).xy.Normalized;

                LocalCameraDir = new Matrix2x2d(localDir.y, -localDir.x, -localDir.x, -localDir.y);

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

            Root.Update();

            World.SkyNode.SetUniforms(m_terrainMaterial);
            World.SunNode.SetUniforms(m_terrainMaterial);
            World.SetUniforms(m_terrainMaterial);
            Deform.SetUniforms(this, m_terrainMaterial);

            if (World.OceanNode != null)
            {
                World.OceanNode.SetUniforms(m_terrainMaterial);
            }
            else
            {
                m_terrainMaterial.SetFloat("_Ocean_DrawBRDF", 0.0f);
            }
        }
コード例 #2
0
    public List <Model3d> CullByFrustum(Frustum3d frustum)
    {
        List <Model3d> result = new List <Model3d>();

        foreach (var iter in m_modleList)
        {
            iter.m_cullFlag = false;
        }

        if (m_octree == null)
        {
            foreach (var iter in m_modleList)
            {
                OBB3d bounds = iter.GetOBB();
                if (IntersectionTest3D.Frustum3dWithOBB3d(frustum, bounds))
                {
                    result.Add(iter);
                }
            }
        }
        else
        {
            List <OctreeNode> nodes = new List <OctreeNode>();
            nodes.Add(m_octree);

            while (nodes.Count > 0)
            {
                OctreeNode active = nodes[0];
                nodes.RemoveAt(0);

                if (active.m_children != null)
                {
                    // Has child nodes
                    for (int i = 0; i < 8; ++i)
                    {
                        AABB3d bounds = active.m_children[i].m_bounds;
                        if (IntersectionTest3D.Frustum3dWithAABB3d(frustum, bounds))
                        {
                            nodes.Add(active.m_children[i]);
                        }
                    }
                }
                else
                {
                    // Is leaf node
                    for (int i = 0; i < active.m_models.Count; ++i)
                    {
                        if (!active.m_models[i].m_cullFlag)
                        {
                            OBB3d bounds = active.m_models[i].GetOBB();
                            if (IntersectionTest3D.Frustum3dWithOBB3d(frustum, bounds))
                            {
                                active.m_models[i].m_cullFlag = true;
                                result.Add(active.m_models[i]);
                            }
                        }
                    }
                }
            }
        }

        return(result);
    }
コード例 #3
0
 /// <summary>
 /// Returns the visibility of a bounding box in local space, in a view
 /// frustum defined in deformed space.
 /// </summary>
 /// <param name="node">This is node is used to get the camera position
 /// in local and deformed space with TerrainNode::GetLocalCamera and
 /// TerrainNode::GetDeformedCamera, as well as the view frustum planes
 /// in deformed space with TerrainNode::GetDeformedFrustumPlanes. </param>
 /// <param name="localBox">a bounding box in local space.</param>
 /// <returns>the visibility of the bounding box in the view frustum.</returns>
 public virtual FRUSTUM_VISIBILTY GetVisibility(TerrainNode node, Box3d localBox)
 {
     // localBox = deformedBox, so we can compare the deformed frustum with it
     return(Frustum3d.GetVisibility(node.DeformedFrustumPlanes, localBox));
 }
コード例 #4
0
ファイル: TerrainNode.cs プロジェクト: zameran/SpaceW
        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);
        }