Exemple #1
0
    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));
    }
Exemple #2
0
    //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);
        }
    }
Exemple #3
0
        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;
        }
Exemple #4
0
    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);
    }
Exemple #6
0
    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);
    }
Exemple #10
0
    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;
        }
Exemple #12
0
    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);
    }
Exemple #15
0
    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;
         */
    }
Exemple #16
0
    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));
 }