예제 #1
0
        private void compactLayers(int bottomLayerIndex, int topLayerIndex)
        {
            int sze = (int)(BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight());

            //subtract from middle layers first
            BTerrainTexturingLayer topLayer = giveLayer(topLayerIndex);

            for (int i = bottomLayerIndex + 1; i < topLayerIndex; i++)
            {
                BTerrainTexturingLayer middleLayer = giveLayer(i);
                //  if (middleLayer.mLayerType != BTerrainTexturingLayer.eLayerType.cLayer_Splat)
                //     continue;

                for (int x = 0; x < sze; x++)
                {
                    middleLayer.mAlphaLayer[x] = (byte)(BMathLib.Clamp(middleLayer.mAlphaLayer[x] - topLayer.mAlphaLayer[x], 0, 255));
                }
            }

            //now add it to the bottom layer
            BTerrainTexturingLayer bottomLayer = giveLayer(bottomLayerIndex);

            for (int x = 0; x < sze; x++)
            {
                bottomLayer.mAlphaLayer[x] = (byte)(BMathLib.Clamp(bottomLayer.mAlphaLayer[x] + topLayer.mAlphaLayer[x], 0, 255));
            }


            //remove top layer
            removeLayer(topLayerIndex);
        }
예제 #2
0
 public void append(BTerrainLayerContainer target)
 {
     //let's just take the values here and add them to ourselves..
     for (int i = 0; i < target.getNumLayers(); i++)
     {
         BTerrainTexturingLayer lyr = new BTerrainTexturingLayer();
         target.mLayers[i].copyTo(lyr);
         mLayers.Add(lyr);
     }
 }
예제 #3
0
 public void copyTo(BTerrainTexturingLayer target)
 {
     target.mLayerType          = mLayerType;
     target.mActiveTextureIndex = mActiveTextureIndex;
     if (target.mAlphaLayer == null)
     {
         target.mAlphaLayer = new Byte[BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight()];
     }
     mAlphaLayer.CopyTo(target.mAlphaLayer, 0);
 }
예제 #4
0
 public void removeRedundantLayers()
 {
     for (int i = 0; i < getNumLayers(); i++)
     {
         BTerrainTexturingLayer topLayer = giveLayer(i);
         if (topLayer.mLayerType != BTerrainTexturingLayer.eLayerType.cLayer_Splat)
         {
             continue;
         }
         //find another layer with my same ID;
         int idToFind = topLayer.mActiveTextureIndex;
         for (int q = i + 1; q < getNumLayers(); q++)
         {
             if (giveLayer(q).mActiveTextureIndex == idToFind && giveLayer(q).mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat)
             {
                 compactLayers(i, q);
             }
         }
     }
 }
예제 #5
0
        unsafe static void valToLayerColumn(BTerrainLayerContainer layers, BTerrainTexturingLayer tLayer, int dIP, byte val, int layerIndex)
        {
            if (val == 0)
            {
                return;
            }

            if (TerrainGlobals.getEditor().mEraseTextureInstead)
            {
                //if i'm erasing, ignore layers above me and just get rid of my values..
                tLayer.mAlphaLayer[dIP] = (byte)(BMathLib.Clamp(tLayer.mAlphaLayer[dIP] - val, 0, 255));
            }
            else
            {
                if (layerIndex + 1 >= layers.getNumLayers())
                {
                    //no layers above me
                    tLayer.mAlphaLayer[dIP] = (byte)(BMathLib.Clamp(tLayer.mAlphaLayer[dIP] + val, 0, 255));
                }
                else
                {
                    float        maxByte = 0;
                    List <float> vList   = new List <float>();
                    for (int k = layerIndex + 1; k < layers.getNumLayers(); k++)
                    {
                        if (layers.giveLayer(k).mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat &&
                            layers.giveLayer(k).mAlphaLayer[dIP] != byte.MinValue)
                        {
                            float v = layers.giveLayer(k).mAlphaLayer[dIP];
                            vList.Add(v);
                            if (v > maxByte)
                            {
                                maxByte = v;
                            }
                        }
                    }

                    if (vList.Count == 0)
                    {
                        tLayer.mAlphaLayer[dIP] = (byte)(BMathLib.Clamp(tLayer.mAlphaLayer[dIP] + val, 0, 255));
                        return;
                    }

                    if (tLayer.mAlphaLayer[dIP] < maxByte)
                    {
                        tLayer.mAlphaLayer[dIP] = (byte)maxByte;
                    }



                    //normalize the contribs for everything above me
                    floatN vec = new floatN((uint)(vList.Count));
                    vec.set(vList);
                    vec = floatN.Normalize(vec);

                    byte hVal      = (byte)(val);
                    uint T         = 0;
                    int  remainder = 0;
                    for (int k = layerIndex + 1; k < layers.getNumLayers(); k++)
                    {
                        if (layers.giveLayer(k).mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat &&
                            layers.giveLayer(k).mAlphaLayer[dIP] != byte.MinValue)
                        {
                            float amt = vec[T++];
                            int   kQ  = layers.giveLayer(k).mAlphaLayer[dIP];
                            int   Del = (int)(((hVal * amt) + remainder));
                            int   R   = kQ - Del;

                            if (R < 0)
                            {
                                remainder = Del - kQ;
                                layers.giveLayer(k).mAlphaLayer[dIP] = 0;
                            }
                            else
                            {
                                layers.giveLayer(k).mAlphaLayer[dIP] = (byte)BMathLib.Clamp(R, 0, 255);
                                remainder = 0;
                            }
                        }
                    }
                    tLayer.mAlphaLayer[dIP] = (byte)(BMathLib.Clamp(tLayer.mAlphaLayer[dIP] + remainder + val, 0, 255));
                }
            }
        }
예제 #6
0
        unsafe static public bool setMaskAlphaToLayer(BTerrainQuadNode node, UInt32 *mskImg, uint mskImgWidth, uint mskImgHeight, float alphaScalar,
                                                      int terrainGridX, int terrainGridZ, char index)
        {
            bool  changed            = false;
            uint  dstImgWidth        = BTerrainTexturing.getAlphaTextureWidth();
            uint  dstImgHeight       = BTerrainTexturing.getAlphaTextureWidth();
            float vertsToPixelsRatio = BTerrainTexturing.getAlphaTextureWidth() / (float)BTerrainQuadNode.getMaxNodeWidth();


            int minxvert = node.getDesc().mMinXVert;
            int minzvert = node.getDesc().mMinZVert;
            int maxxvert = node.getDesc().mMaxXVert;
            int maxzvert = node.getDesc().mMaxZVert;

            BTerrainLayerContainer layers = node.mLayerContainer;
            int layerIndex = layers.giveLayerIndex(index, BTerrainTexturingLayer.eLayerType.cLayer_Splat);

            if (TerrainGlobals.getEditor().mEraseTextureInstead&& layerIndex == 0)
            {
                return(false);
            }

            //  layers.removeRedundantLayers();//CLM is this still needed?!??!

            if (layerIndex == -1)
            {
                if (TerrainGlobals.getEditor().mEraseTextureInstead) //we're erasing, and the texture doesn't exist..
                {
                    return(false);
                }

                //i don't exist yet.
                newSplatLayerEverywhere(index);
                layerIndex = layers.giveLayerIndex(index, BTerrainTexturingLayer.eLayerType.cLayer_Splat);
                BTerrainTexturingLayer tLayer = layers.giveLayer(layerIndex);

                for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                {
                    for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                    {
                        float curWeight = TerrainGlobals.getTerrain().getSoftSelectionWeight(terrainGridX, terrainGridZ);
                        if (!BMathLib.compare(curWeight, 0.0f))
                        {
                            int cX = (int)((x * vertsToPixelsRatio) + minxvert);
                            int cZ = (int)((z * vertsToPixelsRatio) + minzvert);

                            curWeight = BMathLib.Clamp(curWeight, 0, 1);


                            int dIP = x + ((int)BTerrainTexturing.getAlphaTextureHeight()) * z;

                            byte alphaMapVal = giveBrushAlphaValue(mskImg, mskImgWidth, mskImgHeight, minxvert, minzvert, maxxvert, maxzvert, cX, cZ, terrainGridX, terrainGridZ);

                            byte val = (byte)(alphaMapVal * alphaScalar * curWeight);
                            tLayer.mAlphaLayer[dIP] = val;
                        }
                    }
                }
                changed = true;
            }
            else
            {
                BTerrainTexturingLayer tLayer = layers.giveLayer(layerIndex);
                //this layer already exists.
                //If a pixel exists above me, subtract me from it, rather than adding to me.
                for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                {
                    for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                    {
                        //find the closest vert
                        int cX = (int)((x * vertsToPixelsRatio) + minxvert);
                        int cZ = (int)((z * vertsToPixelsRatio) + minzvert);

                        int dIP = x + ((int)BTerrainTexturing.getAlphaTextureHeight()) * z;

                        float curWeight = TerrainGlobals.getTerrain().getSoftSelectionWeight(terrainGridX, terrainGridZ);
                        if (!BMathLib.compare(curWeight, 0.0f))
                        {
                            changed   = true;
                            curWeight = BMathLib.Clamp(curWeight, 0, 1);


                            byte alphaMapVal = giveBrushAlphaValue(mskImg, mskImgWidth, mskImgHeight, minxvert, minzvert, maxxvert, maxzvert, cX, cZ, terrainGridX, terrainGridZ);

                            byte val = (byte)(alphaMapVal * alphaScalar * curWeight);

                            valToLayerColumn(layers, tLayer, dIP, val, layerIndex);
                        }
                    }
                }
            }

            layers.removeBlankLayers();

            return(changed);
        }
예제 #7
0
        //----------------------------------------------
        unsafe static public bool setIndexToMaskedArea(BTerrainQuadNode node, int minxvert, int minzvert, int maxxvert, int maxzvert, char index)
        {
            bool  changed            = false;
            uint  dstImgWidth        = BTerrainTexturing.getAlphaTextureWidth();
            uint  dstImgHeight       = BTerrainTexturing.getAlphaTextureWidth();
            float vertsToPixelsRatio = BTerrainTexturing.getAlphaTextureWidth() / (float)BTerrainQuadNode.getMaxNodeWidth();

            BTerrainLayerContainer layers = node.mLayerContainer;
            int layerIndex = layers.giveLayerIndex(index, BTerrainTexturingLayer.eLayerType.cLayer_Splat);

            if (TerrainGlobals.getEditor().mEraseTextureInstead&& layerIndex == 0)
            {
                return(false);
            }

            //layers.removeRedundantLayers();//CLM is this still needed?!??!

            if (layerIndex == -1)
            {
                if (TerrainGlobals.getEditor().mEraseTextureInstead) //we're erasing, and the texture doesn't exist..
                {
                    return(false);
                }

                //i don't exist yet.
                newSplatLayerEverywhere(index);
                layerIndex = layers.giveLayerIndex(index, BTerrainTexturingLayer.eLayerType.cLayer_Splat);
                BTerrainTexturingLayer tLayer = layers.giveLayer(layerIndex);

                for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                {
                    for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                    {
                        //find the closest vert
                        int cX = (int)((x * vertsToPixelsRatio) + minxvert);
                        int cZ = (int)((z * vertsToPixelsRatio) + minzvert);

                        int vertIndex = (int)(cX * TerrainGlobals.getTerrain().getNumZVerts() + cZ);

                        float curWeight = 1.0f;
                        if (Masking.isPointSelected(vertIndex, ref curWeight))
                        {
                            curWeight = BMathLib.Clamp(curWeight, 0, 1);


                            int dIP = x + ((int)BTerrainTexturing.getAlphaTextureHeight()) * z;

                            byte val = (byte)(curWeight * byte.MaxValue);
                            tLayer.mAlphaLayer[dIP] = val;
                        }
                    }
                }
                changed = true;
            }
            else
            {
                BTerrainTexturingLayer tLayer = layers.giveLayer(layerIndex);
                //this layer already exists.
                //If a pixel exists above me, subtract me from it, rather than adding to me.
                for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                {
                    for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                    {
                        //find the closest vert
                        int cX = (int)((x * vertsToPixelsRatio) + minxvert);
                        int cZ = (int)((z * vertsToPixelsRatio) + minzvert);

                        int vertIndex = (int)(cX * TerrainGlobals.getTerrain().getNumZVerts() + cZ);

                        float curWeight = 1.0f;
                        if (Masking.isPointSelected(vertIndex, ref curWeight))
                        {
                            changed = true;
                            int dIP = x + ((int)BTerrainTexturing.getAlphaTextureHeight()) * z;
                            curWeight = BMathLib.Clamp(curWeight, 0, 1);


                            byte val = (byte)(curWeight * byte.MaxValue);

                            valToLayerColumn(layers, tLayer, dIP, val, layerIndex);
                        }
                    }
                }
            }

            layers.removeBlankLayers();

            return(changed);
        }
예제 #8
0
        void fillCreateLayer(byte[] inputImg, int activeTexIndex, BTerrainTexturingLayer.eLayerType type, int minXTile, int minZTile, byte[] tempLargerImge, byte[] tempBorderedImg)
        {
            int width  = (int)BTerrainTexturing.getAlphaTextureWidth();
            int height = (int)BTerrainTexturing.getAlphaTextureHeight();

            int lw = width + 2;
            int lh = height + 2;

            //Create our texture first, border it, then resize it.
            //fill the origional texture into the new texture
            for (int q = 0; q < (width); q++)
            {
                for (int j = 0; j < (height); j++)
                {
                    tempLargerImge[(q + 1) + lw * (j + 1)] = inputImg[q + (width) * j];
                }
            }

            int numXNodes = (int)(TerrainGlobals.getTerrain().getNumXVerts() / BTerrainQuadNode.cMaxWidth);
            int rootXNode = (int)(minXTile / BTerrainQuadNode.cMaxWidth);
            int rootZNode = (int)(minZTile / BTerrainQuadNode.cMaxHeight);

            BTerrainQuadNode rootNode  = TerrainGlobals.getTerrain().getLeafNode(rootXNode, rootZNode);//TerrainGlobals.getTerrain().getQuadNodeRoot().getLeafNodeContainingTile(minXTile, minZTile);
            BTerrainQuadNode node      = null;
            int layerIndex             = 0;
            BTerrainTexturingLayer lyr = null;



            #region SIDES
            //grab neighbor alpha values, paste them into my edges.
            //LEFT SIDE FILL
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode - 1, rootZNode);// rootNode.getNeighborNode(-1, 0);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the RIGHT pixels
                    for (int i = 0; i < height; i++)
                    {
                        int srcIndex  = (width - 1) + width * i;
                        int destIndex = 0 + (lw * (i + 1));
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //extend the LEFT pixels
                for (int i = 0; i < height; i++)
                {
                    int srcIndex  = 0 + width * i;
                    int destIndex = 0 + (lw * (i + 1));
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }


            //RIGHT SIDE FILL
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode + 1, rootZNode);// rootNode.getNeighborNode(1, 0);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                lyr = node.mLayerContainer.giveLayer(layerIndex);
                //grab the LEFT pixels
                for (int i = 0; i < height; i++)
                {
                    int srcIndex  = 0 + width * i;
                    int destIndex = (lw - 1) + (lw * (i + 1));
                    tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                }
            }
            else
            {
                //extend the RIGHT pixels
                for (int i = 0; i < height; i++)
                {
                    int srcIndex  = (width - 1) + width * i;
                    int destIndex = (lw - 1) + (lw * (i + 1));
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }

            //TOP SIDE FILL
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode, rootZNode + 1);// rootNode.getNeighborNode(0, 1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the BOTTOM pixels
                    for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = i + width * 0;
                        int destIndex = (i + 1) + (lw * (lh - 1));
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //extend the TOP pixels
                for (int i = 0; i < width; i++)
                {
                    int srcIndex  = i + width * (height - 1);
                    int destIndex = (i + 1) + (lw * (lh - 1));
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }

            //BOTTOM SIDE FILL
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode, rootZNode - 1);// rootNode.getNeighborNode(0, -1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the TOP pixels
                    for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = i + width * (height - 1);
                        int destIndex = (i + 1) + (lw * 0);
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //extend the BOTTOM pixels
                for (int i = 0; i < width; i++)
                {
                    int srcIndex  = i + width * 0;
                    int destIndex = (i + 1) + (0);
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }
            #endregion

            #region CORNERS
            //TOP LEFT CORNER
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode - 1, rootZNode + 1);//rootNode.getNeighborNode(-1, 1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the BOTTOM RIGHT pixel
                    //for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = (width - 1) + width * 0;
                        int destIndex = 0 + (lw * (lh - 1));
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //grab the tpo+1, left+1 pixel
                //for (int i = 0; i < width; i++)
                {
                    int srcIndex  = 1 + width * (height - 2);
                    int destIndex = 0 + (lw * (lh - 1));
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }
            //TOP RIGHT CORNER
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode + 1, rootZNode + 1);//rootNode.getNeighborNode(1, 1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the BOTTOM LEFT pixel
                    //for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = 0;// +width * (height - 1);
                        int destIndex = (lw - 1) + (lw * (lh - 1));
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //grab the TOP+1 RIGHT+1 pixel
                //for (int i = 0; i < width; i++)
                {
                    int srcIndex  = (width - 2) + width * (height - 2);
                    int destIndex = (lw - 1) + (lw * (lh - 1));
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }
            //BOTTOM LEFT CORNER
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode - 1, rootZNode - 1);//rootNode.getNeighborNode(-1, -1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the TOP RIGHT pixel
                    //for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = (width - 1) + width * (height - 1);
                        int destIndex = 0 + (lw * 0);
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //grab the BOTTOM+1 LEFT+1 pixel
                //for (int i = 0; i < width; i++)
                {
                    int srcIndex  = 1 + width * 1;
                    int destIndex = 0 + (lw * 0);
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }
            //BOTTOM RIGHT CORNER
            node = TerrainGlobals.getTerrain().getLeafNode(rootXNode + 1, rootZNode - 1);//rootNode.getNeighborNode(1, -1);
            if ((node != null) &&
                ((layerIndex = node.mLayerContainer.giveLayerIndex(activeTexIndex, type)) != -1))
            {
                {
                    lyr = node.mLayerContainer.giveLayer(layerIndex);
                    //grab the TOP LEFT pixel
                    //for (int i = 0; i < width; i++)
                    {
                        int srcIndex  = (0) + width * (height - 1);
                        int destIndex = (lw - 1) + (lw * 0);
                        tempLargerImge[destIndex] = lyr.mAlphaLayer[srcIndex];
                    }
                }
            }
            else
            {
                //grab the BOTTOM+1 RIGHT+1 pixel
                //for (int i = 0; i < width; i++)
                {
                    int srcIndex  = (width - 2) + width * 1;
                    int destIndex = (lw - 1) + (lw * 0);
                    tempLargerImge[destIndex] = inputImg[srcIndex];
                }
            }

            #endregion

            ImageManipulation.resizeGreyScaleImg(tempLargerImge, tempBorderedImg, width + 2, height + 2, width, height, ImageManipulation.eFilterType.cFilter_Linear);
        }