Ejemplo n.º 1
0
        public void ensureProperLayerOrdering()
        {
            ensureProperNumberLayers();
            int numSplatLayers = TerrainGlobals.getTexturing().getActiveTextureCount();

            //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;
            }

            //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].mAlphaContrib;
                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);

            //back solve to calculate new alpha value.
            vContribSorted[(uint)(numSplatLayers - 1)] = vContrib[(uint)(numSplatLayers - 1)];
            for (int k = (numSplatLayers - 2); k >= 0; 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].mAlphaContrib = (byte)(vContribSorted[(uint)mLayers[k].mActiveTextureIndex] * 255);
            }

            //ensure layers are sorted
            ensureProperSorting();
        }
Ejemplo n.º 2
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));
                }
            }
        }
Ejemplo n.º 3
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();
        }