public override bool Equals(object obj) { if (obj is LightVertice) { LightVertice other = (LightVertice)obj; return(v00 == other.v00 && v01 == other.v01 && v11 == other.v11 && v10 == other.v10); } return(false); }
//返回点的顺序要与传入点的顺序一致 public LightVertice GetBlockLightVertice(Section section, int x, int y, int z, Direction direction) { LightVertice lv = new LightVertice(); switch (direction) { case Direction.up: lv.v00 = GetBlockLightAverageValue(section, x, y + 1, z, x - 1, y + 1, z, x - 1, y + 1, z - 1, x, y + 1, z - 1); lv.v01 = GetBlockLightAverageValue(section, x, y + 1, z, x - 1, y + 1, z, x - 1, y + 1, z + 1, x, y + 1, z + 1); lv.v11 = GetBlockLightAverageValue(section, x, y + 1, z, x + 1, y + 1, z, x + 1, y + 1, z + 1, x, y + 1, z + 1); lv.v10 = GetBlockLightAverageValue(section, x, y + 1, z, x + 1, y + 1, z, x + 1, y + 1, z - 1, x, y + 1, z - 1); break; case Direction.down: lv.v00 = GetBlockLightAverageValue(section, x, y - 1, z, x - 1, y - 1, z, x - 1, y - 1, z - 1, x, y - 1, z - 1); lv.v01 = GetBlockLightAverageValue(section, x, y - 1, z, x - 1, y - 1, z, x - 1, y - 1, z + 1, x, y - 1, z + 1); lv.v11 = GetBlockLightAverageValue(section, x, y - 1, z, x + 1, y - 1, z, x + 1, y - 1, z + 1, x, y - 1, z + 1); lv.v10 = GetBlockLightAverageValue(section, x, y - 1, z, x + 1, y - 1, z, x + 1, y - 1, z - 1, x, y - 1, z - 1); break; case Direction.left: lv.v00 = GetBlockLightAverageValue(section, x - 1, y, z, x - 1, y - 1, z, x - 1, y - 1, z - 1, x - 1, y, z - 1); lv.v01 = GetBlockLightAverageValue(section, x - 1, y, z, x - 1, y + 1, z, x - 1, y + 1, z - 1, x - 1, y, z - 1); lv.v11 = GetBlockLightAverageValue(section, x - 1, y, z, x - 1, y + 1, z, x - 1, y + 1, z + 1, x - 1, y, z + 1); lv.v10 = GetBlockLightAverageValue(section, x - 1, y, z, x - 1, y - 1, z, x - 1, y - 1, z + 1, x - 1, y, z + 1); break; case Direction.right: lv.v00 = GetBlockLightAverageValue(section, x + 1, y, z, x + 1, y - 1, z, x + 1, y - 1, z - 1, x + 1, y, z - 1); lv.v01 = GetBlockLightAverageValue(section, x + 1, y, z, x + 1, y + 1, z, x + 1, y + 1, z - 1, x + 1, y, z - 1); lv.v11 = GetBlockLightAverageValue(section, x + 1, y, z, x + 1, y + 1, z, x + 1, y + 1, z + 1, x + 1, y, z + 1); lv.v10 = GetBlockLightAverageValue(section, x + 1, y, z, x + 1, y - 1, z, x + 1, y - 1, z + 1, x + 1, y, z + 1); break; case Direction.front: lv.v00 = GetBlockLightAverageValue(section, x, y, z + 1, x - 1, y, z + 1, x - 1, y - 1, z + 1, x, y - 1, z + 1); lv.v01 = GetBlockLightAverageValue(section, x, y, z + 1, x + 1, y, z + 1, x + 1, y - 1, z + 1, x, y - 1, z + 1); lv.v11 = GetBlockLightAverageValue(section, x, y, z + 1, x + 1, y, z + 1, x + 1, y + 1, z + 1, x, y + 1, z + 1); lv.v10 = GetBlockLightAverageValue(section, x, y, z + 1, x - 1, y, z + 1, x - 1, y + 1, z + 1, x, y + 1, z + 1); break; case Direction.back: lv.v00 = GetBlockLightAverageValue(section, x, y, z - 1, x - 1, y, z - 1, x - 1, y - 1, z - 1, x, y - 1, z - 1); lv.v01 = GetBlockLightAverageValue(section, x, y, z - 1, x + 1, y, z - 1, x + 1, y - 1, z - 1, x, y - 1, z - 1); lv.v11 = GetBlockLightAverageValue(section, x, y, z - 1, x + 1, y, z - 1, x + 1, y + 1, z - 1, x, y + 1, z - 1); lv.v10 = GetBlockLightAverageValue(section, x, y, z - 1, x - 1, y, z - 1, x - 1, y + 1, z - 1, x, y + 1, z - 1); break; } return(lv); }
public virtual void CalculateMesh(Chunk chunk, MeshData meshData, Block self, Direction renderDirection, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, LightVertice sunLight, LightVertice blockLight) { meshData.AddVertice(v1); meshData.AddVertice(v2); meshData.AddVertice(v3); meshData.AddVertice(v4); if ((int)renderDirection > 0) { meshData.AddQuadTriangles(true); } else { meshData.AddQuadTriangles(false); } AddRenderUV(meshData, self.ExtendId, renderDirection); meshData.AddColor(MeshBaseDataCache.Instance.GetColor(sunLight.v00, blockLight.v00, 0, 1)); meshData.AddColor(MeshBaseDataCache.Instance.GetColor(sunLight.v01, blockLight.v01, 0, 1)); meshData.AddColor(MeshBaseDataCache.Instance.GetColor(sunLight.v11, blockLight.v11, 0, 1)); meshData.AddColor(MeshBaseDataCache.Instance.GetColor(sunLight.v10, blockLight.v10, 0, 1)); }
public bool EqualOther(LightVertice other) { return(v00 == other.v00 && v01 == other.v01 && v11 == other.v11 && v10 == other.v10); }
public override void CalculateMesh(Chunk chunk, MeshData meshData, Block self, Direction renderDirection, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, LightVertice sunLight, LightVertice blockLight) { }
public void CalculateSectionMesh(Section section, MeshData meshData) { MeshCalculateWay way = GetCalculateWay(section); if (way == MeshCalculateWay.None) { return; } for (int d = 0; d < 3; d++) { int i, j, k, l, w, h, u = (d + 1) % 3, v = (d + 2) % 3; ClearIntArr(x); ClearIntArr(q); // int[] x = new int[]{0,0,0}; // int[] q = new int[]{0,0,0}; int direction = d + 1; q[d] = 1; if (way == MeshCalculateWay.Side) { x[d] = dims[d] - 1; } else { x[d] = 0; } for (; x[d] < dims[d];) { int n = 0; bool bBInRange = x[d] < dims[d] - 1; for (x[v] = 0; x[v] < dims[v]; x[v]++) { for (x[u] = 0; x[u] < dims[u]; x[u]++) { int x1 = x[0], y1 = x[1], z1 = x[2], x2 = x1 + q[0], y2 = y1 + q[1], z2 = z1 + q[2]; Block bA = (x[d] < 1 || way == MeshCalculateWay.Side) ? section.GetBlock(x1, y1, z1, true) : _prevBlocks[n]; BlockAttributeCalculator aBAC = BlockAttributeCalculatorFactory.GetCalculator(bA.BlockType); Block bB = section.GetBlock(x2, y2, z2, bBInRange); BlockAttributeCalculator bBAC = BlockAttributeCalculatorFactory.GetCalculator(bB.BlockType); CalculateRenderMesh(section.chunk, meshData, x1, y1 + section.chunkOffsetY, z1, x2, y2 + section.chunkOffsetY, z2, bA, bB, aBAC, bBAC, direction, bBInRange); RefreshRenderMask(_renderMask, _renderDirectionMask, _curRenderBlocks, _sunLightsMask, _blockLightsMask, n, section, x1, y1, z1, x2, y2, z2, bA, bB, aBAC, bBAC, bBInRange, direction); RefreshColliderMask(_faceMask, _colliderMask, n, bA, bB, aBAC, bBAC, direction); _prevBlocks[n] = bB; n++; } } x[d]++; // //贪心简化碰撞网格 // n = 0; // for (j = 0; j < dims[v]; j++) { // for (i = 0; i < dims[u];) { // bool c = _faceMask[n]; // MeshColliderType c1 = _colliderMask[n]; // if(c1 != MeshColliderType.none) // { // for (w = 1;i + w < dims[u] && c1 == _colliderMask[n + w] && c == _faceMask[n + w] ; w++); // bool done = false; // for (h = 1; j + h < dims[v]; h++) { // for (k = 0; k < w; k++) { // int doneIndex = n + k + h * dims[u]; // if(c1 != _colliderMask[doneIndex] || c != _faceMask[doneIndex]) // { // done = true; // break; // } // } // if(done)break; // } // // x[u] = i; x[v] = j; // ClearIntArr(du); // ClearIntArr(dv); //// int[] du = new int[]{0,0,0}; //// int[] dv = new int[]{0,0,0}; // du[u] = w; // dv[v] = h; // //因为shader的需求,这边不能-0.5 // AddFace(c,c1,meshData,MeshBaseDataCache.Instance.GetVector3(x[0],x[1] + section.chunkOffsetY,x[2]), // MeshBaseDataCache.Instance.GetVector3(x[0] + du[0],x[1] + du[1] + section.chunkOffsetY,x[2] + du[2]), // MeshBaseDataCache.Instance.GetVector3(x[0] + du[0] + dv[0],x[1] + du[1] + dv[1] + section.chunkOffsetY,x[2] + du[2] + dv[2]), // MeshBaseDataCache.Instance.GetVector3(x[0] + dv[0],x[1] + dv[1] + section.chunkOffsetY,x[2] + dv[2])); // for (l = 0; l < h; l++) { // for (k = 0; k < w; k++) { // int maskIndex = n + k + l * dims[u]; // _faceMask[maskIndex] = true; // _colliderMask[maskIndex] = MeshColliderType.none; // } // } // i+=w; // n+=w; // } // else // { // i++;n++; // } // } // } //贪心简化渲染网格 n = 0; for (j = 0; j < dims[v]; j++) { for (i = 0; i < dims[u];) { bool canRender = _renderMask[n]; Direction renderDirection = _renderDirectionMask[n]; Block curBlock = _curRenderBlocks[n]; BlockAttributeCalculator curCalculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType); LightVertice sunLight = _sunLightsMask[n]; LightVertice blockLight = _blockLightsMask[n]; if (canRender) { for (w = 1; i + w < dims[u] && _renderMask[n + w] && renderDirection == _renderDirectionMask[n + w] && curCalculator.CanCombineWithBlock(curBlock.ExtendId, _curRenderBlocks[n + w]) && sunLight.EqualOther(_sunLightsMask[n + w]) && blockLight.EqualOther(_blockLightsMask[n + w]); w++) { ; } bool done = false; for (h = 1; j + h < dims[v]; h++) { for (k = 0; k < w; k++) { int doneIndex = n + k + h * dims[u]; if (!_renderMask[doneIndex] || renderDirection != _renderDirectionMask[doneIndex] || !curCalculator.CanCombineWithBlock(curBlock.ExtendId, _curRenderBlocks[doneIndex]) || !sunLight.EqualOther(_sunLightsMask[doneIndex]) || !blockLight.EqualOther(_blockLightsMask[doneIndex])) { done = true; break; } } if (done) { break; } } x[u] = i; x[v] = j; ClearIntArr(du); ClearIntArr(dv); // int[] du = new int[]{0,0,0}; // int[] dv = new int[]{0,0,0}; du[u] = w; dv[v] = h; curCalculator.CalculateMesh(section.chunk, meshData, curBlock, renderDirection, MeshBaseDataCache.Instance.GetVector3(x[0], x[1] + section.chunkOffsetY, x[2]), MeshBaseDataCache.Instance.GetVector3(x[0] + du[0], x[1] + du[1] + section.chunkOffsetY, x[2] + du[2]), MeshBaseDataCache.Instance.GetVector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1] + section.chunkOffsetY, x[2] + du[2] + dv[2]), MeshBaseDataCache.Instance.GetVector3(x[0] + dv[0], x[1] + dv[1] + section.chunkOffsetY, x[2] + dv[2]), sunLight, blockLight); for (l = 0; l < h; l++) { for (k = 0; k < w; k++) { int maskIndex = n + k + l * dims[u]; _renderMask[maskIndex] = false; } } i += w; n += w; } else { i++; n++; } } } } } //计算boxcollider int nn = 0; for (int y = 0; y < dims[1]; y++) { for (int x = 0; x < dims[0]; x++) { for (int z = 0; z < dims[2]; z++) { Block block = section.GetBlock(x, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType); MeshColliderType colliderType = calculator.GetMeshColliderType(block.ExtendId); _terrainColliderMask[nn] = colliderType; nn++; } } } nn = 0; int dd; int ww; int hh; int kk; int ll; int mm; for (int y = 0; y < dims[1]; y++) { for (int x = 0; x < dims[0]; x++) { for (int z = 0; z < dims[2];) { MeshColliderType flag = _terrainColliderMask[nn]; if (flag != MeshColliderType.none) { for (dd = 1; z + dd < dims[2] && flag == _terrainColliderMask[nn + dd]; dd++) { ; } bool done = false; for (ww = 1; x + ww < dims[0]; ww++) { for (kk = 0; kk < dd; kk++) { int doneIndex = nn + kk + ww * dims[2]; if (flag != _terrainColliderMask[doneIndex]) { done = true; break; } } if (done) { break; } } done = false; for (hh = 1; y + hh < dims[1]; hh++) { for (ll = 0; ll < ww; ll++) { for (kk = 0; kk < dd; kk++) { int doneIndex = nn + kk + ll * dims[2] + hh * dims[0] * dims[2]; if (flag != _terrainColliderMask[doneIndex]) { done = true; break; } } if (done) { break; } } if (done) { break; } } Vector3 min = new Vector3(x, y, z); Vector3 max = new Vector3(x + ww, y + hh, z + dd); Vector3 center = (min + max) / 2; center.y += section.chunkOffsetY; Vector3 size = max - min; if (flag == MeshColliderType.terrainCollider) { meshData.terrainCollider.AddBox(center, size); } else { meshData.supportCollider.AddBox(center, size); } for (mm = 0; mm < hh; mm++) { for (ll = 0; ll < ww; ll++) { for (kk = 0; kk < dd; kk++) { int maskIndex = nn + kk + ll * dims[2] + mm * dims[0] * dims[2]; _terrainColliderMask[maskIndex] = MeshColliderType.none; } } } nn += dd; z += dd; } else { nn++; z++; } } } } }
public override void CalculateMesh(Chunk chunk, MeshData meshData, Block self, Direction renderDirection, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, LightVertice sunLight, LightVertice blockLight) { meshData.useTransparentTexture = true; meshData.useDoubleFace = true; base.CalculateMesh(chunk, meshData, self, renderDirection, v1, v2, v3, v4, sunLight, blockLight); meshData.useTransparentTexture = MeshData.DefaultUseTransparentTexture; meshData.useDoubleFace = MeshData.DefaultUseDoubleFace; }