コード例 #1
0
    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
                    }
                }
            }
        }
    }