コード例 #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 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);
 }
コード例 #3
0
        public void clearAllAlphasAtPixel(int x, int z)
        {
            if (x < 0 || z < 0 || x >= BTerrainTexturing.getAlphaTextureWidth() || z >= BTerrainTexturing.getAlphaTextureHeight())
            {
                return;
            }

            for (int i = mLayers.Count - 1; i >= 0; i--)
            {
                mLayers[i].mAlphaLayer[x + BTerrainTexturing.getAlphaTextureWidth() * z] = 0;
            }
        }
コード例 #4
0
        //------------------------------------------
        //called to create the mask form the texture
        public unsafe bool applyMask(BTerrainQuadNode node, int x, int z, bool alternate)
        {
            UInt32 *MskPtr = mStroke.getBits();

            mMskImgWidth  = (uint)mStroke.cBufferSize;
            mMskImgHeight = (uint)mStroke.cBufferSize;
            bool changed = Texturing_LayerEditor.setMaskAlphaToTextureBlending(node, BTerrainTexturing.getAlphaTextureWidth(), BTerrainTexturing.getAlphaTextureWidth(),
                                                                               MskPtr, mMskImgWidth, mMskImgHeight, mStroke.mAlphaValue,
                                                                               x, z, alternate);

            mStroke.unlockBits();

            return(changed);
        }
コード例 #5
0
        public void fullLayerAlpha(int layerIndex)
        {
            if (layerIndex < 0 || layerIndex >= mLayers.Count)
            {
                return;
            }

            for (int x = 0; x < (int)BTerrainTexturing.getAlphaTextureWidth(); x++)
            {
                for (int z = 0; z < (int)BTerrainTexturing.getAlphaTextureHeight(); z++)
                {
                    mLayers[layerIndex].mAlphaLayer[x + BTerrainTexturing.getAlphaTextureWidth() * z] = Byte.MaxValue;
                }
            }
        }
コード例 #6
0
        //Functions will effect Decal Only
        public int newDecalLayer(int activeDecalInstanceIndex)
        {
            if (mLayers.Count > 0 &&
                mLayers[mLayers.Count - 1].mActiveTextureIndex == activeDecalInstanceIndex &&
                mLayers[mLayers.Count - 1].mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Decal)
            {
                return(mLayers.Count - 1);
            }

            mLayers.Add(new BTerrainTexturingLayer());

            mLayers[mLayers.Count - 1].mLayerType          = BTerrainTexturingLayer.eLayerType.cLayer_Decal;
            mLayers[mLayers.Count - 1].mActiveTextureIndex = activeDecalInstanceIndex;
            mLayers[mLayers.Count - 1].mAlphaLayer         = new Byte[BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight()];


            fullLayerAlpha(mLayers.Count - 1);
            return(mLayers.Count - 1);
        }
コード例 #7
0
        public bool isLayerAllClear(int layerIndex)
        {
            if (layerIndex < 0 || layerIndex >= mLayers.Count)
            {
                return(false);
            }

            for (int x = 0; x < (int)BTerrainTexturing.getAlphaTextureWidth(); x++)
            {
                for (int z = 0; z < (int)BTerrainTexturing.getAlphaTextureHeight(); z++)
                {
                    if (mLayers[layerIndex].mAlphaLayer[x + BTerrainTexturing.getAlphaTextureWidth() * z] != 0)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #8
0
        public void removeHiddenLayers()
        {
            int sze = (int)(BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight());

            //remove layers below a fully opaque layer
            for (int i = 1; i < mLayers.Count; i++)
            {
                if (mLayers[i].mLayerType != BTerrainTexturingLayer.eLayerType.cLayer_Splat)
                {
                    continue;
                }

                if (isLayerAllSolid(i))
                {
                    removeLayersBelow(i);
                    i = 0;
                }
            }
        }
コード例 #9
0
        //used for clipart
        public BTerrainTextureVector giveLayerChainAtPixel(int x, int z)
        {
            BTerrainTextureVector v = new BTerrainTextureVector();

            if (x < 0 || z < 0 || x >= BTerrainTexturing.getAlphaTextureWidth() || z >= BTerrainTexturing.getAlphaTextureHeight())
            {
                return(v);
            }

            for (int i = 0; i < mLayers.Count; i++)
            {
                BTerrainPerVertexLayerData layer = new BTerrainPerVertexLayerData();
                layer.mActiveTextureIndex = mLayers[i].mActiveTextureIndex;
                layer.mLayerType          = mLayers[i].mLayerType;
                layer.mAlphaContrib       = mLayers[i].mAlphaLayer[x + BTerrainTexturing.getAlphaTextureWidth() * z];
                v.mLayers.Add(layer);
            }

            return(v);
        }
コード例 #10
0
        public int newSplatLayer(int activeTextureIndex, bool insertKeepOrdering)
        {
            if (mLayers.Count > 0 &&
                mLayers[mLayers.Count - 1].mActiveTextureIndex == activeTextureIndex &&
                mLayers[mLayers.Count - 1].mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat)
            {
                return(mLayers.Count - 1);
            }

            int addedIndex = -1;

            if (insertKeepOrdering)
            {
                for (int i = 0; i < mLayers.Count; i++)
                {
                    if (mLayers[i].mActiveTextureIndex > activeTextureIndex)
                    {
                        addedIndex = i;
                        break;
                    }
                }
            }


            if (addedIndex == -1)
            {
                mLayers.Add(new BTerrainTexturingLayer());
                addedIndex = mLayers.Count - 1;
            }
            else
            {
                mLayers.Insert(addedIndex, new BTerrainTexturingLayer());
            }

            mLayers[addedIndex].mLayerType          = BTerrainTexturingLayer.eLayerType.cLayer_Splat;
            mLayers[addedIndex].mActiveTextureIndex = activeTextureIndex;
            mLayers[addedIndex].mAlphaLayer         = new Byte[BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight()];


            return(addedIndex);
        }
コード例 #11
0
        private int giveLayerIDAtPixelInternal(int x, int y, int startingLayer, ref BTerrainTexturingLayer.eLayerType selectedLayerType)
        {
            if (startingLayer > mLayers.Count - 1)
            {
                startingLayer = mLayers.Count - 1;
            }

            if (startingLayer < 0)
            {
                selectedLayerType = BTerrainTexturingLayer.eLayerType.cLayer_Splat;
                return(0);
            }

            for (int i = startingLayer; i >= 0; i--)
            {
                if (mLayers[i].mAlphaLayer[x + BTerrainTexturing.getAlphaTextureWidth() * y] != 0)
                {
                    if (mLayers[i].mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat)
                    {
                        selectedLayerType = BTerrainTexturingLayer.eLayerType.cLayer_Splat;
                        return(mLayers[i].mActiveTextureIndex);
                    }
                    else
                    {
                        BTerrainDecalInstance dcli = TerrainGlobals.getTexturing().getActiveDecalInstance(mLayers[i].mActiveTextureIndex);
                        if (TerrainGlobals.getEditor().mVisTileIntetersectionX <= dcli.mTileBoundsMax.X && TerrainGlobals.getEditor().mVisTileIntetersectionX >= dcli.mTileBoundsMin.X &&
                            TerrainGlobals.getEditor().mVisTileIntetersectionZ <= dcli.mTileBoundsMax.Y && TerrainGlobals.getEditor().mVisTileIntetersectionZ >= dcli.mTileBoundsMin.Y)
                        {
                            selectedLayerType = BTerrainTexturingLayer.eLayerType.cLayer_Decal;
                            return(i);// dcli.mActiveDecalIndex;
                        }
                    }
                }
            }

            selectedLayerType = BTerrainTexturingLayer.eLayerType.cLayer_Splat;
            return(-1);
        }
コード例 #12
0
        public void flip(eFlipType type)
        {
            int width     = (int)(BTerrainTexturing.getAlphaTextureWidth());
            int workWidth = width - 1;

            for (int i = 0; i < mLayers.Count; i++)
            {
                if (type == eFlipType.eFlip_Horiz)
                {
                    byte[] tmpRef = (byte[])mLayers[i].mAlphaLayer.Clone();
                    for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                    {
                        for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                        {
                            int dstIndex = x + width * z;
                            int srcIndex = (workWidth - x) + width * z;

                            mLayers[i].mAlphaLayer[dstIndex] = tmpRef[srcIndex];
                        }
                    }
                }
                else if (type == eFlipType.eFlip_Vert)
                {
                    byte[] tmpRef = (byte[])mLayers[i].mAlphaLayer.Clone();
                    for (int x = 0; x < BTerrainTexturing.getAlphaTextureWidth(); x++)
                    {
                        for (int z = 0; z < BTerrainTexturing.getAlphaTextureWidth(); z++)
                        {
                            int dstIndex = x + width * z;
                            int srcIndex = x + width * (workWidth - z);

                            mLayers[i].mAlphaLayer[dstIndex] = tmpRef[srcIndex];
                        }
                    }
                }
            }
        }
コード例 #13
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);
        }
コード例 #14
0
        public void computeDecalLayerAlphaContrib(int layerIndex, int minXVertex, int minZVertex)
        {
            if (layerIndex < 0 || layerIndex >= mLayers.Count)
            {
                return;
            }

            //grab our decal instance
            if (mLayers[layerIndex].mLayerType != BTerrainTexturingLayer.eLayerType.cLayer_Decal)
            {
                return;
            }

            float vertsToHighResPixelSpaceRatio = BTerrainTexturing.getTextureWidth() / BTerrainQuadNode.cMaxWidth;

            BTerrainDecalInstance        dcli = TerrainGlobals.getTexturing().getActiveDecalInstance(mLayers[layerIndex].mActiveTextureIndex);
            BTerrainActiveDecalContainer dcl  = TerrainGlobals.getTexturing().getActiveDecal(dcli.mActiveDecalIndex);


            //scale, rotate, translate us
            int h  = dcl.mHeight;
            int w  = dcl.mWidth;
            int nW = (int)(w * ((1.0f / dcli.mUScale) / vertsToHighResPixelSpaceRatio));
            int nH = (int)(h * ((1.0f / dcli.mVScale) / vertsToHighResPixelSpaceRatio));
            int tW = 0;
            int tH = 0;

            byte[] tImgResized = null;
            byte[] tImgRotated = null;
            byte[] imgDat      = new byte[h * w];
            imgDat      = ImageManipulation.valueGreyScaleImg(imgDat, w, h, ImageManipulation.eValueOperation.cValue_Set, 255);
            tImgResized = ImageManipulation.resizeGreyScaleImg(imgDat, w, h, nW, nH, ImageManipulation.eFilterType.cFilter_Linear);
            tImgRotated = ImageManipulation.rotateGreyScaleImg(tImgResized, nW, nH, (float)(-dcli.mRotation * (180.0f / Math.PI)), false, out nW, out nH, ImageManipulation.eFilterType.cFilter_Nearest);

            byte[] tImg   = tImgRotated;
            int    startX = (int)((dcli.mTileCenter.X / vertsToHighResPixelSpaceRatio) - (nW >> 1) - minXVertex);
            int    startY = (int)((dcli.mTileCenter.Y / vertsToHighResPixelSpaceRatio) - (nH >> 1) - minZVertex);

            clearLayerAlpha(layerIndex);

            //copy back to masking
            for (int i = 0; i < nW; i++)
            {
                for (int j = 0; j < nH; j++)
                {
                    int iS = startX + i;
                    if (iS < 0 || iS >= BTerrainTexturing.getAlphaTextureWidth())
                    {
                        continue;
                    }

                    int jS = startY + j;
                    if (jS < 0 || jS >= BTerrainTexturing.getAlphaTextureHeight())
                    {
                        continue;
                    }

                    int srcIndex = j + i * nW;
                    int dstIndex = (int)(iS + BTerrainTexturing.getAlphaTextureHeight() * jS);

                    byte val = tImg[srcIndex];
                    mLayers[layerIndex].mAlphaLayer[dstIndex] = val;
                }
            }

            //also, walk any layers that exist above us, and subtract out their values as well
            for (int k = layerIndex + 1; k < mLayers.Count; k++)
            {
                if (mLayers[k].mLayerType == BTerrainTexturingLayer.eLayerType.cLayer_Splat)
                {
                    for (int i = 0; i < BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight(); i++)
                    {
                        mLayers[layerIndex].mAlphaLayer[i] = (byte)BMathLib.Clamp(mLayers[layerIndex].mAlphaLayer[i] - mLayers[k].mAlphaLayer[i], 0, 255);
                    }
                }
            }

            imgDat      = null;
            tImgResized = null;
            tImgRotated = null;
            tImg        = null;
        }
コード例 #15
0
        public void ensureProperLayerOrdering()
        {
            ensureProperNumberLayers();
            int numSplatLayers = TerrainGlobals.getTexturing().getActiveTextureCount();
            int aWidth         = (int)BTerrainTexturing.getAlphaTextureWidth();
            int aHeight        = (int)BTerrainTexturing.getAlphaTextureHeight();

            for (int y = 0; y < aHeight; y++)
            {
                for (int x = 0; x < aWidth; x++)
                {
                    int aIndex = x + aWidth * y;

                    //create N floatN vectors
                    floatN[] layerVecs = new floatN[numSplatLayers];
                    for (uint k = 0; k < numSplatLayers; k++)
                    {
                        layerVecs[k]    = new floatN((uint)numSplatLayers);
                        layerVecs[k][k] = 1;
                    }

                    //quick early out test to make sure we're not screwing up by re-normalizing..
                    floatN nVal = new floatN((uint)numSplatLayers);
                    for (uint k = 0; k < numSplatLayers; k++)
                    {
                        byte  b     = mLayers[(int)k].mAlphaLayer[aIndex];
                        float alpha = ((float)b) / 255.0f;
                        nVal[k] = alpha;
                    }
                    float len = nVal.Length();
                    if (len == 1.0f)
                    {
                        continue;
                    }


                    //now, calculate a VContrib vector for the current layering.
                    floatN vContrib = layerVecs[0].Clone();//start with 100% base layer
                    for (uint k = 1; k < numSplatLayers; k++)
                    {
                        byte  b     = mLayers[(int)k].mAlphaLayer[aIndex];
                        int   lIdx  = mLayers[(int)k].mActiveTextureIndex;
                        float alpha = ((float)b) / 255.0f;
                        vContrib = (
                            (layerVecs[lIdx] * alpha) + (vContrib * (1 - alpha))
                            );
                    }

                    //vContrib now holds at each vector element, the amount the layer is visible to the final pixel
                    //although it's not sorted in the current layer ordering
                    //so, calculate the xF for the new layer ordering, and store it in a temp var
                    floatN vContribSorted    = new floatN((uint)numSplatLayers);
                    floatN vContribSortedInv = new floatN((uint)numSplatLayers);

                    //back solve to calculate new alpha value.
                    vContribSorted[(uint)(numSplatLayers - 1)]    = vContrib[(uint)(numSplatLayers - 1)];
                    vContribSortedInv[(uint)(numSplatLayers - 1)] = 1 - vContribSorted[(uint)(numSplatLayers - 1)];
                    for (int k = (numSplatLayers - 2); k >= 0; k--)
                    {
                        //multiply the inversions together that we have so far.
                        float mulSoFar = 1;
                        for (uint q = (uint)k + 1; q < numSplatLayers; q++)
                        {
                            mulSoFar *= vContribSortedInv[q];
                        }


                        vContribSorted[(uint)k]    = mulSoFar == 0 ? 0 : vContrib[(uint)(k)] / mulSoFar;
                        vContribSortedInv[(uint)k] = 1 - vContribSorted[(uint)k];

                        //uint invK = (uint)((numSplatLayers - 2) - k);
                        //float Vc = vContrib[(uint)(k + 1)];   //vContrib for upper layer
                        //float invVc = 1.0f - Vc;

                        ////current layer vContrib
                        //float cVc = vContrib[(uint)(k)];
                        //float xF = invVc==0?0:(cVc / invVc);

                        ////move back
                        //vContribSorted[(uint)k] = xF;
                    }

                    //now copy back to the unsorted layer index
                    for (int k = 0; k < numSplatLayers; k++)
                    {
                        mLayers[k].mAlphaLayer[aIndex] = (byte)(vContribSorted[(uint)mLayers[k].mActiveTextureIndex] * 255);
                    }
                }
            }

            //ensure layers are sorted
            ensureProperSorting();
        }
コード例 #16
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);
        }
コード例 #17
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);
        }
コード例 #18
0
        public void toTextureArray(ref List <Texture> mTempAlphaTextures, int minXVert, int minZVert)
        {
            bool doBlendedFill = true;

            //lock in our alpha texture
            int slicePitch = (int)(BTerrainTexturing.getAlphaTextureWidth() * BTerrainTexturing.getAlphaTextureHeight());
            int count      = Math.Min(mTempAlphaTextures.Count, mLayers.Count);

            int width  = (int)BTerrainTexturing.getAlphaTextureWidth();
            int height = (int)BTerrainTexturing.getAlphaTextureHeight();

            byte[] tempLargerImg = new byte[(width + 2) * (height + 2)];
            byte[] bordered      = new byte[width * height];

            int i = 0;

            for (i = 0; i < count; i++)
            {
                if (mTempAlphaTextures[i] != null)
                {
                    GraphicsStream texstream = mTempAlphaTextures[i].LockRectangle(0, LockFlags.None);
                    if (i == 0)
                    {
                        for (int k = 0; k < slicePitch; k++)
                        {
                            texstream.WriteByte(255);
                        }
                    }
                    else
                    {
                        if (doBlendedFill)
                        {
                            fillCreateLayer(mLayers[i].mAlphaLayer, mLayers[i].mActiveTextureIndex, mLayers[i].mLayerType, minXVert, minZVert, tempLargerImg, bordered);
                            texstream.Write(bordered, 0, slicePitch);
                        }
                        else
                        {
                            texstream.Write(mLayers[i].mAlphaLayer, 0, slicePitch);
                        }
                    }

                    mTempAlphaTextures[i].UnlockRectangle(0);
                    texstream.Close();
                }
                else
                {
                }
            }

            //we've got more layers than we've preallocated
            if (mTempAlphaTextures.Count < mLayers.Count)
            {
                int diff = mLayers.Count - mTempAlphaTextures.Count;
                for (int k = 0; k < diff; k++)
                {
                    mTempAlphaTextures.Add(new Texture(BRenderDevice.getDevice(), (int)BTerrainTexturing.getAlphaTextureWidth(), (int)BTerrainTexturing.getAlphaTextureHeight(), 1, 0, Format.L8, Pool.Managed));

                    GraphicsStream texstream = mTempAlphaTextures[mTempAlphaTextures.Count - 1].LockRectangle(0, LockFlags.None);
                    if (doBlendedFill)
                    {
                        fillCreateLayer(mLayers[i + k].mAlphaLayer, mLayers[i + k].mActiveTextureIndex, mLayers[i + k].mLayerType, minXVert, minZVert, tempLargerImg, bordered);
                        texstream.Write(bordered, 0, slicePitch);
                    }
                    else
                    {
                        texstream.Write(mLayers[i + k].mAlphaLayer, 0, slicePitch);
                    }

                    mTempAlphaTextures[mTempAlphaTextures.Count - 1].UnlockRectangle(0);
                    texstream.Close();
                }
            }

            tempLargerImg = null;
        }