public void BuildFromLandingSpot(SphericalCoord landingSpot) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); terrainChunks = new DynamicTerrainChunk[numCols, numRows]; // Create the center chunk. Quaternion rotation = CoordHelper.SphericalToRotation(landingSpot); if (rotTest) { rotation *= Quaternion.Euler(0, 0, 45); } Vector3 position = new Vector3( (-WorldUnitsPerChunk / 2f), 0, (-WorldUnitsPerChunk / 2f) ); // FIXME: Hardcoded? terrainChunks[1, 1] = BuildChunk(rotation, position); BuildChunkArray(); //RebuildChunks(); sw.Stop(); Debug.Log("Terrain generation time: " + (sw.ElapsedMilliseconds / 1000f)); }
//TODO: Split into different files private void OnMouseUp() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { Transform objectHit = hit.transform; //Instantiate ( this.Cube, hit.point, Quaternion.identity ); var point = hit.point; Debug.Log(point.y + ", " + (point.y - 0.2f * point.y)); if (point.y > 1.4 && point.y < 1.93) { point.y -= 0.1f * point.y; } if (point.y > 1.93) { point.y -= 0.18f * point.y; } Vector3 p = new Vector3(point.x, point.y, point.z); SphericalCoord cs = CoordHelper.TransformToSphericalCoord(p, this.transform.position); Vector2 uv = CoordHelper.SphericalToUV(cs); ReadFromMap(uv); } }
protected override void OnStartIdle(float deltaTime) { Vector3 relativePos = transform.position - mRotationCenter; mSphericalCoord = Geometry.Cartesian2Spherical(new CVec(relativePos.X, relativePos.Y, relativePos.Z)); mSphericalCoord.R = mOrbitRadius; }
public static Vector2 SphericalToUV(SphericalCoord sc) { Vector2 uv = new Vector2( (1 - (sc.Longitude / 360f)), ((sc.Latitude / 180f)) ); return(uv); }
public static Vector2 SphericalToUV(SphericalCoord sphereCoord) { Vector2 uv = new Vector2( (sphereCoord.Longitude / 360f), (sphereCoord.Latitude + 90) / 180f ); return(uv); }
void FixedUpdate() { string s = ""; s += string.Format("TRANSFORM (SPACE): {0}\n", TargetObject.position); SphericalCoord sphereCoord = CoordHelper.TransformToSphericalCoord(TargetObject.position, ParentObject.position); s += string.Format("SPHERICAL COORDINATES: {0}\n", sphereCoord.ToString()); Vector2 uvCoord = CoordHelper.SphericalToUV(sphereCoord); s += string.Format("UV COORDINATES: {0}\n", uvCoord.ToString()); text.text = s; }
/// <summary> /// 指定した位置の球面座標上に移動させます。 /// </summary> /// <param name="position">位置</param> public void SetPos(Vector3 position) { var centerPos = center.position; centerPos.y += parameter.heightOffset; var cartesianPos = position - centerPos; var sphericalTemp = SphericalCoord.GetSphericalPositionFromCartesianCoord(cartesianPos); spherical.phi = sphericalTemp.phi; spherical.theta = sphericalTemp.theta; UpdatePos(); }
void Update() { string s = ""; s += string.Format("Transform: {0}\n", TargetObject.position); SphericalCoord sphereCoord = CoordHelper.TransformToSphericalCoord(TargetObject.position, ParentObject.position); s += string.Format("Spherical Coordinates: {0}\n", sphereCoord.ToString()); Vector2 uvCoord = CoordHelper.SphericalToUV(sphereCoord); s += string.Format("Texture UV: {0}\n", uvCoord.ToString()); text.text = s; }
public static SphericalCoord TransformToSphericalCoord(Vector3 targetPos, Vector3 parentPos) { Vector3 dirToTarget = targetPos - parentPos; Quaternion quatToTarget = Quaternion.LookRotation(dirToTarget); SphericalCoord coord = new SphericalCoord(); float lat = quatToTarget.eulerAngles.x; float lon = quatToTarget.eulerAngles.y; coord.Latitude = lat; coord.Longitude = lon; return(coord); }
public void SwitchToSpace() { if (isTerrain == false) { Debug.LogError("Already in space mode."); return; } // We are in terrain mode, but have to switch to space mode. isTerrain = false; // What are the coordinates of the ship relative to the planetoid SphericalCoord sphereCoord = TheTerrain.GetComponent <DynamicTerrainMaster>().WorldToSpherical(TheShip.transform.position); string s = string.Format("Taking off from coordinates: {0}\n", sphereCoord.ToString()); Debug.Log(s); TheTerrain.GetComponent <DynamicTerrainMaster>().DestroyChunks(); ThePlanetoid.SetActive(true); TheTerrain.SetActive(false); // Now that the terrain exists, move the ship to be in the same reference system. // Rotate the ship -90 around the X axis TheShip.transform.RotateAround(Vector3.zero, Vector3.right, 90); Vector3 pos = TheShip.transform.position; float planetRadius = ThePlanetoid.transform.localScale.x / 2f; // Pick any one axis of the scale // In space, 1 unit = 1km. On ground, 1 unit = 1m. So DIVIDE scales/distance by 1000. pos /= 1000f; // Re-add the radius of the planetoid pos = pos.normalized * (pos.magnitude + planetRadius); TheShip.transform.position = pos; Vector3 scale = TheShip.transform.localScale / 1000f; TheShip.transform.localScale = scale; }
/// <summary> /// 現在の球面座標に従って位置を更新します。 /// </summary> private void UpdatePos() { // センターがなければ実行不可 if (center == null) { return; } // 中心位置セット var centerPos = center.position; centerPos.y += parameter.heightOffset; // 仰角制限を適用したうえで球面座標から直交座標の位置に変換 spherical.phi = Mathf.Clamp(spherical.phi, -parameter.thetaRestrictionDegree * Mathf.Deg2Rad, parameter.thetaRestrictionDegree * Mathf.Deg2Rad); position = SphericalCoord.GetPositionFromSphericalCoord(spherical); // ターゲットの距離と中心の位置を適用 position = position.normalized * parameter.distance; position += centerPos; transform.position = position; }
public void SwitchToTerrain() { if (isTerrain) { Debug.LogError("Already in terrain mode."); return; } // We are in space mode, but have to switch to terrain mode. isTerrain = true; // What are the coordinates of the ship relative to the planetoid SphericalCoord sphereCoord = CoordHelper.TransformToSphericalCoord(TheShip.position, ThePlanetoid.transform.position); string s = string.Format("Landing ship at coordinates: {0}\n", sphereCoord.ToString()); Debug.Log(s); ThePlanetoid.SetActive(false); TheTerrain.SetActive(true); // NOTE: This will freeze the game for a few seconds depending on processor speed. // Consider solutions like CoRoutines or Threading. TheTerrain.GetComponent <DynamicTerrainMaster>().BuildFromLandingSpot(sphereCoord); // Now that the terrain exists, move the ship to be in the same reference system. // Rotate the ship -90 around the X axis TheShip.transform.RotateAround(Vector3.zero, Vector3.right, -90); Vector3 pos = TheShip.transform.position; float planetRadius = ThePlanetoid.transform.localScale.x / 2f; // Pick any one axis of the scale // Subtract the radius of the planetoid pos = pos.normalized * (pos.magnitude - planetRadius); // In space, 1 unit = 1km. On ground, 1 unit = 1m. So mult scales/distance by 1000. TheShip.transform.position = pos * 1000f; Vector3 scale = TheShip.transform.localScale * 1000f; TheShip.transform.localScale = scale; }
/// <summary> /// Converts a SphericalCoord (Lat/Lon) into a Vector3 that represents /// the position of the Lat/Lon on this terrain chunk /// </summary> /// <param name="sc">Sc.</param> Vector3 SphericalToLocalPosition(SphericalCoord sc) { //Debug.Log( gameObject.name + " -- " + sc.ToString()); Quaternion buildingQat = CoordHelper.SphericalToRotation(sc); float xAngleDiff = buildingQat.eulerAngles.x - ChunkRotation.eulerAngles.x; while (xAngleDiff < -360) { xAngleDiff += 360; } while (xAngleDiff > 360) { xAngleDiff -= 360; } float yAngleDiff = buildingQat.eulerAngles.y - ChunkRotation.eulerAngles.y; //Debug.Log( gameObject.name + " -- xAngleDiff: " + xAngleDiff); //Debug.Log( gameObject.name + " -- yAngleDiff: " + yAngleDiff); Vector3 distFromCenter = new Vector3( ((yAngleDiff / DegreesPerChunk)) * WorldUnitsPerChunk, 0, // HEIGHT of building ((xAngleDiff / DegreesPerChunk)) * WorldUnitsPerChunk ); // Rotate the vector based on chunk's rotation // FIXME: I AM WRONG HERE. MAKE MATH MORE BETTER PLEASE // Do we need to incorporate longitude? I think we do. // I think we need to check the different in longitude between the center of the // terrain chunk and where the building is. distFromCenter = Quaternion.Euler(0, -ChunkRotation.eulerAngles.z, 0) * distFromCenter; // Now move the vector's origin to the bottom-left corner and return that return(distFromCenter + new Vector3(WorldUnitsPerChunk / 2, 0, WorldUnitsPerChunk / 2)); }
public static SphericalCoord TransformToSphericalCoord(Vector3 targetPos, Vector3 parentPos) { Vector3 dirToTarget = targetPos - parentPos; if (dirToTarget.sqrMagnitude == 0) { // Parent and target is the same, so force a 0/0 coord return(new SphericalCoord(0, 0)); } Quaternion quatToTarget = Quaternion.LookRotation(dirToTarget); SphericalCoord coord = new SphericalCoord(); float lat = quatToTarget.eulerAngles.x; float lon = 360 - quatToTarget.eulerAngles.y; coord.Latitude = lat; coord.Longitude = lon; return(coord); }
public static SphericalCoord TransformToSphericalCoord(Vector3 targetPos, Vector3 parentPos) { SphericalCoord sc = new SphericalCoord(); Vector3 dirToTarget = targetPos - parentPos; Quaternion quatToTarget = Quaternion.LookRotation(dirToTarget); sc.Latitude = quatToTarget.eulerAngles.x; sc.Longitude = quatToTarget.eulerAngles.y; return(sc); /* * SphericalCoord sc = new SphericalCoord (); * var point = parentPos-targetPos; * sc.Longitude = Mathf.Atan2 (point.x, point.z); * sc.Latitude = Mathf.Atan2 (-point.y, new Vector2 (point.x, point.z).magnitude); * sc.Latitude *= Mathf.Rad2Deg; * sc.Longitude *= Mathf.Rad2Deg; * return sc; */ }
public void BuildFromLandingSpot(SphericalCoord landingSpot) { terrainChunks = new DynamicTerrainChunk[numCols, numRows]; // Create the center chunk. Quaternion rotation = CoordHelper.SphericalToRotation(landingSpot); //rotation *= Quaternion.Euler( 0, 0, 45 ); Vector3 position = new Vector3( (-WorldUnitsPerChunk / 2f), 0, (-WorldUnitsPerChunk / 2f) ); // FIXME: Hardcoded? terrainChunks[1, 1] = BuildChunk(rotation, position); BuildChunkArray(); //RebuildChunks(); }
void BuildStructures() { // Loop through each pixel of the structures map // if we find pixels that aren't transparent (or whatever our criteria is) // then we will spawn a structure based on the color code. // IDEALLY -- We don't want to have to parse the building map for every chunk. // It would be nice instead if we did this once and just cached where all the // buildings should be. -- This is very easy. Color32[] pixels = StructureMapTexture.GetPixels32(); Color32 c32 = new Color32(255, 0, 0, 255); // Holy crap, it turns out that these .width and .height calls are SUUUUUUUUUPER expensive. // I cut my ENTIRE terrain-generation time in half by caching these. // -- quill18 int w = StructureMapTexture.width; int h = StructureMapTexture.height; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { Color32 p = pixels[x + y * w]; if (p.a < 128) { // transparent pixel, ignore. continue; } //Debug.Log("Not transparent!: " + p.ToString()); foreach (StructureColor sc in StructureColors) { if (sc.Color.r == p.r && sc.Color.g == p.g && sc.Color.b == p.b) { //Debug.Log("Color match!"); // What is the position of the building? SphericalCoord buildingLatLon = CoordHelper.UVToSpherical(new Vector2((float)x / w, (float)(y) / h)); Vector3 localPosition = SphericalToLocalPosition(buildingLatLon); if (localPosition.x < 0 || localPosition.x > WorldUnitsPerChunk || localPosition.z < 0 || localPosition.z > WorldUnitsPerChunk) { // Not in our chunk! continue; } // Spawn the correct building. Vector3 globalPosition = localPosition + this.transform.position; // Fix the building's height float heightAtGlobalPosition = terrain.SampleHeight(globalPosition); globalPosition.y = heightAtGlobalPosition; // Our rotation is going to be a factor of our longitude and the Z rotation of this chunk // FIXME: Test me -- especially near the poles and with different chunk rotations Quaternion rot = Quaternion.Euler(0, ChunkRotation.eulerAngles.z + Mathf.Sin(Mathf.Deg2Rad * buildingLatLon.Latitude) * buildingLatLon.Longitude, 0); GameObject theStructure = (GameObject)Instantiate(sc.StructurePrefab, globalPosition, rot, this.transform); SmoothTerrainUnderStructure(theStructure); // Stop looping through structure colors break; // foreach } } } } }
public static Quaternion SphericalToRotation(SphericalCoord sphereCoord) { return(Quaternion.Euler(-sphereCoord.Latitude, sphereCoord.Longitude, 0)); }