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()); }
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()); }
/* * 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()); }
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)); }
/* * 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); }
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()); }
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)); }
/* * 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)); } }
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)); }
// 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); }
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>(); }
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()); }
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)))); }
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); }
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); }
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); } } }
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); }
public override void SetUniforms(TerrainNode node, Material target) { if (target == null || node == null) { return; } base.SetUniforms(node, target); target.SetFloat(uniforms.radius, (float)R); }
/* * 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); }
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); }
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()); }
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; } } }
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); } }
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); }
// 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); }
/// <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); }
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); }
/** * 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); }
// 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()"); } } } } } }
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()); }
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; }
/** * 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); }
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()); }
/** * 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); }
/** * 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()); }