예제 #1
0
        protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, Material target)
        {
            base.SetScreenUniforms(node, quad, target);

            target.SetVector(uniforms.screenQuadCornerNorms, quad.Lengths.ToVector4());
            target.SetMatrix(uniforms.tangentFrameToWorld, quad.TangentFrameToWorld.ToMatrix4x4());
        }
예제 #2
0
 public virtual Matrix4x4 CalculateDeformedLocalToTangent(TerrainNode node, TerrainQuad quad)
 {
     return((node.DeformedLocalToTangent * new Matrix4x4d(quad.Length, 0.0, quad.Ox - node.LocalCameraPosition.x, 0.0,
                                                          0.0, quad.Length, quad.Oy - node.LocalCameraPosition.y, 0.0,
                                                          0.0, 0.0, 1.0, 0.0,
                                                          0.0, 0.0, 0.0, 1.0)).ToMatrix4x4());
 }
예제 #3
0
        /*
         * Sets the shader uniforms that are necessary to project on screen the
         * TerrainQuad of the given TerrainNode. This method can set the uniforms
         * that are common to all the quads of the given terrain.
         */
        public virtual void SetUniforms(TerrainNode node, Material mat)
        {
            if (mat == null || node == null)
            {
                return;
            }

            float d1 = node.GetSplitDist() + 1.0f;
            float d2 = 2.0f * node.GetSplitDist();

            mat.SetVector(m_uniforms.blending, new Vector2(d1, d2 - d1));

            m_localToCamera = node.GetView().GetWorldToCamera() * node.GetLocalToWorld();
            m_localToScreen = node.GetView().GetCameraToScreen() * m_localToCamera;

            Vector3d2 localCameraPos = node.GetLocalCameraPos();
            Vector3d2 worldCamera    = node.GetView().GetWorldCameraPos();

            Matrix4x4d A = LocalToDeformedDifferential(localCameraPos);
            Matrix4x4d B = DeformedToTangentFrame(worldCamera);

            Matrix4x4d ltot = B * node.GetLocalToWorld() * A;

            m_localToTangent = new Matrix3x3d(ltot.m[0, 0], ltot.m[0, 1], ltot.m[0, 3],
                                              ltot.m[1, 0], ltot.m[1, 1], ltot.m[1, 3],
                                              ltot.m[3, 0], ltot.m[3, 1], ltot.m[3, 3]);

            mat.SetMatrix(m_uniforms.localToScreen, m_localToScreen.ToMatrix4x4());
            mat.SetMatrix(m_uniforms.localToWorld, node.GetLocalToWorld().ToMatrix4x4());
        }
예제 #4
0
 public virtual Vector4 CalculateDeformedCameraPosition(TerrainNode node, TerrainQuad quad)
 {
     return(new Vector4((float)((node.LocalCameraPosition.x - quad.Ox) / quad.Length),
                        (float)((node.LocalCameraPosition.y - quad.Oy) / quad.Length),
                        (float)((node.LocalCameraPosition.z - node.ParentBody.HeightZ) / (quad.Length * (double)node.DistanceFactor)),
                        (float)node.LocalCameraPosition.z));
 }
예제 #5
0
        /*
         * Sets the shader uniforms that are necessary to project on screen the
         * given TerrainQuad. This method can set the uniforms that are specific to
         * the given quad.
         */
        public virtual void SetUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            if (matPropertyBlock == null || node == null || quad == null)
            {
                return;
            }

            double ox         = quad.GetOX();
            double oy         = quad.GetOY();
            double l          = quad.GetLength();
            double distFactor = (double)node.GetDistFactor();
            int    level      = quad.GetLevel();

            matPropertyBlock.AddVector(m_uniforms.offset, new Vector4((float)ox, (float)oy, (float)l, (float)level));

            Vector3d2 camera = node.GetLocalCameraPos();

            matPropertyBlock.AddVector(m_uniforms.camera, new Vector4((float)((camera.x - ox) / l), (float)((camera.y - oy) / l),
                                                                      (float)((camera.z - node.GetView().GetGroundHeight()) / (l * distFactor)),
                                                                      (float)camera.z));

            Vector3d2 c = node.GetLocalCameraPos();

            Matrix3x3d m = m_localToTangent * (new Matrix3x3d(l, 0.0, ox - c.x, 0.0, l, oy - c.y, 0.0, 0.0, 1.0));

            matPropertyBlock.AddMatrix(m_uniforms.tileToTangent, m.ToMatrix4x4());

            SetScreenUniforms(node, quad, matPropertyBlock);
        }
예제 #6
0
        protected virtual void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l  = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, 0.0);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, 0.0);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, 0.0);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, 0.0);

            Matrix4x4d corners = new Matrix4x4d(p0.x, p1.x, p2.x, p3.x,
                                                p0.y, p1.y, p2.y, p3.y,
                                                p0.z, p1.z, p2.z, p3.z,
                                                1.0, 1.0, 1.0, 1.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * corners).ToMatrix4x4());

            Matrix4x4d verticals = new Matrix4x4d(0.0, 0.0, 0.0, 0.0,
                                                  0.0, 0.0, 0.0, 0.0,
                                                  1.0, 1.0, 1.0, 1.0,
                                                  0.0, 0.0, 0.0, 0.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * verticals).ToMatrix4x4());
        }
예제 #7
0
 protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
 {
     matPropertyBlock.SetMatrix(uniforms.screenQuadCorners, (localToScreen * quad.DeformedCorners).ToMatrix4x4());
     matPropertyBlock.SetMatrix(uniforms.screenQuadVerticals, (localToScreen * quad.DeformedVerticals).ToMatrix4x4());
     matPropertyBlock.SetVector(uniforms.screenQuadCornerNorms, quad.Lengths.ToVector4());
     matPropertyBlock.SetMatrix(uniforms.tangentFrameToWorld, quad.TangentFrameToWorld.ToMatrix4x4());
 }
        public Tuple <string, TerrainNode> BuildTerrainNodePacket(string name, double x, double y, double z, int scale, bool smoothnormals)
        {
            TerrainNode obj = new TerrainNode()
            {
                id   = "scene/node/add",
                data = new Data3()
                {
                    name       = name,
                    components = new Components2()
                    {
                        transform = new Transform()
                        {
                            position = new double[] { x, y, x },
                            scale    = scale,
                            rotation = new double[] { 0, 0, 0, }
                        },
                        terrain = new ClientGUI.Sub_Objects.Terrain()
                        {
                            smoothnormals = smoothnormals
                        }
                    }
                }
            };
            string json = JsonConvert.SerializeObject(obj);

            return(new Tuple <string, TerrainNode>(json, obj));
        }
예제 #9
0
 /*
  * public AdjacentNode (TerrainNode _adjacent_node) {
  *      adjacent_node = _adjacent_node;
  *      position = adjacent_node.node.transform.position;
  *      distance = 0.0f;
  * }*/
 public AdjacentNode(TerrainNode _terrain_node, float _distance)
 {
     terrain_node = _terrain_node;
     position     = terrain_node.position;
     transform    = terrain_node.transform;
     distance     = _distance;
 }
        // Returns true when pathing is complete
        public void IteratePath()
        {
            if (frontier.Count <= 0)
            {
                Debug.Log("Frontier is empty");
                complete = true;
                return;
            }

            MoveCostNode curr = frontier[0];

            frontier.RemoveAt(0);
            if (curr.node == to)
            {
                Debug.Log($"Found: {curr.node.name}");

                TerrainNode currNode = curr.node;
                finalPath.Add(currNode);
                while (currNode != from)
                {
                    currNode = currPath[currNode.GetInstanceID()].node;
                    finalPath.Add(currNode);
                }
                finalPath.Reverse();

                complete = true;
                return;
            }

            for (int i = 0; i < curr.node.paths.Count; i++)
            {
                TerrainNode path = curr.node.paths[i];
                if (path == null || path.type == TerrainType.Blocked)
                {
                    continue;
                }

                float newCost = curr.totalMoveCost + path.moveCost;

                // Current paths either don't have the path node, or they do but the new move cost is better than existing move cost
                if (visited.Contains(path))
                {
                    continue;
                }
                if (currPath.ContainsKey(path.GetInstanceID()) && newCost >= currPath[path.GetInstanceID()].totalMoveCost)
                {
                    continue;
                }

                currPath.Remove(path.GetInstanceID());

                currPath.Add(path.GetInstanceID(), new MoveCostNode(curr.node, newCost));
                visited.Add(path);

                frontier.Add(new MoveCostNode(path, newCost));
                frontier.Sort((a, b) => a.totalMoveCost.CompareTo(b.totalMoveCost));
            }
        }
예제 #11
0
    public TerrainNode[] FindPath(Vector3 start_position, Transform target_transform)
    {
        TerrainNode start_node  = terrain_nodes_list.FindClosestTerrainNodeToPoint(start_position);
        TerrainNode target_node = terrain_nodes_list.FindTerrainNodeFromTransform(target_transform);
        //print (target_node.transform.name);
        AdjacentNode          closest_node_to_target = new AdjacentNode(start_node, Vector3.Distance(start_node.position, target_node.position));
        Heap <TerrainNode>    open_set   = new Heap <TerrainNode>(terrain_size);
        HashSet <TerrainNode> closed_set = new HashSet <TerrainNode>();

        open_set.Add(start_node);

        //start_node.transform.gameObject.GetComponent<Renderer>().material = mat_start;
        //target_node.transform.gameObject.GetComponent<Renderer>().material = mat_target;

        // A* pathfinding algorithm
        while (open_set.Count > 0)
        {
            TerrainNode current_node = open_set.RemoveFirst();
            closed_set.Add(current_node);

            //current_node.transform.gameObject.GetComponent<Renderer>().material = mat_path;
            if (current_node == target_node)
            {
                return(RetracePath(start_node, target_node));
            }
            foreach (AdjacentNode adj_neighbour in current_node.GetAdjecentNodesArray())
            {
                TerrainNode neighbour = adj_neighbour.terrain_node;
                if (closed_set.Contains(neighbour))
                {
                    continue;
                }
                float new_movement_cost_to_new_neighbour = current_node.g_cost + adj_neighbour.distance;
                if (new_movement_cost_to_new_neighbour < neighbour.g_cost || !open_set.Contains(neighbour))
                {
                    neighbour.g_cost = new_movement_cost_to_new_neighbour;
                    neighbour.h_cost = Vector3.Distance(neighbour.position, target_node.position);
                    neighbour.parent = current_node;

                    if (!open_set.Contains(neighbour))
                    {
                        open_set.Add(neighbour);
                    }
                    else
                    {
                        open_set.UpdateItem(neighbour);
                    }
                    if (neighbour.h_cost < closest_node_to_target.distance)
                    {
                        closest_node_to_target = new AdjacentNode(neighbour, neighbour.h_cost);
                    }
                }
            }
        }
        // no path found, return the closest node to target
        return(FindPath(start_position, closest_node_to_target.transform));
    }
예제 #12
0
 // Constructor if given a list of transforms
 public TerrainNodeList(List <Transform> transform_node_list, float _max_distance)
 {
     max_distance = _max_distance;
     foreach (Transform transform_node in transform_node_list)
     {
         terrain_node_list.Add(new TerrainNode(transform_node));
     }
     TerrainNode.SortAdjacentNodes(terrain_node_list, max_distance);
 }
예제 #13
0
        public override void Start()
        {
            base.Start();

            m_producer    = GetComponent <TileProducer>();
            m_terrainNode = m_terrainNodeGO.GetComponent <TerrainNode>();
            m_uniforms    = new Uniforms(m_producer.GetName());
            m_tileFilters = GetComponents <TileFilter>();
        }
예제 #14
0
        protected virtual void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            var p0 = new Vector3d(quad.Ox, quad.Oy, 0.0);
            var p1 = new Vector3d(quad.Ox + quad.Length, quad.Oy, 0.0);
            var p2 = new Vector3d(quad.Ox, quad.Oy + quad.Length, 0.0);
            var p3 = new Vector3d(quad.Ox + quad.Length, quad.Oy + quad.Length, 0.0);

            matPropertyBlock.SetMatrix(uniforms.screenQuadCorners, (localToScreen * new Matrix4x4d(p0.x, p1.x, p2.x, p3.x, p0.y, p1.y, p2.y, p3.y, p0.z, p1.z, p2.z, p3.z, 1.0, 1.0, 1.0, 1.0)).ToMatrix4x4());
            matPropertyBlock.SetMatrix(uniforms.screenQuadVerticals, (localToScreen * new Matrix4x4d(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0)).ToMatrix4x4());
        }
예제 #15
0
    private int heuristic_cost_estimate(TerrainNode node1, TerrainNode node2)
    {
        int x0 = node1.getX();
        int z0 = node1.getZ();

        int x1 = node2.getX();
        int z1 = node2.getX();

        return((int)Mathf.Abs(Mathf.Sqrt((x1 - x0) * (x1 - x0) + (z1 - z0) * (z1 - z0))));
    }
예제 #16
0
    public void AddTerrainNode(Transform node)
    {
        TerrainNode terrain_node = new TerrainNode(node);

        terrain_node_list.Add(terrain_node);
        // TODO: Instead of reanalyzing the entire list,
        // there could be a method in TerrainNode (Heap-like structure)
        // that would update only the nodes that need to be updated.
        TerrainNode.SortAdjacentNodes(terrain_node_list, max_distance);
    }
예제 #17
0
        public override Frustum.VISIBILITY GetVisibility(TerrainNode node, Box3d localBox)
        {
            var deformedBox = new Vector3d[4];

            deformedBox[0] = LocalToDeformed(new Vector3d(localBox.xmin, localBox.ymin, localBox.zmax));
            deformedBox[1] = LocalToDeformed(new Vector3d(localBox.xmax, localBox.ymin, localBox.zmax));
            deformedBox[2] = LocalToDeformed(new Vector3d(localBox.xmax, localBox.ymax, localBox.zmax));
            deformedBox[3] = LocalToDeformed(new Vector3d(localBox.xmin, localBox.ymax, localBox.zmax));

            var f = (float)((R - localBox.zmin) / ((R - localBox.zmax) * Math.Cos((localBox.ymax - localBox.ymin) / (2.0 * R))));

            var v0 = GetClipVisibility(node.DeformedFrustumPlanes[0], deformedBox, f);

            if (v0 == Frustum.VISIBILITY.INVISIBLE)
            {
                return(Frustum.VISIBILITY.INVISIBLE);
            }

            var v1 = GetClipVisibility(node.DeformedFrustumPlanes[1], deformedBox, f);

            if (v1 == Frustum.VISIBILITY.INVISIBLE)
            {
                return(Frustum.VISIBILITY.INVISIBLE);
            }

            var v2 = GetClipVisibility(node.DeformedFrustumPlanes[2], deformedBox, f);

            if (v2 == Frustum.VISIBILITY.INVISIBLE)
            {
                return(Frustum.VISIBILITY.INVISIBLE);
            }

            var v3 = GetClipVisibility(node.DeformedFrustumPlanes[3], deformedBox, f);

            if (v3 == Frustum.VISIBILITY.INVISIBLE)
            {
                return(Frustum.VISIBILITY.INVISIBLE);
            }

            var v4 = GetClipVisibility(node.DeformedFrustumPlanes[4], deformedBox, f);

            if (v4 == Frustum.VISIBILITY.INVISIBLE)
            {
                return(Frustum.VISIBILITY.INVISIBLE);
            }

            if (v0 == Frustum.VISIBILITY.FULLY && v1 == Frustum.VISIBILITY.FULLY &&
                v2 == Frustum.VISIBILITY.FULLY && v3 == Frustum.VISIBILITY.FULLY &&
                v4 == Frustum.VISIBILITY.FULLY)
            {
                return(Frustum.VISIBILITY.FULLY);
            }

            return(Frustum.VISIBILITY.PARTIALLY);
        }
예제 #18
0
    protected override void OnUpdate()
    {
        if (flag)
        {
            return;
        }

        flag = true;

        ComponentGroup planetGroup = GetComponentGroup(typeof(Planet), typeof(PlanetNoise));
        ComponentGroup dataGroup   = GetComponentGroup(typeof(PlanetSharedData));

        ComponentDataArray <Planet>                 planetArray = planetGroup.GetComponentDataArray <Planet>();
        ComponentDataArray <PlanetNoise>            noiseArray  = planetGroup.GetComponentDataArray <PlanetNoise>();
        SharedComponentDataArray <PlanetSharedData> dataArray   = dataGroup.GetSharedComponentDataArray <PlanetSharedData>();

        GameObject prefab = dataArray[0].nodePrefab;

        for (int i = 0; i < planetArray.Length; ++i)
        {
            Planet        planet = planetArray[i];
            PlanetNoise   noise  = noiseArray[i];
            HyperDistance r      = planet.radius;

            for (int n = 0; n < 20; ++n)
            {
                Entity      nodeEntity = EntityManager.Instantiate(prefab);
                TerrainNode node       = EntityManager.GetComponentData <TerrainNode>(nodeEntity);
                node.level        = 0;
                node.planetData   = planet;
                node.noiseData    = noise;
                node.built        = 0;
                node.divided      = 0;
                node.hyperDistant = 1;

                int idx = n * 3;
                node.corner1 = icoVerts[idx];
                node.corner2 = icoVerts[idx + 1];
                node.corner3 = icoVerts[idx + 2];
                EntityManager.SetComponentData(nodeEntity, node);

                HyperPosition pos = math.normalize(node.corner1 + node.corner2 + node.corner3) * r;

                PrecisePosition prspos = new PrecisePosition {
                    pos = pos.prs
                };
                EntityManager.SetComponentData(nodeEntity, prspos);

                OctantPosition octpos = new OctantPosition {
                    pos = pos.oct
                };
                EntityManager.SetComponentData(nodeEntity, octpos);
            }
        }
    }
예제 #19
0
        public virtual void SetUniforms(TerrainNode node, Material target)
        {
            if (target == null || node == null)
            {
                return;
            }

            target.SetVector(uniforms.blending, node.DistanceBlending);
            target.SetMatrix(uniforms.localToScreen, node.LocalToScreen.ToMatrix4x4());
            target.SetMatrix(uniforms.localToWorld, node.LocalToWorld.ToMatrix4x4());
        }
        public override void SetUniforms(TerrainNode node, Material mat)
        {
            if (mat == null || node == null)
            {
                return;
            }

            base.SetUniforms(node, mat);

            mat.SetFloat(m_uniforms.radius, (float)R);
        }
예제 #21
0
        public override void SetUniforms(TerrainNode node, Material target)
        {
            if (target == null || node == null)
            {
                return;
            }

            base.SetUniforms(node, target);

            target.SetFloat(uniforms.radius, (float)R);
        }
예제 #22
0
 /*
  * Creates a new TerrainQuad.
  *
  * param owner the TerrainNode to which the terrain quadtree belongs.
  * param parent the parent quad of this quad.
  * param tx the logical x coordinate of this quad.
  * param ty the logical y coordinate of this quad.
  * param ox the physical x coordinate of the lower left corner of this quad.
  * param oy the physical y coordinate of the lower left corner of this quad.
  * param l the physical size of this quad.
  * param zmin the minimum %terrain elevation inside this quad.
  * param zmax the maximum %terrain elevation inside this quad.
  */
 public TerrainQuad(TerrainNode owner, TerrainQuad parent, int tx, int ty, double ox, double oy, double length, float zmin, float zmax)
 {
     m_owner    = owner;
     m_parent   = parent;
     m_level    = (m_parent == null) ? 0 : m_parent.GetLevel() + 1;
     m_tx       = tx;
     m_ty       = ty;
     m_ox       = ox;
     m_oy       = oy;
     m_zmax     = zmax;
     m_zmin     = zmin;
     m_length   = length;
     m_localBox = new Box3d(m_ox, m_ox + m_length, m_oy, m_oy + m_length, m_zmin, m_zmax);
 }
예제 #23
0
파일: Body.cs 프로젝트: zameran/SpaceW
        private void DrawTerrain(TerrainNode node, int layer)
        {
            // So, if doesn't have any samplers - do anything...
            if (node.Samplers.Count == 0 || node.SamplersSuitable.Count == 0)
            {
                return;
            }

            // Find all the quads in the terrain node that need to be drawn
            node.FindDrawableQuads(node.TerrainQuadRoot);

            // The draw them
            node.DrawQuads(node.TerrainQuadRoot, QuadMesh, MPB, layer);
        }
예제 #24
0
        public virtual void SetUniforms(TerrainNode node, TerrainQuad quad, Material target)
        {
            if (target == null || node == null || quad == null)
            {
                return;
            }

            target.SetVector(uniforms.offset, CalculateDeformedOffset(quad));
            target.SetVector(uniforms.camera, CalculateDeformedCameraPosition(node, quad));

            target.SetMatrix(uniforms.tileToTangent, CalculateDeformedLocalToTangent(node, quad));

            SetScreenUniforms(node, quad, target);
        }
        protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l  = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, R);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, R);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, R);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R);
            Vector3d2 pc = (p0 + p3) * 0.5;

            double    l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0;
            Vector3d2 v0 = p0.Normalized(ref l0);
            Vector3d2 v1 = p1.Normalized(ref l1);
            Vector3d2 v2 = p2.Normalized(ref l2);
            Vector3d2 v3 = p3.Normalized(ref l3);

            Matrix4x4d deformedCorners = new Matrix4x4d(v0.x * R, v1.x * R, v2.x * R, v3.x * R,
                                                        v0.y * R, v1.y * R, v2.y * R, v3.y * R,
                                                        v0.z * R, v1.z * R, v2.z * R, v3.z * R,
                                                        1.0, 1.0, 1.0, 1.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4());

            Matrix4x4d deformedVerticals = new Matrix4x4d(v0.x, v1.x, v2.x, v3.x,
                                                          v0.y, v1.y, v2.y, v3.y,
                                                          v0.z, v1.z, v2.z, v3.z,
                                                          0.0, 0.0, 0.0, 0.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4());
            matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3));

            Vector3d2 uz = pc.Normalized();
            Vector3d2 ux = (new Vector3d2(0, 1, 0)).Cross(uz).Normalized();
            Vector3d2 uy = uz.Cross(ux);

            Matrix4x4d ltow = node.GetLocalToWorld();

            Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0, 0], ltow.m[0, 1], ltow.m[0, 2],
                                                            ltow.m[1, 0], ltow.m[1, 1], ltow.m[1, 2],
                                                            ltow.m[2, 0], ltow.m[2, 1], ltow.m[2, 2]);

            Matrix3x3d m = new Matrix3x3d(ux.x, uy.x, uz.x,
                                          ux.y, uy.y, uz.y,
                                          ux.z, uy.z, uz.z);

            matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4());
        }
예제 #26
0
 public void RemoveTerrainNode(Transform transform_node)
 {
     foreach (TerrainNode terrain_node in terrain_node_list)
     {
         if (transform_node == terrain_node.transform)
         {
             terrain_node_list.Remove(terrain_node);
             // TODO: Instead of reanalyzing the entire list,
             // there could be a method in TerrainNode (Heap-like structure)
             // that would update only the nodes that need to be updated.
             TerrainNode.SortAdjacentNodes(terrain_node_list, max_distance);
             break;
         }
     }
 }
예제 #27
0
 public List <TerrainNode> reconstruct_path(List <TerrainNode> came_from, TerrainNode current_node)
 {
     if (current_node.getCameFrom() != null)
     {
         List <TerrainNode> p = reconstruct_path(came_from, current_node.getCameFrom());
         p.Add(current_node);
         return(p);
     }
     else
     {
         List <TerrainNode> p = new List <TerrainNode>();
         p.Add(current_node);
         return(p);
     }
 }
예제 #28
0
        public override Frustum3d.VISIBILITY GetVisibility(TerrainNode node, Box3d localBox, Vector3d[] deformedBox)
        {
            var f = (float)((R - localBox.Min.z) / ((R - localBox.Max.z) * Math.Cos((localBox.Max.y - localBox.Min.y) / (2.0 * R))));

            var v0 = GetClipVisibility(node.DeformedFrustumPlanes[0], deformedBox, f);

            if (v0 == Frustum3d.VISIBILITY.INVISIBLE)
            {
                return(Frustum3d.VISIBILITY.INVISIBLE);
            }

            var v1 = GetClipVisibility(node.DeformedFrustumPlanes[1], deformedBox, f);

            if (v1 == Frustum3d.VISIBILITY.INVISIBLE)
            {
                return(Frustum3d.VISIBILITY.INVISIBLE);
            }

            var v2 = GetClipVisibility(node.DeformedFrustumPlanes[2], deformedBox, f);

            if (v2 == Frustum3d.VISIBILITY.INVISIBLE)
            {
                return(Frustum3d.VISIBILITY.INVISIBLE);
            }

            var v3 = GetClipVisibility(node.DeformedFrustumPlanes[3], deformedBox, f);

            if (v3 == Frustum3d.VISIBILITY.INVISIBLE)
            {
                return(Frustum3d.VISIBILITY.INVISIBLE);
            }

            var v4 = GetClipVisibility(node.DeformedFrustumPlanes[4], deformedBox, f);

            if (v4 == Frustum3d.VISIBILITY.INVISIBLE)
            {
                return(Frustum3d.VISIBILITY.INVISIBLE);
            }

            if (v0 == Frustum3d.VISIBILITY.FULLY && v1 == Frustum3d.VISIBILITY.FULLY &&
                v2 == Frustum3d.VISIBILITY.FULLY && v3 == Frustum3d.VISIBILITY.FULLY &&
                v4 == Frustum3d.VISIBILITY.FULLY)
            {
                return(Frustum3d.VISIBILITY.FULLY);
            }

            return(Frustum3d.VISIBILITY.PARTIALLY);
        }
예제 #29
0
    // Finds the closest Terrrain Node in the list to a given point
    public TerrainNode FindClosestTerrainNodeToPoint(Vector3 point)
    {
        TerrainNode closest_terrain_node = terrain_node_list[0];
        float       shortest_distance    = Vector3.Distance(terrain_node_list[0].position, point);

        foreach (TerrainNode terrain_node in terrain_node_list)
        {
            float distance = Vector3.Distance(terrain_node.position, point);
            if (distance < shortest_distance)
            {
                closest_terrain_node = terrain_node;
                shortest_distance    = distance;
            }
        }
        return(closest_terrain_node);
    }
예제 #30
0
        /// <summary>
        /// Converts a 2D TerrainCell array to raw VP terrain data
        /// </summary>
        /// <remarks>http://stackoverflow.com/a/650886</remarks>
        internal static byte[] NodeToNodeData(TerrainNode node)
        {
            var data = new byte[512];

            for (var i = 0; i < 64; i++)
            {
                var cell   = node[i];
                var buffer = Marshal.AllocHGlobal(8);
                var array  = new byte[8];
                Marshal.StructureToPtr(cell, buffer, false);
                Marshal.Copy(buffer, data, i * 8, 8);
                Marshal.FreeHGlobal(buffer);
            }

            return(data);
        }
예제 #31
0
        public override void SetUniforms(TerrainNode node, Material mat)
        {
            if(mat == null || node == null) return;

            base.SetUniforms(node, mat);

            mat.SetFloat(m_uniforms.radius, (float)R);
        }
예제 #32
0
 /**
  * Returns the visibility of a bounding box in local space, in a view
  * frustum defined in deformed space.
  *
  * param node a TerrainNode. 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 localBox a bounding box in local space.
  * return the visibility of the bounding box in the view frustum.
  */
 public virtual Frustum.VISIBILTY GetVisibility(TerrainNode node, Box3d localBox)
 {
     // localBox = deformedBox, so we can compare the deformed frustum with it
     return Frustum.GetVisibility(node.GetDeformedFrustumPlanes(), localBox);
 }
예제 #33
0
    // Update is called once per frame
    void Update()
    {
        if (GameManager.mGameInstance.CurrentGameMode == GameMode.E_BUILDINGMODE) {
            if (mIsBuildingSelected) {
                Ray ray = new Ray();
                RaycastHit hit;
                if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor)
                {
                    ray = Camera.main.ScreenPointToRay (Input.mousePosition);
                    if(Physics.Raycast (ray, out hit, Mathf.Infinity, LayerMask.GetMask ("Terrain")))
                    {
                        if (hit.collider) {
                            //hit.collider.GetComponent<SpriteRenderer> ().color = new Color (0, 0, 0);
                            Vector3 tempselectposition = hit.collider.transform.position;
                            TerrainNode tempterrainnode = hit.collider.GetComponent<TerrainNode> ();
                            switch (mSelectedBuilding.mBI.getBuildingType ()) {
                            case BuildingType.E_WALL:
                                tempselectposition.y += 0.5f;
                                break;
                            case BuildingType.E_HOUSE:
                                tempselectposition.x += 0.5f;
                                tempselectposition.z += 0.5f;
                                break;
                            case BuildingType.E_DRAWER:
                                tempselectposition.x += 0.9f;
                                tempselectposition.z += 0.9f;
                                break;
                            }

                            mCurrentSelectedBuilding.transform.position = tempselectposition;
                            mSelectedBuilding.mBI.Position = tempselectposition;
                            mCurrentOccupiedIndex = tempterrainnode.RowColumnInfo;
                            mCurrentSelectedNode = mNodeTerrainList [tempterrainnode.Index];
                        }
                    }
                }
                else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
                {
                    if(Input.touchCount == 1)
                    {
                        if(Input.touches[0].phase == TouchPhase.Moved)
                        {
                            ray = Camera.main.ScreenPointToRay (Input.touches[0].position);
                            if(Physics.Raycast (ray, out hit, Mathf.Infinity, LayerMask.GetMask ("Terrain")))
                            {
                                if (hit.collider) {
                                    TerrainNode currentterrainnode = hit.transform.gameObject.GetComponent<TerrainNode>();
                                    if(Utility.IsValidTerrainToMoveBuilding(currentterrainnode.Index))
                                    {
                                        //hit.collider.GetComponent<SpriteRenderer> ().color = new Color (0, 0, 0);
                                        Vector3 tempselectposition = hit.collider.transform.position;
                                        TerrainNode tempterrainnode = hit.collider.GetComponent<TerrainNode> ();
                                        switch (mSelectedBuilding.mBI.getBuildingType ()) {
                                        case BuildingType.E_WALL:
                                            tempselectposition.y += 0.5f;
                                            break;
                                        case BuildingType.E_HOUSE:
                                            tempselectposition.x += 0.5f;
                                            tempselectposition.z += 0.5f;
                                            break;
                                        case BuildingType.E_DRAWER:
                                            tempselectposition.x += 0.9f;
                                            tempselectposition.z += 0.9f;
                                            break;
                                        }

                                        mCurrentSelectedBuilding.transform.position = tempselectposition;
                                        mSelectedBuilding.mBI.Position = tempselectposition;
                                        mSelectedBuilding.mBI.mIndex = mSelectedBuilding.GetBuildingIndex();
                                        mCurrentOccupiedIndex = tempterrainnode.RowColumnInfo;
                                        mCurrentSelectedNode = mNodeTerrainList [tempterrainnode.Index];
                                    }
                                }
                            }
                        }
                        else
                        {
                            Debug.Log("hit.transform.gameObject.GetInstanceID() != MapManager.MMInstance.CurrentSelectedBuilding.GetInstanceID()");
                        }
                    }
                }

            }
        }
    }
예제 #34
0
        protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, R);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, R);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, R);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R);
            Vector3d2 pc = (p0 + p3) * 0.5;

            double l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0;
            Vector3d2 v0 = p0.Normalized(ref l0);
            Vector3d2 v1 = p1.Normalized(ref l1);
            Vector3d2 v2 = p2.Normalized(ref l2);
            Vector3d2 v3 = p3.Normalized(ref l3);

            Matrix4x4d deformedCorners = new Matrix4x4d(v0.x * R, v1.x * R, v2.x * R, v3.x * R,
                                                        v0.y * R, v1.y * R, v2.y * R, v3.y * R,
                                                        v0.z * R, v1.z * R, v2.z * R, v3.z * R,
                                                        1.0, 1.0, 1.0, 1.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4());

            Matrix4x4d deformedVerticals = new Matrix4x4d(	v0.x, v1.x, v2.x, v3.x,
                                                          v0.y, v1.y, v2.y, v3.y,
                                                          v0.z, v1.z, v2.z, v3.z,
                                                          0.0, 0.0, 0.0, 0.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4());
            matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3));

            Vector3d2 uz = pc.Normalized();
            Vector3d2 ux = (new Vector3d2(0,1,0)).Cross(uz).Normalized();
            Vector3d2 uy = uz.Cross(ux);

            Matrix4x4d ltow = node.GetLocalToWorld();

            Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0,0], ltow.m[0,1], ltow.m[0,2],
                                                            ltow.m[1,0], ltow.m[1,1], ltow.m[1,2],
                                                            ltow.m[2,0], ltow.m[2,1], ltow.m[2,2]);

            Matrix3x3d m = new Matrix3x3d(	ux.x, uy.x, uz.x,
                                          ux.y, uy.y, uz.y,
                                          ux.z, uy.z, uz.z);

            matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4());
        }
예제 #35
0
        public override Frustum.VISIBILTY GetVisibility(TerrainNode t, Box3d localBox)
        {
            Vector3d2[] deformedBox = new Vector3d2[4];
            deformedBox[0] = LocalToDeformed(new Vector3d2(localBox.xmin, localBox.ymin, localBox.zmin));
            deformedBox[1] = LocalToDeformed(new Vector3d2(localBox.xmax, localBox.ymin, localBox.zmin));
            deformedBox[2] = LocalToDeformed(new Vector3d2(localBox.xmax, localBox.ymax, localBox.zmin));
            deformedBox[3] = LocalToDeformed(new Vector3d2(localBox.xmin, localBox.ymax, localBox.zmin));

            double a = (localBox.zmax + R) / (localBox.zmin + R);
            double dx = (localBox.xmax - localBox.xmin) / 2 * a;
            double dy = (localBox.ymax - localBox.ymin) / 2 * a;
            double dz = localBox.zmax + R;
            double f = Math.Sqrt(dx * dx + dy * dy + dz * dz) / (localBox.zmin + R);

            Vector4d[] deformedFrustumPlanes = t.GetDeformedFrustumPlanes();

            Frustum.VISIBILTY v0 = GetVisibility(deformedFrustumPlanes[0], deformedBox, f);
            if (v0 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            Frustum.VISIBILTY v1 = GetVisibility(deformedFrustumPlanes[1], deformedBox, f);
            if (v1 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            Frustum.VISIBILTY v2 = GetVisibility(deformedFrustumPlanes[2], deformedBox, f);
            if (v2 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            Frustum.VISIBILTY v3 = GetVisibility(deformedFrustumPlanes[3], deformedBox, f);
            if (v3 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            Frustum.VISIBILTY v4 = GetVisibility(deformedFrustumPlanes[4], deformedBox, f);
            if (v4 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            Vector3d2 c = t.GetDeformedCameraPos();
            double lSq = c.SqrMagnitude();
            double rm = R + Math.Min(0.0, localBox.zmin);
            double rM = R + localBox.zmax;
            double rmSq = rm * rm;
            double rMSq = rM * rM;
            Vector4d farPlane = new Vector4d(c.x, c.y, c.z, Math.Sqrt((lSq - rmSq) * (rMSq - rmSq)) - rmSq);

            Frustum.VISIBILTY v5 = GetVisibility(farPlane, deformedBox, f);
            if (v5 == Frustum.VISIBILTY.INVISIBLE) {
                return Frustum.VISIBILTY.INVISIBLE;
            }

            if (v0 == Frustum.VISIBILTY.FULLY && v1 == Frustum.VISIBILTY.FULLY &&
                v2 == Frustum.VISIBILTY.FULLY && v3 == Frustum.VISIBILTY.FULLY &&
                v4 == Frustum.VISIBILTY.FULLY && v5 == Frustum.VISIBILTY.FULLY)
            {
                return Frustum.VISIBILTY.FULLY;
            }
            return Frustum.VISIBILTY.PARTIALLY;
        }
예제 #36
0
 /**
 * Creates a new TerrainQuad.
 *
 * param owner the TerrainNode to which the terrain quadtree belongs.
 * param parent the parent quad of this quad.
 * param tx the logical x coordinate of this quad.
 * param ty the logical y coordinate of this quad.
 * param ox the physical x coordinate of the lower left corner of this quad.
 * param oy the physical y coordinate of the lower left corner of this quad.
 * param l the physical size of this quad.
 * param zmin the minimum %terrain elevation inside this quad.
 * param zmax the maximum %terrain elevation inside this quad.
 */
 public TerrainQuad(TerrainNode owner, TerrainQuad parent, int tx, int ty, double ox, double oy, double length, float zmin, float zmax)
 {
     m_owner = owner;
     m_parent = parent;
     m_level = (m_parent == null) ? 0 : m_parent.GetLevel() + 1;
     m_tx = tx;
     m_ty = ty;
     m_ox = ox;
     m_oy = oy;
     m_zmax = zmax;
     m_zmin = zmin;
     m_length = length;
     m_localBox = new Box3d(m_ox, m_ox + m_length, m_oy, m_oy + m_length, m_zmin, m_zmax);
 }
예제 #37
0
        protected virtual void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, 0.0);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, 0.0);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, 0.0);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, 0.0);

            Matrix4x4d corners = new Matrix4x4d(p0.x, p1.x, p2.x, p3.x,
                                                p0.y, p1.y, p2.y, p3.y,
                                                p0.z, p1.z, p2.z, p3.z,
                                                1.0, 1.0, 1.0, 1.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * corners).ToMatrix4x4());

            Matrix4x4d verticals = new Matrix4x4d(	0.0, 0.0, 0.0, 0.0,
                                                  0.0, 0.0, 0.0, 0.0,
                                                  1.0, 1.0, 1.0, 1.0,
                                                  0.0, 0.0, 0.0, 0.0);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * verticals).ToMatrix4x4());
        }
예제 #38
0
        /**
        * Sets the shader uniforms that are necessary to project on screen the
        * given TerrainQuad. This method can set the uniforms that are specific to
        * the given quad.
        */
        public virtual void SetUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            if(matPropertyBlock == null || node == null || quad == null) return;

            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l = quad.GetLength();
            double distFactor = (double)node.GetDistFactor();
            int level = quad.GetLevel();

            matPropertyBlock.AddVector(m_uniforms.offset, new Vector4((float)ox, (float)oy, (float)l, (float)level));

            Vector3d2 camera = node.GetLocalCameraPos();

            matPropertyBlock.AddVector(m_uniforms.camera, new Vector4(	(float)((camera.x - ox) / l), (float)((camera.y - oy) / l),
                                                                      (float)((camera.z - node.GetView().GetGroundHeight()) / (l * distFactor)),
                                                                      (float)camera.z));

            Vector3d2 c = node.GetLocalCameraPos();

            Matrix3x3d m = m_localToTangent * (new Matrix3x3d(l, 0.0, ox - c.x, 0.0, l, oy - c.y, 0.0, 0.0, 1.0));

            matPropertyBlock.AddMatrix(m_uniforms.tileToTangent, m.ToMatrix4x4());

            SetScreenUniforms(node, quad, matPropertyBlock);
        }
예제 #39
0
        /**
        * Sets the shader uniforms that are necessary to project on screen the
        * TerrainQuad of the given TerrainNode. This method can set the uniforms
        * that are common to all the quads of the given terrain.
        */
        public virtual void SetUniforms(TerrainNode node, Material mat)
        {
            if(mat == null || node == null) return;

            float d1 = node.GetSplitDist() + 1.0f;
            float d2 = 2.0f * node.GetSplitDist();
            mat.SetVector(m_uniforms.blending, new Vector2(d1, d2 - d1));

            m_localToCamera = node.GetView().GetWorldToCamera() * node.GetLocalToWorld();
            m_localToScreen = node.GetView().GetCameraToScreen() * m_localToCamera;

            Vector3d2 localCameraPos = node.GetLocalCameraPos();
            Vector3d2 worldCamera = node.GetView().GetWorldCameraPos();

            Matrix4x4d A = LocalToDeformedDifferential(localCameraPos);
            Matrix4x4d B = DeformedToTangentFrame(worldCamera);

            Matrix4x4d ltot = B * node.GetLocalToWorld() * A;

            m_localToTangent = new Matrix3x3d(	ltot.m[0,0], ltot.m[0,1], ltot.m[0,3],
                                              ltot.m[1,0], ltot.m[1,1], ltot.m[1,3],
                                              ltot.m[3,0], ltot.m[3,1], ltot.m[3,3]);

            mat.SetMatrix(m_uniforms.localToScreen, m_localToScreen.ToMatrix4x4());
            mat.SetMatrix(m_uniforms.localToWorld, node.GetLocalToWorld().ToMatrix4x4());
        }