예제 #1
0
    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);
            }
        }
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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;
    }
예제 #5
0
 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);
     }
 }
예제 #6
0
    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);
        }
    }
예제 #7
0
    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;
    }
예제 #8
0
    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);
    }
예제 #9
0
    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);
    }
예제 #10
0
    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);
    }
예제 #11
0
    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?");
            }
        }
    }
예제 #12
0
    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);
    }
예제 #13
0
    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);
            }
        }
    }
예제 #14
0
 public void removeNegativeSideFaceAtCoord(AlignedCoord alco)
 {
     removeBlockFaceAtCoord(alco, false, true);
 }
예제 #15
0
 public void removePositiveSideFaceAtCoord(AlignedCoord alco)
 {
     removeBlockFaceAtCoord(alco, true, false);
 }
예제 #16
0
 public void removeBothPositiveAndNegativeFacesAtCoord(AlignedCoord alco)
 {
     removeBlockFaceAtCoord(alco, true, true);
 }
예제 #17
0
 private int unshiftedIndexOfFaceSetAtCoord(AlignedCoord coord, Direction dir)
 {
     return(indexOfFaceSetAtCoord(coord, dir) + FaceAggregator.FACETABLE_LOOKUP_SHIFT);
 }
예제 #18
0
    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);
            }
        }
    }
예제 #19
0
 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));
 }
예제 #20
0
 public static PTwo PTwoFromAlignedCoord(AlignedCoord alco)
 {
     return(new PTwo(alco.across, alco.up));
 }
예제 #21
0
    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);
        }
    }
예제 #22
0
 public bool isIndexSafe(AlignedCoord arrayDims)
 {
     return(this.across >= 0 && this.up >= 0 && this.across < arrayDims.across && this.up < arrayDims.up);
 }
예제 #23
0
 public static Quad UnitQuadWithAlignedCoord(AlignedCoord alco)
 {
     return(new Quad(PTwo.PTwoFromAlignedCoord(alco), new PTwo(1, 1)));
 }