private IEnumerable faceSetsAtAcrossIndexFlushWithRange(int acrossI, Range1D range, Direction dir) { int currentFSI = -1; for (int j = range.start; j < range.extent(); ++j) { if (j < 0) { continue; } if (j > faceSetTableHalfDims.t) { break; } AlignedCoord curAlco = new AlignedCoord(acrossI, j); int fsindex = indexOfFaceSetAtCoord(curAlco, dir); if (fsindex >= 0 && fsindex != currentFSI) { currentFSI = fsindex; yield return(fsindex); } } }
public void addFaceAtCoordBlockType(FaceInfo faceInfo) { // TODO: raise exception if this seems to be the wrong dir... AlignedCoord alco = alignedCoordFromCoord(faceInfo.coord); BlockType type = faceInfo.blockType; Direction dir = faceInfo.direction; if (alco.across != 0) { if (addCoordToFaceSetAtCoord(alco, alco.acrossMinusOne(), type, dir, faceInfo.lightLevel)) { return; } } if (alco.up != 0) { if (addCoordToFaceSetAtCoord(alco, alco.upMinusOne(), type, dir, faceInfo.lightLevel)) { return; } } // ok we need a new face set... newFaceSetAtCoord(alco, type, dir, faceInfo.lightLevel, faceInfo.lightDataProvider); }
private bool addCoordToFaceSetAtCoord(AlignedCoord addMeCoord, AlignedCoord adjacentCoord, BlockType type, Direction dir, byte lightLevel) { // if there is a face set here int faceSetIndex = indexOfFaceSetAtCoord(adjacentCoord, dir); if (indexRepresentsAnOccupiedCoord(faceSetIndex)) { FaceSet fset = faceSets[faceSetIndex]; // if it matches the type we want, add if (type == fset.blockType && fset.blockFaceDirection == dir) { //beyond limit for this face set? if (coordIsBeyondFaceSetMaxAllowArea(fset, addMeCoord)) { // b.bug("need a new faceset at coord: " + addMeCoord.toString() + "face set limits: " + fset.getFaceSetLimits().toString() + " direction: " + dir); return(false); } fset.addCoord(addMeCoord, lightLevel); //, adjacentCoord); copyFaceSetIndexFromToCoord(adjacentCoord, addMeCoord, dir); return(true); } } return(false); }
private void newFaceSetAtCoord(AlignedCoord coord, BlockType type, Direction dir, byte lightLevel, ILightDataProvider lightDataProvider) { //TODO: figure out what we should really to in this case. // maybe some kind of look up table re: which block type wins? int currentLookupIndex = indexOfFaceSetAtCoord(coord, dir); if (indexRepresentsAnOccupiedCoord(currentLookupIndex)) // { // remove // b.bug("represents an occupied coord: cur lookup index: " + currentLookupIndex + " direction: " + dir); FaceSet currentOccupantFaceSet = faceSets[currentLookupIndex]; currentOccupantFaceSet.removeFaceAtCoord(coord); // hang on to your hats! (no bugs please!) } // b.bug("adding a new face set at coord: " + coord.toString() ); int faceSetsCount = faceSets.Count; FaceSet fs = new FaceSet(type, dir, coord, lightLevel, lightDataProvider); faceSets.Add(fs); int nudge_lookup = ((int)dir % 2 == 0) ? 0 : 1; // pos dirs are 0, 2 and 4 faceSetTable[coord.across * 2 + nudge_lookup, coord.up] = faceSetsCount + FaceAggregator.FACETABLE_LOOKUP_SHIFT; }
private void editFaceAggregatorsAtCoordAndAxis(Coord co, Axis axis, AlignedCoord alco, Coord nudgeCoord, bool add_block, BlockType btype) { if (add_block) { this.addBlockAtCoordAndAxis(co, axis, alco, nudgeCoord, btype); } else { this.removeBlockAtCoordAndAxis(co, axis, alco, nudgeCoord, btype); } }
private void setIndexOfFaceSetAtCoord(int _index, AlignedCoord coord, Direction dir) { int nudge_lookup = ((int)dir % 2 == 0) ? 0 : 1; // pos dirs are 0, 2 and 4 try { faceSetTable[coord.across * 2 + nudge_lookup, coord.up] = _index; // - FaceAggregator.FACETABLE_LOOKUP_SHIFT; } catch (IndexOutOfRangeException e) { throw new Exception("this index was: across " + (coord.across * 2 + nudge_lookup) + " up: " + coord.up + ". face table length was: dim 0: " + faceSetTable.GetLength(0) + " 1 " + faceSetTable.GetLength(1) + " coord was " + coord.toString() + "Direction was: " + dir + " my face axis is: " + faceNormal); } }
private void copyFaceSetIndexFromToCoord(AlignedCoord fromC, AlignedCoord toC, Direction dirForBothCoords) { int indexFrom = indexOfFaceSetAtCoord(fromC, dirForBothCoords); //WE THINK WE SHOULD ADD THIS HERE.... int nudge_across = ((int)dirForBothCoords % 2 == 0) ? 0 : 1; faceSetTable[toC.across * 2 + nudge_across, toC.up] = indexFrom + FaceAggregator.FACETABLE_LOOKUP_SHIFT; //for some reason it was this way before.... // faceSetTable[toC.across , toC.up] = indexFrom + FaceAggregator.FACETABLE_LOOKUP_SHIFT; }
private FaceSet faceSetAt(AlignedCoord alco, Direction dir) { int index = indexOfFaceSetAtCoord(alco, dir); // bug ("got the index: " + index); if (index < 0) { return(null); } try { return(faceSets[index]); } catch (ArgumentOutOfRangeException e) { throw new Exception("index was out of range: index was: " + index + " aligned coord: " + alco.toString() + "direction: " + dir); } return(null); }
private void removeFaceSetAtCoord(AlignedCoord alco, Direction dir) { int index = indexOfFaceSetAtCoord(alco, dir); //NOTE: problems will/should arise if this face set has more than one face! // only remove < 1 face faceSet please! if (index < faceSets.Count) { faceSets.RemoveAt(index); } //TODO: decrement the faceSetTable for greater than index adjustLookupTableForRemovalOfIndex(index); //set the index in the table to zero setIndexOfFaceSetAtCoord(0, alco, dir); }
private MeshSet newMeshSetByRemovingBlockAtCoordDONTCALL(AlignedCoord alco, float verticalHeight) { throw new Exception("don't call this anymore"); int pos_vert_count_before = 0; int neg_vert_count_before = 0; int pos_vert_count_after = 0; int neg_v_count_after = 0; int pos_change = 0; int neg_change = 0; MeshSet mset = MeshSet.emptyMeshSet(); FaceSet posFaceSet = faceSetAt(alco, direction(true)); if (posFaceSet != null) { pos_vert_count_before = posFaceSet.vertexCount(); posFaceSet.removeFaceAtCoord(alco); pos_vert_count_after = posFaceSet.vertexCount(); } FaceSet negFaceSet = faceSetAt(alco, direction(false)); if (negFaceSet != null) { neg_vert_count_before = negFaceSet.vertexCount(); negFaceSet.removeFaceAtCoord(alco); neg_v_count_after = negFaceSet.vertexCount(); } // rebuild the all facesets (instead, for now of trying to splice the verts/i/uv arrays) mset = getFaceGeometry(verticalHeight); pos_change = pos_vert_count_after - pos_vert_count_before; neg_change = neg_v_count_after - neg_vert_count_before; mset.deltaVertexCount = pos_change + neg_change; return(mset); }
private void removeBlockFaceAtCoord(AlignedCoord alco, bool removePosFace, bool removeNegFace) { if (removePosFace) { FaceSet posFaceSet = faceSetAt(alco, direction(true)); if (posFaceSet != null) { posFaceSet.removeFaceAtCoord(alco); //now empty? if (posFaceSet.faceCount == 0) { removeFaceSetAtCoord(alco, direction(true)); } } else { throw new Exception("why? trying to remove a face set that was null already?"); } } if (removeNegFace) { FaceSet negFaceSet = faceSetAt(alco, direction(false)); if (negFaceSet != null) { negFaceSet.removeFaceAtCoord(alco); if (negFaceSet.faceCount == 0) { removeFaceSetAtCoord(alco, direction(false)); } } else { throw new Exception("why? trying to remove a face set that was null already?"); } } }
private static bool coordIsBeyondFaceSetMaxAllowArea(FaceSet fset, AlignedCoord alco) { Quad currentLimits = fset.getFaceSetLimits(); if (alco.across - currentLimits.origin.s >= FaceSet.MAX_DIMENSIONS.s) { return(true); } if (alco.up - currentLimits.origin.t >= FaceSet.MAX_DIMENSIONS.t) { return(true); } if (currentLimits.extentMinusOne().s - alco.across >= FaceSet.MAX_DIMENSIONS.s) { return(true); } if (currentLimits.extentMinusOne().t - alco.up >= FaceSet.MAX_DIMENSIONS.t) { return(true); } return(false); }
private void addNewFaceSetsWith(int acrossI, FaceInfo finfo) { Range1D addRange = finfo.range; Direction dir = finfo.direction; AlignedCoord startAlco = new AlignedCoord(acrossI, addRange.start); int fsIndex = indexOfFaceSetAtCoord(startAlco, dir); if (!indexRepresentsAnOccupiedCoord(fsIndex)) { newFaceSetAtCoord(startAlco, addRange.blockType, dir, 0, finfo.lightDataProvider); } // newFaceSetAtCoord(startAlco, addRange.blockType, dir, addRange.bottom_light_level, finfo.lightDataProvider); FaceSet justAddedFS = faceSetAt(startAlco, dir); Range1D usedRange = justAddedFS.addRangeAtAcrossReturnAddedRange(addRange, acrossI); int nowOccupiedFS = unshiftedIndexOfFaceSetAtCoord(startAlco, dir); AssertUtil.Assert(nowOccupiedFS > -1, "wha negative occupied coord? " + nowOccupiedFS); setIndicesOfFaceSetsAtRangeToIndex(usedRange, acrossI, dir, nowOccupiedFS); AssertUtil.Assert(addRange.subRangeBelowRange(usedRange).isErsatzNull(), "we thought there would be no range below. whoops"); Range1D unusedRangeAbove = addRange.subRangeAboveRange(usedRange); if (!unusedRangeAbove.isErsatzNull()) { if (unusedRangeAbove.range > 0) { finfo.range = unusedRangeAbove; addNewFaceSetsWith(acrossI, finfo); } } }
public void removeNegativeSideFaceAtCoord(AlignedCoord alco) { removeBlockFaceAtCoord(alco, false, true); }
public void removePositiveSideFaceAtCoord(AlignedCoord alco) { removeBlockFaceAtCoord(alco, true, false); }
public void removeBothPositiveAndNegativeFacesAtCoord(AlignedCoord alco) { removeBlockFaceAtCoord(alco, true, true); }
private int unshiftedIndexOfFaceSetAtCoord(AlignedCoord coord, Direction dir) { return(indexOfFaceSetAtCoord(coord, dir) + FaceAggregator.FACETABLE_LOOKUP_SHIFT); }
private void removeBlockAtCoordAndAxis(Coord co, Axis axis, AlignedCoord alco, Coord nudgeCoord, BlockType btype) { Block test_b; test_b = this.m_chunk.blockAt(new ChunkIndex(co - nudgeCoord)); //x_one int relevantComponent = Coord.SumOfComponents(co * nudgeCoord); int relevantUpperLimit = Coord.SumOfComponents(Chunk.DIMENSIONSINBLOCKS * nudgeCoord); Direction relevantPosDir = MeshBuilder.posDirectionForAxis(axis); FaceAggregator faXY = null; if (isFaceAggregatorAt(co, axis)) { faXY = faceAggregatorAt(co, relevantPosDir); } // *Neg direction neighbor block wasn't air? // *we need to add a face on its pos side if (test_b.type != BlockType.Air) { if (relevantComponent > 0) { FaceAggregator faXminusOne = faceAggregatorAt(co - nudgeCoord, relevantPosDir); // aggregatorArray[relevantComponent - 1]; // TODO: make sure this func is really 'add face if not exists.' faXminusOne.addFaceAtCoordBlockType(new FaceInfo(co, Block.MAX_LIGHT_LEVEL, relevantPosDir, test_b.type, this.m_chunk.lightDataProvider)); faXminusOne.getFaceGeometry(relevantComponent - 1); // CONSIDER: TRY REMOVING A FACE AT THIS FACE AGG AS WELL. EVEN THOUGH THERE 'SHOULDN'T' BE ONE. // AND SIMILAR FOR ADDING BLOCKS } } else // it is air at x (or whichever co) - 1 { if (faXY != null) { // * neighbor is an air block, so there should be a face to remove at our block in this direction faXY.removeNegativeSideFaceAtCoord(alco); if (faXY.faceSetCount == 0) { removeFaceAggregatorAt(co, axis); } else { faXY.getFaceGeometry(relevantComponent); } } } // x plus one test_b = this.m_chunk.blockAt(new ChunkIndex(co + nudgeCoord)); if (test_b.type != BlockType.Air) { if (relevantComponent < relevantUpperLimit - 1) { FaceAggregator faXplusone = faceAggregatorAt(co + nudgeCoord, relevantPosDir); // aggregatorArray[relevantComponent + 1]; faXplusone.addFaceAtCoordBlockType(new FaceInfo(co, Block.MAX_LIGHT_LEVEL, relevantPosDir + 1, test_b.type, this.m_chunk.lightDataProvider)); faXplusone.getFaceGeometry(relevantComponent + 1); } } else { if (faXY != null) { // * neighbor was air, so there should be a face to remove faXY.removePositiveSideFaceAtCoord(alco); if (faXY.faceSetCount == 0) { removeFaceAggregatorAt(co, axis); } else { faXY.getFaceGeometry(relevantComponent); } faXY.getFaceGeometry(relevantComponent); } } }
public static AlignedCoord LesserValues(AlignedCoord _aa, AlignedCoord _bb) { return(new AlignedCoord(_aa.across < _bb.across ? _aa.across : _bb.across, _aa.up < _bb.up ? _aa.up : _bb.up)); }
public static PTwo PTwoFromAlignedCoord(AlignedCoord alco) { return(new PTwo(alco.across, alco.up)); }
private void addBlockAtCoordAndAxis(Coord co, Axis axis, AlignedCoord alco, Coord nudgeCoord, BlockType btype) { Block neg_neighbor_block = this.m_chunk.blockAt(new ChunkIndex(co - nudgeCoord)); //x_one Block pos_neighbor_block = this.m_chunk.blockAt(new ChunkIndex(co + nudgeCoord)); int relevantComponent = Coord.SumOfComponents(co * nudgeCoord); int relevantUpperLimit = Coord.SumOfComponents(Chunk.DIMENSIONSINBLOCKS * nudgeCoord); Direction relevantPosDir = MeshBuilder.posDirectionForAxis(axis); FaceAggregator faXY = null; if (Block.BlockTypeIsATranslucentType(neg_neighbor_block.type) || Block.BlockTypeIsATranslucentType(pos_neighbor_block.type)) { faXY = faceAggregatorAt(co, relevantPosDir); // don't allocate if we won't have to... } //NEG NEIGHBOR if (!Block.BlockTypeIsATranslucentType(neg_neighbor_block.type)) // (neg_neighbor_block.type != BlockType.Air) { if (relevantComponent > 0) { // * neighbor not air, so there should be a face that is now hidden and that we should remove if (isFaceAggregatorAt(co - nudgeCoord, axis)) { FaceAggregator faXminusOne = faceAggregatorAt(co - nudgeCoord, relevantPosDir); // aggregatorArray[relevantComponent - 1]; faXminusOne.removePositiveSideFaceAtCoord(alco); // if faceSetCount now zero, remove faceAgg if (faXminusOne.faceSetCount == 0) { removeFaceAggregatorAt(co - nudgeCoord, axis); } else { // else get Face geom... faXminusOne.getFaceGeometry(relevantComponent - 1); } } } } else { // * neighbor is air, so we need to add a face at our coord faXY.addFaceAtCoordBlockType(new FaceInfo(co, Block.MAX_LIGHT_LEVEL, relevantPosDir + 1, btype, this.m_chunk.lightDataProvider)); faXY.getFaceGeometry(relevantComponent); } // POS NEIGHBOR // neighbor_block = this.m_chunk.blockAt(new ChunkIndex( co + nudgeCoord)); if (!Block.BlockTypeIsATranslucentType(pos_neighbor_block.type)) // (pos_neighbor_block.type != BlockType.Air) { if (relevantComponent < relevantUpperLimit - 1) { if (isFaceAggregatorAt(co + nudgeCoord, axis)) { // * neighbor not air, remove occluded face FaceAggregator faXplusone = faceAggregatorAt(co + nudgeCoord, relevantPosDir); // aggregatorArray[relevantComponent + 1]; faXplusone.removeNegativeSideFaceAtCoord(alco); //check if face agg now empty if (faXplusone.faceSetCount == 0) { removeFaceAggregatorAt(co + nudgeCoord, axis); } else { // else get Face geom... faXplusone.getFaceGeometry(relevantComponent + 1); } } } } else { // * neighbor is air, need to add a face at this coord faXY.addFaceAtCoordBlockType(new FaceInfo(co, Block.MAX_LIGHT_LEVEL, relevantPosDir, btype, this.m_chunk.lightDataProvider)); faXY.getFaceGeometry(relevantComponent); } }
public bool isIndexSafe(AlignedCoord arrayDims) { return(this.across >= 0 && this.up >= 0 && this.across < arrayDims.across && this.up < arrayDims.up); }
public static Quad UnitQuadWithAlignedCoord(AlignedCoord alco) { return(new Quad(PTwo.PTwoFromAlignedCoord(alco), new PTwo(1, 1))); }