public void OnColliderReady()
    {
        Profiler.BeginSample("OnColReady");
        bool isNewCollider = (OriginalChunkGo == null);

        if (OriginalChunkGo != null)
        {
            VFGoPool <VFVoxelChunkGo> .FreeGo(OriginalChunkGo);

            OriginalChunkGo = null;

            if (RebuildChunkColliderEvent != null)
            {
                try{ RebuildChunkColliderEvent(this); }
                catch { Debug.LogError("Error in RebuildChunkColliderEvent:" + transform.position); }
            }
            Profiler.EndSample();
            return;
        }
        else if (Data != null)
        {
            Data.OnGoColliderReady();
        }

        if (CreateChunkColliderEvent != null && isNewCollider)
        {
            try{ CreateChunkColliderEvent(this); }
            catch { Debug.LogError("Error in CreateChunkColliderEvent:" + transform.position); }
        }
        Profiler.EndSample();
    }
Beispiel #2
0
    public void ChunkProcPostGenMesh(IVxSurfExtractReq ireq)
    {
        SurfExtractReqMC req  = ireq as SurfExtractReqMC;
        VFVoxelChunkGo   vfGo = VFVoxelChunkGo.CreateChunkGo(req);

        req._chunk.AttachChunkGo(vfGo, req);
#if !ScopedCollider
        if (vfGo != null)
        {
            bChunkColliderRebuilding = true;
            vfGo._mc.sharedMesh      = null;
            vfGo._mc.sharedMesh      = vfGo._mf.mesh;
            foreach (Transform subGo in vfGo.transform)
            {
                VFVoxelChunkGo vfGoSub = subGo.GetComponent <VFVoxelChunkGo>();
                if (vfGoSub != null)
                {
                    vfGoSub._mc.sharedMesh = null;
                    vfGoSub._mc.sharedMesh = vfGoSub._mf.mesh;
                }
            }
            bChunkColliderRebuilding = false;
        }
#endif
    }
    public static VFVoxelChunkGo CreateChunkGo(Mesh sharedMesh)
    {
        VFVoxelChunkGo vfGo = VFGoPool <VFVoxelChunkGo> .GetGo();

        vfGo.Mf.sharedMesh = sharedMesh;
        vfGo._bPrimal      = true;
        vfGo.gameObject.SetActive(true);
        return(vfGo);
    }
    void OnChunkColliderRebuild(VFVoxelChunkGo chunk)
    {
        Vector3 min   = chunk.transform.position;
        Vector3 max   = chunk.transform.position + Vector3.one * VoxelTerrainConstants._numVoxelsPerAxis;
        Bounds  bound = new Bounds();

        bound.SetMinMax(min, max);
        AddChunk(bound);
    }
    // The above functions can be invoked in other thread
    // The below function will be invoked in main thread.
    public void AttachChunkGo(VFVoxelChunkGo vfGo, SurfExtractReqMC req = null)
    {
        if (vfGo != null)
        {
            float fScale = (1 << _chunkPosLod.w);
#if UNITY_EDITOR
            vfGo.name = PatheaScript.Util.GetChunkName(_chunkPosLod);
#endif
            vfGo.transform.localScale = new Vector3(fScale, fScale, fScale);
            vfGo.transform.position   = Pos;
            vfGo.Data            = this;
            vfGo.OriginalChunkGo = null;
            if (null != _goChunk && _goChunk.name.Equals(vfGo.name))
            {
                if (_goChunk.OriginalChunkGo != null)
                {
                    vfGo.OriginalChunkGo     = _goChunk.OriginalChunkGo;
                    _goChunk.OriginalChunkGo = null;
                }
                else if (_goChunk.Mc.sharedMesh != null)
                {
                    vfGo.OriginalChunkGo = _goChunk;
                    _goChunk.Mr.enabled  = false;
                    _goChunk             = null;
                }
            }
            else if (_node != null && SigOfType == VFVoxelTerrain.self.ChunkSig)
            {
                _node.OnMeshCreated();
            }
        }
        if (null != _goChunk)
        {
            VFGoPool <VFVoxelChunkGo> .FreeGo(_goChunk);
        }
        _goChunk  = vfGo;
        _bNoVerts = vfGo == null;

        if (_node != null && req != null)
        {
            if (!req.IsInvalid)
            {
#if BegEndUpdateNodeDataInSameThread
                lock (s_lstReqsToEndUpdateNodeData)
                {
                    s_lstReqsToEndUpdateNodeData.Add(new EndUpdateReq(req));
                }
#else
                EndUpdateNodeData();
#endif
            }
            return;
        }

        BuildStep = BuildStep_NotInBuild;
    }
Beispiel #6
0
    void ProcGenSeaSurface(SurfExtractReqMC req)
    {
        _tmpSeaSurfaceVerts.Clone(_seaSurfaceVerts [req._chunk.LOD]);           // To avoid outputdata(_seaSurfaceVerts) from clearing
        req.AddOutData(_tmpSeaSurfaceVerts);

        VFVoxelChunkGo vfGo = VFVoxelChunkGo.CreateChunkGo(req, _waterMat, s_layer);

        vfGo.transform.parent = gameObject.transform;
        req._chunkData        = _tmpSurfChunkData4Req;
        req._chunk.AttachChunkGo(vfGo, req);
    }
Beispiel #7
0
    public void ChunkProcPostGenMesh(IVxSurfExtractReq ireq)
    {
        SurfExtractReqMC req  = ireq as SurfExtractReqMC;
        VFVoxelChunkGo   vfGo = VFVoxelChunkGo.CreateChunkGo(req, _waterMat, s_layer);

        if (vfGo != null)
        {
            vfGo.transform.parent = gameObject.transform;
        }
        req._chunk.AttachChunkGo(vfGo, req);
    }
    public bool OnReqFinished()
    {
        bool ret = false;

        if (!IsInvalid)
        {
            VFVoxelChunkGo go = _chunkData.ChunkGo;
            if (go != null && !go.Equals(null))
            {
                go.SetTransGo(this, _faceMask);
                ret = true;
            }
        }
        return(ret);
    }
 public void DestroyChunkGO()
 {
     if (null != (System.Object)_goChunk)            // In thread, Monobehaviour's compare can not be used
     {
         if (_node == null)
         {
             VFGoPool <VFVoxelChunkGo> .FreeGo(_goChunk);                                            // for those cases not in thread
         }
         else
         {
             VFGoPool <VFVoxelChunkGo> .ReqFreeGo(_goChunk);                                         // for those cases in thread use lock
         }
         _goChunk = null;
     }
 }
    public void OnRecycle()
    {
        gameObject.SetActive(false);
        if (IsOriginalGo)
        {
            Mr.enabled = true;
        }
        else if (_bPrimal)
        {
            if (Mc.sharedMesh != null)
            {
                OnColliderDestroy();
            }
        }

        //Note: Directly mesh.Clear() will cause rebuilding MeshCollider which cause spike;
        //		Destroy do not destroy it until the end of this frame, which cause FillMesh may fill the willDestroy mesh
        //      So use DestroyImmediate instead.
        //DestroyImmediate(_mf.sharedMesh, true);
        Mc.sharedMesh = null;
        Mf.sharedMesh.Clear();
        _terType = int.MinValue;
        _bPrimal = false;
        Data     = null;
        if (OriginalChunkGo != null)
        {
            Debug.LogError("[VFChunkGo]Free original chunk go" + OriginalChunkGo.name);
            VFGoPool <VFVoxelChunkGo> .FreeGo(OriginalChunkGo);

            OriginalChunkGo = null;
        }
        if (TransvoxelGo != null)
        {
            VFGoPool <VFTransVoxelGo> .FreeGo(TransvoxelGo);

            TransvoxelGo = null;
        }
        // Reset to default
        Mr.sharedMaterial = DefMat;
        gameObject.layer  = DefLayer;
        transform.parent  = DefParent;
        for (int i = transform.childCount - 1; i >= 0; i--)
        {
            Transform child = transform.GetChild(i);
            VFGoPool <VFVoxelChunkGo> .FreeGo(child.GetComponent <VFVoxelChunkGo>());
        }
    }
    void OnChunkColliderCreated(VFVoxelChunkGo chunk)
    {
#if true // divide into 4 blocks(because astar_grid is y_ignored, so the upper_4 bounds are ignored)
        for (int i = 0; i < 4; i++)
        {
            Bounds  b   = new Bounds();
            Vector3 min = chunk.transform.position + _ofsParts[i];
            b.SetMinMax(min, min + _sizeParts);
            AddChunk(b);
        }
#else
        Vector3 min   = chunk.transform.position;
        Vector3 max   = chunk.transform.position + Vector3.one * VoxelTerrainConstants._numVoxelsPerAxis;
        Bounds  bound = new Bounds();
        bound.SetMinMax(min, max);
        AddChunk(bound);
#endif
    }
    public static VFVoxelChunkGo CreateChunkGo(IVxSurfExtractReq req, Material mat = null, int layer = 0)
    {
        if (req.FillMesh(null) == 0)
        {
            return(null);
        }

        VFVoxelChunkGo vfGo = VFGoPool <VFVoxelChunkGo> .GetGo();

        int nMesh = req.FillMesh(vfGo.Mf.sharedMesh);

        vfGo._bPrimal = true;
        if (mat != null)
        {
            vfGo.Mr.sharedMaterial = mat;
        }
        if (layer != 0)
        {
            vfGo.gameObject.layer = layer;
        }
        vfGo.gameObject.SetActive(true);

        while (nMesh > 0)
        {
            VFVoxelChunkGo subGo = VFGoPool <VFVoxelChunkGo> .GetGo();

            nMesh = req.FillMesh(subGo.Mf.sharedMesh);
            subGo.transform.parent        = vfGo.transform;
            subGo.transform.localScale    = Vector3.one;
            subGo.transform.localPosition = Vector3.zero;
            if (mat != null)
            {
                subGo.Mr.sharedMaterial = mat;
            }
            if (layer != 0)
            {
                subGo.gameObject.layer = layer;
            }
            subGo.gameObject.SetActive(true);
        }

        return(vfGo);
    }
    public void ClearAllTrans()
    {
        //VFVoxelChunkGo[] chunks = VFVoxelTerrain.self.transform.GetComponentsInChildren<VFVoxelChunkGo>();
        Transform terTransform = VFVoxelTerrain.self.transform;

        foreach (Transform trans in terTransform)
        {
            VFVoxelChunkGo chunkGo = trans.GetComponent <VFVoxelChunkGo>();
            if (chunkGo != null)
            {
                if (chunkGo.TransvoxelGo != null)
                {
                    VFGoPool <VFTransVoxelGo> .FreeGo(chunkGo.TransvoxelGo);

                    chunkGo.TransvoxelGo = null;
                }
            }
        }
    }
    public static void CreateTransvoxelGo(VFVoxelChunkGo chunkGo, int faceMask)
    {
        TransVertices verts          = new TransVertices();
        List <int>    indexedIndices = new List <int>();
        float         cellSize       = 0.01f;

        TransvoxelExtractor2.BuildTransitionCells(faceMask, chunkGo.Data, cellSize, verts, indexedIndices);
        Vector3[] vert;
        Vector2[] norm01;
        Vector2[] norm2t;
        int       chunkVertsCurCnt = UnindexedVertex(verts, indexedIndices, out vert, out norm01, out norm2t);

        SurfExtractReqTrans req = new SurfExtractReqTrans(0, null);

        req.vert   = vert;
        req.norm01 = norm01;
        req.norm2t = norm2t;
        req.indice = new int[chunkVertsCurCnt];
        Array.Copy(SurfExtractorsMan.s_indiceMax, req.indice, chunkVertsCurCnt);

        chunkGo.SetTransGo(req, faceMask);
    }
Beispiel #15
0
 void FixedUpdate()
 {
     if (LodMan != null && LodMan.Observer != null && _frameCnt != Time.frameCount && VFVoxelTerrain.bChunkColliderRebuilding)               //water is low prior
     {
         _frameCnt = Time.frameCount;
         Vector3 posCurrent = LodMan.Observer.position;
         int     cx         = ((int)posCurrent.x) >> VoxelTerrainConstants._shift;
         int     cy         = ((int)posCurrent.y) >> VoxelTerrainConstants._shift;
         int     cz         = ((int)posCurrent.z) >> VoxelTerrainConstants._shift;
         int     nOffset    = VFVoxelTerrain.OrderedOffsetList.Count;
         for (int n = 0; n < nOffset; n++)
         {
             IntVector3       vecOffset = VFVoxelTerrain.OrderedOffsetList[n];
             VFVoxelChunkData chunk     = _voxels.readChunk(vecOffset.x + cx, vecOffset.y + cy, vecOffset.z + cz);
             VFVoxelChunkGo   vfgo      = VFVoxelTerrain.GenOneCollider(chunk);
             if (null != vfgo)
             {
                 vfgo.OnColliderReady();
                 break;
             }
         }
     }
 }
 public bool PrepChunkList()
 {
     if (curStatus == ETransBuildStatus.Status_Idle)
     {
         transRebuildList.Clear();
         Transform parTrans = VFVoxelTerrain.self.transform;
         foreach (Transform trans in parTrans)
         {
             if (trans.gameObject.activeSelf)
             {
                 try{
                     VFVoxelChunkGo   chunkGo = trans.GetComponent <VFVoxelChunkGo>();
                     VFVoxelChunkData cdata   = chunkGo.Data;
                     transRebuildList.Add(cdata.ChunkPosLod, cdata);
                 }
                 catch {}                    // Delayed Destroy will cause Dictionary.Add's exception
             }
         }
         curStatus = ETransBuildStatus.Status_ToBuild;
         return(true);
     }
     return(false);
 }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        VFVoxelChunkGo script     = (VFVoxelChunkGo)target;
        bool           bApplyRead = EditorGUILayout.Toggle("ReadVoxel", script.bApplyRead);

        if (bApplyRead != script.bApplyRead)
        {
            script.bApplyRead = bApplyRead;
        }
        bool bApplyWrite = EditorGUILayout.Toggle("WriteVoxel", script.bApplyWrite);

        if (bApplyWrite != script.bApplyWrite)
        {
            script.bApplyWrite = bApplyWrite;
        }
        bool bGenTrans = EditorGUILayout.Toggle("GenTrans", script.bGenTrans);

        if (bGenTrans != script.bGenTrans)
        {
            script.bGenTrans = bGenTrans;
        }
    }
Beispiel #18
0
    void CheckTerrain()
    {
        Ray        ray = PeCamera.mouseRay;
        RaycastHit hitInfo;

        mOpCube.Enable = false;
        if (Physics.Raycast(ray, out hitInfo, 100f, 1 << Pathea.Layer.VFVoxelTerrain))
        {
            VFVoxelChunkGo chunk = hitInfo.collider.gameObject.GetComponent <VFVoxelChunkGo>();
            if (chunk != null)
            {
                mOpCube.Enable = true;
                IntVector3 basePos = new IntVector3();

                if (hitInfo.normal.x == 0 || hitInfo.point.x - (int)hitInfo.point.x > 0.5f)
                {
                    basePos.x = Mathf.RoundToInt(hitInfo.point.x);
                }
                else
                {
                    basePos.x = hitInfo.normal.x > 0 ? Mathf.CeilToInt(hitInfo.point.x) : Mathf.FloorToInt(hitInfo.point.x);
                }

                if (hitInfo.normal.y == 0 || hitInfo.point.y - (int)hitInfo.point.y > 0.5f)
                {
                    basePos.y = Mathf.RoundToInt(hitInfo.point.y);
                }
                else
                {
                    basePos.y = hitInfo.normal.y > 0 ? Mathf.CeilToInt(hitInfo.point.y) : Mathf.FloorToInt(hitInfo.point.y);
                }

                if (hitInfo.normal.z == 0 || hitInfo.point.z - (int)hitInfo.point.z > 0.5f)
                {
                    basePos.z = Mathf.RoundToInt(hitInfo.point.z);
                }
                else
                {
                    basePos.z = hitInfo.normal.z > 0 ? Mathf.CeilToInt(hitInfo.point.z) : Mathf.FloorToInt(hitInfo.point.z);
                }

                IntVector3 nearestPos = basePos;

                float minDis = 100f;

                VFVoxel voxel = VFVoxelTerrain.self.Voxels.SafeRead(basePos.x, basePos.y, basePos.z);

                if (voxel.Volume < 127)
                {
                    for (int i = -1; i <= 1; i++)
                    {
                        for (int j = -1; j <= 1; j++)
                        {
                            for (int k = -1; k <= 1; k++)
                            {
                                IntVector3 now = new IntVector3(basePos.x + i, basePos.y + j, basePos.z + k);
                                voxel = VFVoxelTerrain.self.Voxels.SafeRead(now.x, now.y, now.z);
                                if (voxel.Volume > 127)
                                {
                                    float nowDis = (now.ToVector3() - hitInfo.point).magnitude;
                                    if (minDis >= nowDis)
                                    {
                                        nearestPos = now;
                                        minDis     = nowDis;
                                    }
                                }
                            }
                        }
                    }
                }

                mOpCube.transform.position = nearestPos.ToVector3();
                voxel = VFVoxelTerrain.self.Voxels.SafeRead(nearestPos.x, nearestPos.y, nearestPos.z);

                mOpCube.Enable = Vector3.Distance(mSkillRunner.transform.position + Vector3.up, hitInfo.point) < 3f &&
                                 voxel.Volume > 0 &&
                                 mSkillRunner.GetComponent <Rigidbody>().velocity.sqrMagnitude < 9;
                if (mOpCube.Enable)
                {
                    mTarget = new VFTerrainTarget(hitInfo.point, nearestPos, ref voxel);
                }
            }
            else
            {
                mOpCube.Enable = false;
            }
        }
    }
Beispiel #19
0
    public void CastDamageSkill(Collider other)
    {
        if (emitRunner == null || other == null)
        {
            return;
        }

        VFVoxelChunkGo chunk      = other.GetComponent <VFVoxelChunkGo>();
        B45ChunkGo     buildChunk = other.GetComponent <B45ChunkGo>();

        if (chunk != null || null != buildChunk)
        {
            EffSkill skillData = EffSkill.s_tblEffSkills.Find(iterSkill1 => EffSkill.MatchId(iterSkill1, damageSkillID));
            if (skillData.m_scopeOfSkill != null)
            {
                RunEff(damageSkillID, null);
            }
            else
            {
                RunEff(damageSkillID, new DefaultPosTarget(transform.position));
            }
        }
        else
        {
            if (other != null)
            {
                int emitHarm = AiUtil.GetHarm(emitRunner.gameObject);
                if (GameConfig.IsMultiMode)
                {
                    SkillRunner obj = VCUtils.GetComponentOrOnParent <SkillRunner>(other.gameObject);
                    if (null == obj)
                    {
                        return;
                    }

                    int targetHarm = AiUtil.GetHarm(obj.gameObject);

                    if (AiHarmData.GetHarmValue(emitHarm, targetHarm) == 0)
                    {
                        return;
                    }
                }
                else
                {
                    int targetHarm = AiUtil.GetHarm(other.gameObject);

                    if (AiHarmData.GetHarmValue(emitHarm, targetHarm) == 0)
                    {
                        return;
                    }
                }
            }

            EffSkill data = EffSkill.s_tblEffSkills.Find(iterSkill1 => EffSkill.MatchId(iterSkill1, damageSkillID));

            if (data != null)
            {
                if (data.m_scopeOfSkill != null)
                {
                    RunEff(damageSkillID, null);
                }
                else
                {
                    SkillRunner runner = VCUtils.GetComponentOrOnParent <SkillRunner>(other.gameObject);
                    if (runner != null)
                    {
                        RunEff(damageSkillID, runner);
                    }
                }
            }
        }
    }