static MarchingCubesDispatcher instance; // just used to make sure only one of these at once
    void Awake()
    {
        if (!SystemInfo.supportsComputeShaders)
        {
            Debug.LogError("THIS IS BAD");
            DestroyImmediate(gameObject);
            return;
        }

        if (instance == null)
        {
            instance = this;
        }
        else
        {
            DestroyImmediate(this);
            return;
        }

        queue = new FastPriorityQueue <ChunkRequest>(10000);

        kernelMC = MarchingCubesCS.FindKernel("MarchingCubes");
        //kernelTripleCount = MarchingCubesCS.FindKernel("TripleCount");

        MarchingCubesCS.SetInt("_gridSize", resolution);
        MarchingCubesCS.SetFloat("_isoLevel", 0.0f);    // halfway point for noise in range [-1, 1]

        workers = new MarchingCubesWorker[numWorkers];
        for (int i = 0; i < workers.Length; ++i)
        {
            workers[i] = new MarchingCubesWorker(resolution, kernelMC, MarchingCubesCS, noiseMat);
        }
    }
Example #2
0
    // for GPU cubes. just throw out all ur meshes and request new ones
    // nice for when you change material params
    public void ResetMeshes()
    {
        SetSplitting(false);

        // dont do this actually since changing parameters will cause the terrain to change
        // so spots that were empty might not be anymore... even doing this tho will cause the number of
        // trees to rise as old ones that were split fully become empty but remain max split
        // should maybe just rebuild whole tree everytime...
        // this is just purely for debugging tho so doesnt really matter
        if (emptyMesh)
        {
            //return;
        }

        if (obj.mf.mesh != null)
        {
            Object.Destroy(obj.mf.mesh);
        }
        // double check that the tree didnt die is only thing (inner nodes should still get their meshes regened)
        MarchingCubesDispatcher.Enqueue(worldPos, voxelSize, AssignMesh, NotDead, GetSqrDistToCamFromCenter()); // do this since still splitting emptys in this mode
        if (hasChildren)
        {
            for (int i = 0; i < 8; ++i)
            {
                children[i].ResetMeshes();
            }
        }
    }
Example #3
0
    void Update()
    {
        if (Input.GetKey(KeyCode.R))
        {
            transform.Rotate(rotation * Time.deltaTime);
        }
        if (Input.GetKeyDown(KeyCode.P))
        {
            MarchingCubesDispatcher.ClearRequests();
            root.ResetMeshes();
        }
        currentMatrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);

        // cache player position this frame because like a billion things reference
        // this and the cost of transform.getposition adds up
        player = playerTransform.position;

        root.Update();
        invalidCheckTimer -= Time.deltaTime;
        if (invalidCheckTimer < 0.0f)
        {
            if (!root.IsTreeValid())
            {
                Debug.LogError("INVALID TREE DETECTED");
            }
            invalidCheckTimer = 2.0f;
            int num = root.GetCount(false);
            countText.text = "Trees: " + num;
            //Debug.Log(root.GetNumGameObjects(true));
        }
    }
Example #4
0
    // Use this for initialization
    void Start()
    {
        // will later need to set this in chunk material property blocks i think
        //mat.SetVector("_PlanetCenter", transform.position);

        root = new Octree(this, null, Vector3.zero, 0, 0);
        //root.BuildGameObject(root.GenerateMesh(true));

        root.SetupChunk();
        MarchingCubesDispatcher.Enqueue(root.worldPos, root.voxelSize, root.AssignMesh, root.GetSqrDistToCamFromCenter());
        //root.SplitCompute();

        // calculating split levels by hand now
        // too hard to get right witha formula to look good both on surface and
        // from high up in space (may need to change strat, like dynamic split more chunks based on total num tris)
        Debug.Assert(splitLevels.Length >= Octree.MAX_DEPTH + 1);
        //splitLevels = new float[Octree.MAX_DEPTH + 1];
        //int len = splitLevels.Length;
        //splitLevels[len - 1] = maxDepthDist;
        //for (int i = len - 2; i >= 0; --i) {
        //    splitLevels[i] = splitLevels[i + 1] * 1.74f;
        //    //splitLevels[i] = splitLevels[i + 1] * 2.0f;
        //}

        // old way of calculating squaresplit levels
        //for (int i = 0; i < squareSplitLevels.Length; i++) {
        //    float level = Mathf.Pow(2f, Octree.MAX_DEPTH - i) * 100f; //64.0f;
        //    squareSplitLevels[i] = level * level;
        //}
        rotation = Random.onUnitSphere; // * speed?

        playerTransform = GameObject.Find("Player").transform;
    }
Example #5
0
    public void SplitCompute()
    {
        SetSplitting(true);

        if (childMeshes == null)
        {
            childMeshes = new MeshData[8];
        }
        childMeshCount = 0;
        int   childDepth     = depth + 1;
        float childVoxelSize = GetVoxelSize(childDepth);
        float priority       = GetSplitPriority();

        for (int i = 0; i < 8; ++i)
        {
            Vector3 childWorldPos = GetChildCenter(i) - Vector3.one * (SIZE / 2f) * childVoxelSize;

            MarchingCubesDispatcher.Enqueue(childWorldPos, childVoxelSize, GetChildMesh, LastSplitCheck, priority, i);
        }
    }