コード例 #1
0
        //-----------------------------------------------------------------------------------

        //-----------------------------------------------------------------------------------
        void calculateWorldBounds(bool includeSimMod)
        {
            float tileScale = TerrainGlobals.getTerrain().getTileScale();

            mWorldMin    = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min;
            mWorldMax    = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max;
            mWorldMin.Y -= 1.0f;
            mWorldMax.Y += 1.0f;
            mWorldMin.X  = (float)Math.Floor(mWorldMin.X);
            mWorldMin.Y  = (float)Math.Floor(mWorldMin.Y);
            mWorldMin.Z  = (float)Math.Floor(mWorldMin.Z);
            mWorldMax.X  = (float)Math.Ceiling(mWorldMax.X);
            mWorldMax.Y  = (float)Math.Ceiling(mWorldMax.Y);
            mWorldMax.Z  = (float)Math.Ceiling(mWorldMax.Z);

            if (includeSimMod)
            {
                //include any bounding boxes from objects we're including..
                BBoundingBox bb = SimGlobals.getSimMain().getBBoxForDecalObjects();
                bb.addPoint(mWorldMax);
                bb.addPoint(mWorldMin);
                mWorldMin.Y = bb.min.Y;
                mWorldMax.Y = bb.max.Y;
            }
            if (mWorldMin.X < 0)
            {
                mWorldMin.X = 0;
            }
            if (mWorldMin.Z < 0)
            {
                mWorldMin.Z = 0;
            }
        }
コード例 #2
0
        private BBoundingBox axisPlaneBox(int axis)
        {
            BBoundingBox bbox = new BBoundingBox();

            bbox.min.X = -0.1f;
            bbox.min.Y = -0.1f;
            bbox.min.Z = -0.1f;

            float hl = mRodLength / 3.0f;

            if (axis == 0) //X
            {
                bbox.max.X = hl;
                bbox.max.Y = hl;
                bbox.max.Z = 0.1f;
            }
            else if (axis == 1) //Y
            {
                bbox.max.X = mRodLength * 0.75f;
                bbox.max.Y = 0.1f;
                bbox.max.Z = mRodLength * 0.75f;
            }
            else if (axis == 2) //Z
            {
                bbox.max.X = 0.1f;
                bbox.max.Y = hl;
                bbox.max.Z = hl;
            }

            bbox.min *= mVisibleScale.Y;
            bbox.max *= mVisibleScale.Y;

            return(bbox);
        }
コード例 #3
0
        //selection testing
        private BBoundingBox axisRodBox(int axis)
        {
            BBoundingBox bbox = new BBoundingBox();

            bbox.min.X = -mRodWidth;
            bbox.min.Y = -mRodWidth;
            bbox.min.Z = -mRodWidth;

            if (axis == 0) //X
            {
                bbox.max.X = mRodLength + 0.7f;;
                bbox.max.Y = mRodWidth;
                bbox.max.Z = mRodWidth;
            }
            else if (axis == 1) //Y
            {
                bbox.max.X = mRodWidth;
                bbox.max.Y = mRodLength + 0.7f;;
                bbox.max.Z = mRodWidth;
            }
            else if (axis == 2) //Z
            {
                bbox.max.X = mRodWidth;
                bbox.max.Y = mRodWidth;
                bbox.max.Z = mRodLength + 0.7f;;
            }

            bbox.min *= mVisibleScale.Y;
            bbox.max *= mVisibleScale.Y;

            return(bbox);
        }
コード例 #4
0
        //world grid management
        static private void addLightToGrid(lightInstance light)
        {
            LocalLight   l  = light.mSimEditorObject;
            BBoundingBox bb = new BBoundingBox();

            bb.addPoint(l.mAABB.min);
            bb.addPoint(l.mAABB.max);
            bb.min += l.getPosition();
            bb.max += l.getPosition();

            //walk every world chunk, update our bounds, do intersections
            BBoundingBox worldAABB = new BBoundingBox();

            for (int x = 0; x < mWorldChunks.GetLength(0); x++)
            {
                for (int y = 0; y < mWorldChunks.GetLength(1); y++)
                {
                    worldAABB.max   = mWorldChunks[x, y].mQNPointer.getDesc().m_maxPostDeform;
                    worldAABB.min   = mWorldChunks[x, y].mQNPointer.getDesc().m_minPostDeform;
                    worldAABB.max.Y = 300;
                    worldAABB.min.Y = -300;

                    if (bb.intersect(worldAABB))
                    {
                        mWorldChunks[x, y].mLightsAffectingMe.Add(light);
                        light.mWorldChunksImAffecting.Add(mWorldChunks[x, y]);
                    }
                }
            }
        }
コード例 #5
0
        void findMaxsMinsRange(ref Vector3 max, ref Vector3 mid, ref Vector3 range)
        {
            BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB();

            max = bb.max;
            mid = bb.min;

            range = (max - mid) * 2.1f;

            mid   = range * 0.5f;
            mid.X = rangeCompact(mid.X);
            mid.Y = rangeCompact(mid.Y);
            mid.Z = rangeCompact(mid.Z);

            range = (mid * 2.1f);

            if (range.X == 0)
            {
                mid.X = 0; range.X = 1;
            }
            if (range.Y == 0)
            {
                mid.Y = 0; range.Y = 1;
            }
            if (range.Z == 0)
            {
                mid.Z = 0; range.Z = 1;
            }
        }
コード例 #6
0
        void calculateWorldBounds(ref Vector3 mWorldMin, ref Vector3 mWorldMax, ref BBoundingBox worldBounds, bool renderWorldObjects)
        {
            float tileScale = TerrainGlobals.getTerrain().getTileScale();

            mWorldMin    = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min; // -new Vector3(tileScale, tileScale, tileScale);
            mWorldMax    = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max; // +new Vector3(tileScale, tileScale, tileScale);
            mWorldMin.Y -= 1.0f;
            mWorldMax.Y += 1.0f;
            mWorldMin.X  = (float)Math.Floor(mWorldMin.X);
            mWorldMin.Y  = (float)Math.Floor(mWorldMin.Y);
            mWorldMin.Z  = (float)Math.Floor(mWorldMin.Z);
            mWorldMax.X  = (float)Math.Ceiling(mWorldMax.X);
            mWorldMax.Y  = (float)Math.Ceiling(mWorldMax.Y);
            mWorldMax.Z  = (float)Math.Ceiling(mWorldMax.Z);

            //CLM TEMPORARY!!!
            //if(renderWorldObjects)
            //{
            //   //include any bounding boxes from objects we're including..
            //   BBoundingBox bb = SimGlobals.getSimMain().getBBoxForAOObjects();
            //   bb.addPoint(mWorldMax);
            //   bb.addPoint(mWorldMin);


            //   mWorldMin.Y = bb.min.Y;
            //   mWorldMax.Y = bb.max.Y;
            //}

            worldBounds.min    = mWorldMin;
            worldBounds.min.Y -= 2;
            worldBounds.max    = mWorldMax;
            worldBounds.max.Y += 2;
        }
コード例 #7
0
        void computeViewToProj(ref Vector3 rayDir, BBoundingBox worldBounds, Matrix worldToView, out Matrix viewToProj,
                               int numXSegments, int numYSegments, int xSegment, int ySegment)
        {
            BBoundingBox viewBounds = new BBoundingBox();

            for (int i = 0; i < 8; i++)
            {
                Vector3 corner     = worldBounds.getCorner((BBoundingBox.eCornerIndex)i);
                Vector4 viewCorner = Vector3.Transform(corner, worldToView);

                viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z);
            }

            float minZ = viewBounds.min.Z; // *0.5f;
            float maxZ = viewBounds.max.Z; // *2;

            float distanceX = Math.Abs(viewBounds.max.X - viewBounds.min.X);
            float segSizeX  = distanceX / numXSegments;
            float distanceY = Math.Abs(viewBounds.max.Y - viewBounds.min.Y);
            float segSizeY  = distanceY / numYSegments;

            float minXSeg = viewBounds.min.X + (segSizeX * xSegment);
            float minYSeg = viewBounds.min.Y + (segSizeY * ySegment);

            viewToProj = Matrix.OrthoOffCenterLH(
                minXSeg, minXSeg + segSizeX,
                minYSeg, minYSeg + segSizeY,
                minZ, maxZ);
        }
コード例 #8
0
        float calcAdjustedMidValue(float inputMid)
        {
            BBoundingBox bb    = TerrainGlobals.getTerrain().getDisplacementBB();
            float        diff  = bb.max.Y - bb.min.Y;
            int          qDiff = (int)(diff / 100) * 2;

            float adjustedMid = qDiff / 10.0f;

            return(inputMid - adjustedMid);
        }
コード例 #9
0
        Vector3 calcAdjustedMidValue(Vector3 inputMid)
        {
            BBoundingBox bb    = TerrainGlobals.getTerrain().getDisplacementBB();
            Vector3      diff  = bb.max - bb.min;
            int          qDiff = (int)(diff.Y / 100) * 2;

            Vector3 adjustedMid = new Vector3(0, qDiff / 10.0f, 0);

            return(inputMid - adjustedMid);
        }
コード例 #10
0
        static public BBoundingBox giveMaxBBs()
        {
            BBoundingBox bb = new BBoundingBox();

            bb.empty();

            for (int i = 0; i < getNumSets(); i++)
            {
                bb.addPoint(mFoliageSets[i].mBBMin);
                bb.addPoint(mFoliageSets[i].mBBMax);
            }

            return(bb);
        }
コード例 #11
0
        private bool testPlanesIntersection(Vector3 r0, Vector3 rD)
        {
            mHitDist[0] = float.MaxValue;
            mHitDist[1] = float.MaxValue;
            mHitDist[2] = float.MaxValue;

            Vector3      tc    = Vector3.Empty;
            Vector3      tOrg  = r0 - mTranslation;
            BBoundingBox yxBox = axisPlaneBox(0);

            if (!BMathLib.ray3AABB(ref tc, ref mHitDist[0], ref tOrg, ref rD, ref yxBox.min, ref yxBox.max))
            {
                mHitDist[0] = float.MaxValue;
            }

            BBoundingBox zxBox = axisPlaneBox(1);

            if (!BMathLib.ray3AABB(ref tc, ref mHitDist[1], ref tOrg, ref rD, ref zxBox.min, ref zxBox.max))
            {
                mHitDist[1] = float.MaxValue;
            }

            BBoundingBox yzBox = axisPlaneBox(2);

            if (!BMathLib.ray3AABB(ref tc, ref mHitDist[2], ref tOrg, ref rD, ref yzBox.min, ref yzBox.max))
            {
                mHitDist[2] = float.MaxValue;
            }

            if (mHitDist[0] < mHitDist[1] && mHitDist[0] < mHitDist[2])
            {
                mXaxisSelected = mYaxisSelected = true;
            }
            else if (mHitDist[1] < mHitDist[0] && mHitDist[1] < mHitDist[2])
            {
                mXaxisSelected = mZaxisSelected = true;
            }
            else if (mHitDist[2] < mHitDist[1] && mHitDist[2] < mHitDist[0])
            {
                mZaxisSelected = mYaxisSelected = true;
            }

            return(mXaxisSelected | mYaxisSelected | mZaxisSelected);
        }
コード例 #12
0
        void findMaxsMinsRange(ref float max, ref float mid, ref float range)
        {
            BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB();

            max = bb.max.Y;
            mid = bb.min.Y;

            range = (max - mid) * 2.1f;

            mid = range * 0.5f;
            mid = rangeCompact(mid);

            range = (mid * 2.1f);

            if (range == 0)
            {
                mid = 0; range = 1;
            }
        }
コード例 #13
0
        void calculateWorldBounds(ref Vector3 mWorldMin, ref Vector3 mWorldMax, ref BBoundingBox worldBounds, bool renderWorldObjects)
        {
            float tileScale = TerrainGlobals.getTerrain().mTileScale;

            mWorldMin    = TerrainGlobals.getTerrain().mTerrainBBMin; // -new Vector3(tileScale, tileScale, tileScale);
            mWorldMax    = TerrainGlobals.getTerrain().mTerrainBBMax; // +new Vector3(tileScale, tileScale, tileScale);
            mWorldMin.Y -= 1.0f;
            mWorldMax.Y += 1.0f;
            mWorldMin.X  = (float)Math.Floor(mWorldMin.X);
            mWorldMin.Y  = (float)Math.Floor(mWorldMin.Y);
            mWorldMin.Z  = (float)Math.Floor(mWorldMin.Z);
            mWorldMax.X  = (float)Math.Ceiling(mWorldMax.X);
            mWorldMax.Y  = (float)Math.Ceiling(mWorldMax.Y);
            mWorldMax.Z  = (float)Math.Ceiling(mWorldMax.Z);

            worldBounds.min    = mWorldMin;
            worldBounds.min.Y -= 2;
            worldBounds.max    = mWorldMax;
            worldBounds.max.Y += 2;
        }
コード例 #14
0
        private bool testRodsIntersection(Vector3 r0, Vector3 rD)
        {
            Vector3 coord = Vector3.Empty;
            float   t     = 0;

            Vector3 tOrg = r0 - mTranslation;

            BBoundingBox xBox = axisRodBox(0);

            mXaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref xBox.min, ref xBox.max);

            BBoundingBox yBox = axisRodBox(1);

            mYaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref yBox.min, ref yBox.max);

            BBoundingBox zBox = axisRodBox(2);

            mZaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref zBox.min, ref zBox.max);

            return(mXaxisSelected | mYaxisSelected | mZaxisSelected);
        }
コード例 #15
0
        //--------------------------------------------------------------------------
        void computeTransforms(ref Vector3 rayDir, out Matrix worldToView, out Matrix viewToProj)
        {
            Vector3 mWorldMin = mScene.getWorldMin();
            Vector3 mWorldMax = mScene.getWorldMax();

            Vector3 eyePos   = new Vector3((mWorldMin.X + mWorldMax.X) * .5f, mWorldMax.Y + 50.0f, (mWorldMin.Z + mWorldMax.Z) * .5f);
            Vector3 focusPos = eyePos; focusPos.Y -= 1;
            Vector3 upDir    = BMathLib.unitZ;

            worldToView = Matrix.LookAtLH(eyePos, focusPos, upDir);

            BBoundingBox worldBounds = new BBoundingBox();

            worldBounds.min    = mWorldMin;
            worldBounds.min.Y -= 2;    //for depth peeling
            worldBounds.max    = mWorldMax;
            worldBounds.max.Y += 2;    //for depth peeling

            BBoundingBox viewBounds = new BBoundingBox();

            for (int i = 0; i < 8; i++)
            {
                Vector3 corner     = worldBounds.getCorner((BBoundingBox.eCornerIndex)i);
                Vector4 viewCorner = Vector3.Transform(corner, worldToView);

                viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z);
            }

            float minZ = viewBounds.min.Z;
            float maxZ = viewBounds.max.Z;

            float offsetX = 0.5f / (viewBounds.max.X - viewBounds.min.X);
            float offsetY = 0;// -0.5f / (viewBounds.max.Y - viewBounds.min.Y);

            viewToProj = Matrix.OrthoOffCenterLH(
                viewBounds.min.X + offsetX, viewBounds.max.X + offsetX,
                viewBounds.min.Y + offsetY, viewBounds.max.Y + offsetY,
                minZ, maxZ);
        }
コード例 #16
0
        //--------------------------------------------------------------------------
        void computeTransforms(Vector3 upDir, ref Matrix worldToView, ref Matrix viewToProj, ref BBoundingBox worldBounds, ref double worldMinY, ref double worldMaxY)
        {
            float   diameter    = Vector3.Length(mWorldMax - mWorldMin);
            float   radius      = diameter * 0.5f;
            Vector3 worldCenter = (mWorldMax - mWorldMin) * 0.5f;

            Vector3 eyePos   = worldCenter + (BMathLib.unitY * radius);
            Vector3 focusPos = worldCenter;

            worldToView = Matrix.LookAtLH(eyePos, focusPos, upDir);

            worldBounds.min = mWorldMin;
            //     worldBounds.min.Y -= 2;
            worldBounds.max = mWorldMax;
            //    worldBounds.max.Y += 2;
            //worldBounds.max.X += 1; //CLM WHAT?
            //worldBounds.max.Z += 1; //CLM WHAT?


            BBoundingBox viewBounds = new BBoundingBox();

            for (int i = 0; i < 8; i++)
            {
                Vector3 corner     = worldBounds.getCorner((BBoundingBox.eCornerIndex)i);
                Vector4 viewCorner = Vector3.Transform(corner, worldToView);
                viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z);
            }

            float minZ = viewBounds.min.Z; // *0.5f;
            float maxZ = viewBounds.max.Z; // *2;

            viewToProj = Matrix.OrthoOffCenterLH(
                viewBounds.min.X, viewBounds.max.X,
                viewBounds.min.Y, viewBounds.max.Y,
                minZ, maxZ);

            worldMinY = eyePos.Y + -minZ;
            worldMaxY = eyePos.Y + -maxZ;
        }
コード例 #17
0
        public override bool testIntersection()
        {
            if (mLocked)
            {
                return(true);
            }

            mXaxisSelected = mYaxisSelected = mZaxisSelected = false;

            //cast a ray
            //find what axis it's hitting..
            Point cursorPos = new Point();

            UIManager.GetCursorPos(ref cursorPos);
            Vector3 orig = BRenderDevice.getRayPosFromMouseCoords(false, cursorPos);
            Vector3 dir  = BRenderDevice.getRayPosFromMouseCoords(true, cursorPos) - orig;

            dir = BMathLib.Normalize(dir);

            //test intersection against our entire widget first
            BBoundingBox myBox = new BBoundingBox();

            myBox.min = mTranslation - (new Vector3(mRodWidth, mRodWidth, mRodWidth) * mVisibleScale.Y);
            myBox.max = mTranslation + (new Vector3(mRodLength + 0.5f, mRodLength + 0.5f, mRodLength + 0.5f) * mVisibleScale.Y);
            if (!myBox.intersect(orig, dir))
            {
                return(false);
            }

            //if we didn't hit a plane, check our boxes
            if (!testPlanesIntersection(orig, dir))
            {
                testRodsIntersection(orig, dir);
            }


            return(mXaxisSelected | mYaxisSelected | mZaxisSelected);
        }
コード例 #18
0
        public void updateBoundsFromChildren()
        {
            if (mChildren != null)
            {
                BBoundingBox aabb = new BBoundingBox();
                for (uint i = 0; i < (int)eQNKidEnum.cNumQuadTreeKids; i++)
                {
                    if (mChildren[i] == null)
                    {
                        continue;
                    }

                    mChildren[i].updateBoundsFromChildren();

                    float3 min = mChildren[i].getAABBMin();               aabb.addPoint(min.X, min.Y, min.Z);
                    min = mChildren[i].getAABBMax();               aabb.addPoint(min.X, min.Y, min.Z);
                }

                mAABBMin = new float3(aabb.min);
                mAABBMax = new float3(aabb.max);
                aabb     = null;
            }
        }
コード例 #19
0
        void recalculateCellBB(SpatialQuadTreeCell spatialCell)
        {
            BBoundingBox bb = new BBoundingBox();

            bb.empty();
            RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)spatialCell.mExternalData);

            for (uint i = (uint)cell.mMinXVert; i <= cell.mMinXVert + mNumXVertsPerCell; i++)
            {
                for (uint j = (uint)cell.mMinZVert; j <= cell.mMinZVert + mNumZVertsPerCell; j++)
                {
                    if (i >= mWidth || j >= mHeight)
                    {
                        continue;
                    }

                    float3 worldPos = getWorldspacePoint((int)i, (int)j);
                    bb.addPoint(worldPos.toVec3());
                }
            }
            spatialCell.setBounds(new float3(bb.min), new float3(bb.max));
            bb = null;
        }
コード例 #20
0
        private void generateGridChunks(ref XTDVisualHeader header)
        {
            //Create and write our flat terrain quadnode chunks

            BTerrainQuadNode[] mLeafNodes = TerrainGlobals.getTerrain().getQuadNodeLeafArray();


            for (int i = 0; i < mLeafNodes.Length; i++)
            {
                int width = (int)BTerrainQuadNode.getMaxNodeWidth();
                ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
                chunkHolder.mDataMemStream = new MemoryStream();
                BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

                XTDTerrainChunk gridNode = new XTDTerrainChunk();

                int locX = mLeafNodes[i].getDesc().mMinXVert / width;
                int locZ = mLeafNodes[i].getDesc().mMinZVert / width;

                gridNode.gridLocX = locX;
                gridNode.gridLocZ = locZ;


                //calculate our chunk data

                gridNode.heightmapOnly = false;
                gridNode.maxVertStride = 64;


                //lets get our verts, normals, and ambOcclu

                int mnX = locX * width;
                int mnZ = locZ * width;

                BBoundingBox bb = new BBoundingBox();
                bb.empty();


                for (int z = 0; z < width + 1; z++)
                {
                    for (int x = 0; x < width + 1; x++)
                    {
                        int xVal = (int)(mnX + x);
                        int zVal = (int)(mnZ + z);

                        Vector3 v = TerrainGlobals.getTerrain().getPos(xVal, zVal);

                        bb.addPoint(v);
                    }
                }

                gridNode.mMin = bb.min;
                gridNode.mMax = bb.max;

                //IF WE CONTAIN FOLIAGE! increase the size of our bounding boxes..
                if (FoliageManager.isChunkUsed(mLeafNodes[i]))
                {
                    BBoundingBox bbA = FoliageManager.giveMaxBBs();

                    gridNode.mMin += bbA.min;
                    gridNode.mMax += bbA.max;
                }



                //expand our box a tad
                float scle = TerrainGlobals.getTerrain().getTileScale();
                gridNode.mMin -= new Vector3(scle, scle, scle);
                gridNode.mMax += new Vector3(scle, scle, scle);

                //send the verts off to the compressor to be compressed properly into an image (using whatever technique)
                //be sure to assign a corolary ID so we can reference it later.
                writeChunk(gridNode, binWriter);

                //add this chunk to our main data stream
                ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_TerrainChunk, chunkHolder, binWriter.BaseStream.Length);
                binWriter.Close();
                binWriter = null;
                chunkHolder.Close();
                chunkHolder = null;
            }

            mLeafNodes = null;
        }
コード例 #21
0
        public bool export_XTD(string filename, ExportSettings expSettings, ref ExportResults results)
        {
            DateTime start = DateTime.Now;

            //write the header for the entire XTD file
            XTDVisualHeader header = new XTDVisualHeader();

            header.version    = (int)eFileVersions.cXTDVersion;
            header.numXVerts  = TerrainGlobals.getTerrain().getNumXVerts();
            header.numXChunks = (int)(TerrainGlobals.getTerrain().getNumXVerts() / BTerrainQuadNode.cMaxWidth);
            header.tileScale  = TerrainGlobals.getTerrain().getTileScale();

            BBoundingBox simRepBB  = SimGlobals.getSimMain().getBBoxForDecalObjects();
            Vector3      visRepMin = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min - new Vector3(0, header.tileScale, 0);
            Vector3      visRepMax = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max + new Vector3(0, header.tileScale, 0);

            if (!CoreGlobals.mbLoadTerrainVisRep)
            {
                visRepMin = simRepBB.min;
                visRepMax = simRepBB.max;
            }


            header.worldMin = visRepMin;
            header.worldMax = visRepMax;
            header.endianSwap();


            //write our header first.
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            binWriter.Write(ExportTo360.StructToByteArray(header));
            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_XTDHeader, chunkHolder, (int)chunkHolder.mDataMemStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            header.endianSwap();


            generateGridChunks(ref header);

            writeAtlasToMemory(ref results);

            writeAOData(ref results);

            writeAlpha(ref results);

            writeTessData(expSettings.RefineTerrain, expSettings.RefineEpsilon, expSettings.RefineMinorityBias, ref results);

            writeLightData(ref expSettings, ref results);

            bool exportOK = ExportTo360.safeECFFileWrite(filename, ".XTD");


            TimeSpan ts = DateTime.Now - start;

            results.totalTime = ts.TotalMinutes;

            return(exportOK);
        }
コード例 #22
0
        public void calcualteAO(eAOQuality quality, bool renderWorldObjects, ref float totalTime, ref float peelTime, ref float gatherTime,
                                int startSampleIndex, int endSampleIndex)
        {
            totalTime  = 0;
            peelTime   = 0;
            gatherTime = 0;

            DateTime n = DateTime.Now;


            //should we multithread?
            if (CoreGlobals.mProcessorInfo.NumLogicalProcessors > 1)
            {
                mUsingMultithreading            = true;
                AmbientOcclusion.IncrementCount = 0;
                AOIncrements = new int[TerrainGlobals.getTerrain().getNumXVerts() * TerrainGlobals.getTerrain().getNumZVerts()];
            }
            else
            {
                mUsingMultithreading = false;
            }



            int width  = 512;
            int height = 512;

            int numXSegments = 1;
            int numYSegments = 1;

            //special settings for Final mode
            if (quality == eAOQuality.cAO_Final)
            {
                numXSegments = 4; //what should these values really be?
                numYSegments = 4; // they should scale, so that huge terrain gets more segments..

                //   width = 1024;
                //  height = 1024;

                // mUsingMultithreading = false;
            }

            //clear any handles available so we can use them as we see fit!
            TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle();
            TerrainGlobals.getVisual().destroyAllHandles();
            TerrainGlobals.getVisual().setHandleGenMode(true);

            blackoutAO(); //so we can gather light data

            Vector3      mWorldMin   = Vector3.Empty;
            Vector3      mWorldMax   = Vector3.Empty;
            BBoundingBox worldBounds = new BBoundingBox();

            calculateWorldBounds(ref mWorldMin, ref mWorldMax, ref worldBounds, renderWorldObjects);


            mPeeler.init(width, height);

            Vector3 rayDir = -BMathLib.unitY;

            rayDir.Normalize();
            Matrix worldToView = Matrix.Identity;
            Matrix viewToProj  = Matrix.Identity;

            int numDesiredSamples = (int)Math.Sqrt((int)quality);

            int            startIndex = 0;
            int            endIndex   = numDesiredSamples;
            List <Vector3> rayDirs    = null;

            if (startSampleIndex != -1)
            {
                rayDirs    = giveStratifiedOnHemiSphere(0, numDesiredSamples, false);
                startIndex = startSampleIndex;
                endIndex   = Math.Min(endSampleIndex, rayDirs.Count);
            }
            else
            {
                rayDirs    = giveStratifiedOnHemiSphere(0, numDesiredSamples, true);
                startIndex = 0;
                endIndex   = rayDirs.Count;
            }

            float rcpNumSamples = 1.0f / (float)(rayDirs.Count);


            int numSamples = endIndex - startIndex;
            //begin our peel & gather process...
            bool ownBeginScene = !BRenderDevice.isInSceneRender();

            if (ownBeginScene)
            {
                BRenderDevice.getDevice().BeginScene();
            }
            for (int dc = startIndex; dc < endIndex; dc++)
            {
                //choose one
                rayDir = -rayDirs[dc];

                computeWorldToView(ref rayDir, ref mWorldMin, ref mWorldMax, out worldToView);
                for (int x = 0; x < numXSegments; x++)
                {
                    for (int y = 0; y < numYSegments; y++)
                    {
                        //calculate our lightspace projection matrix
                        computeViewToProj(ref rayDir, worldBounds, worldToView, out viewToProj,
                                          numXSegments, numYSegments, x, y);


                        //use worker threads..
                        gatherWorkerData wd = new gatherWorkerData(0, 0, TerrainGlobals.getTerrain().getNumXVerts(), TerrainGlobals.getTerrain().getNumZVerts(),
                                                                   width, height,
                                                                   rayDir,
                                                                   worldToView * viewToProj,
                                                                   rcpNumSamples);
                        mPeeler.mDepthArray = null;
                        mPeeler.mDepthArray = wd.fragList;



                        //create our depth layers
                        DateTime dpn = DateTime.Now;
                        mPeeler.depthPeel(ref rayDir, ref worldToView, ref viewToProj, renderWorldObjects);
                        TimeSpan dpts = DateTime.Now - dpn;
                        peelTime += (float)dpts.TotalMinutes;



                        //do final gathering (AO SPECIFIC)
                        if (mUsingMultithreading)
                        {
                            finalGatherMultiThreaded(wd);
                        }
                        else
                        {
                            DateTime fgn = DateTime.Now;
                            finalGatherSingleThreaded(wd);
                            TimeSpan fgts = DateTime.Now - fgn;
                            gatherTime += (float)fgts.TotalMinutes;
                        }
                        wd = null;
                        mPeeler.mDepthArray = null;
                    }
                }
            }



            if (ownBeginScene)
            {
                BRenderDevice.getDevice().EndScene();
            }
            mPeeler.destroy();
            TerrainGlobals.getVisual().setHandleGenMode(false);



            //if we're using multithreading, wait for all our worker threads to finish.
            if (mUsingMultithreading)
            {
                while (AmbientOcclusion.IncrementCount <= numSamples - 1)
                {
                    Thread.Sleep(1);
                }

                float[] AOVals = TerrainGlobals.getEditor().getAmbientOcclusionValues();
                for (int i = 0; i < AOIncrements.Length; i++)
                {
                    AOVals[i] = AOIncrements[i] * rcpNumSamples;
                }
            }



            TimeSpan ts = DateTime.Now - n;

            totalTime = (float)ts.TotalMinutes;
        }
コード例 #23
0
 public BRenderGrannyMesh()
 {
     mPrimitives = new List <BRenderPrimitive>();
     mBBox       = new BBoundingBox();
 }
コード例 #24
0
 //-----------------------------------------------------------------------------
 public void setModelBoundingBox(BBoundingBox box)
 {
     mModelBoundingBox        = box;
     mModelBoundingBoxMaxSize = mModelBoundingBox.getMaxSize();
 }
コード例 #25
0
        public void computeHeightField(uint width, uint height, bool includeSimMod, Vector3 upDir, uint cNumSamples)
        {
            copyTempD3DValues();
            TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle();
            TerrainGlobals.getVisual().destroyAllHandles();
            TerrainGlobals.getVisual().setHandleGenMode(true);
            GC.WaitForPendingFinalizers();

            ExportTo360.checkLoadRender();

            createTempTextures(width, height);

            calculateWorldBounds(includeSimMod);


            mHeightFieldAttributes = new BHeightFieldAttributes(width, height);

            Matrix       worldToView = Matrix.Identity;
            Matrix       viewToProj = Matrix.Identity;
            BBoundingBox worldBounds = new BBoundingBox();
            double       worldMinY = 0, worldMaxY = 0;

            computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY);

            Random rand = new Random();

            double minDepth = float.MaxValue;
            double maxDepth = float.MinValue;



            cNumSamples = (uint)BMathLib.Clamp(cNumSamples, 1, 32);

            for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++)
            {
                float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;
                float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;

                Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f);

                generateDepthBuffer(ref pHighDepthSurf, width, height, false, worldToView, viewToProj * projOfs, includeSimMod);
                generateDepthBuffer(ref pLowDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod);

                fillHeightFieldTexture(width, height, mHeightFieldAttributes, pLowDepths, pHighDepths, ref minDepth, ref maxDepth);
            }

            viewToProj = viewToProj * Matrix.Translation(0.0f, 0.0f, (float)(-minDepth)) * Matrix.Scaling(1.0f, 1.0f, (float)(1.0f / (maxDepth - minDepth)));
            double newWorldMinY = worldMinY + (worldMaxY - worldMinY) * minDepth;

            worldMaxY = worldMinY + (worldMaxY - worldMinY) * maxDepth;
            worldMinY = newWorldMinY;
            minDepth  = 0.0f;
            maxDepth  = 1.0f;

            mHeightFieldAttributes.mWidth  = width;
            mHeightFieldAttributes.mHeight = height;
            mHeightFieldAttributes.mBounds = worldBounds;

            mHeightFieldAttributes.mWorldMinY   = (float)worldMinY;
            mHeightFieldAttributes.mWorldMaxY   = (float)worldMaxY;
            mHeightFieldAttributes.mWorldRangeY = (float)(worldMaxY - worldMinY);


            float minZ = 0;
            float maxZ = 1;
            float x    = 0;
            float y    = 0;

            Matrix cMTProjToScreen = BMathLib.matrixFrom16floats(
                width * .5f, 0.0f, 0.0f, 0.0f,
                0.0f, height * -.5f, 0.0f, 0.0f,
                0.0f, 0.0f, maxZ - minZ, 0.0f,
                x + width * .5f, y + height * .5f, minZ, 1.0f);

            mHeightFieldAttributes.mWorldToNormZ = worldToView * viewToProj * cMTProjToScreen;


            Matrix screenToProj    = Matrix.Invert(cMTProjToScreen);
            Matrix projToView      = Matrix.Invert(viewToProj);
            Matrix cMTScreenToView = Matrix.Multiply(screenToProj, projToView);

            mHeightFieldAttributes.mNormZToWorld = cMTScreenToView * Matrix.Invert(worldToView);

            releaseTempTextures();
            restoreTempD3DValues();
            TerrainGlobals.getVisual().setHandleGenMode(false);
            ExportTo360.checkUnloadRender();

            //copy our pixels from the previous point
            {
                for (int q = 0; q < width; q++)
                {
                    mHeightFieldAttributes.mpTexelsLO[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsLO[(width - 2) * width + q];
                    mHeightFieldAttributes.mpTexelsLO[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsLO[q * width + (width - 2)];
                    mHeightFieldAttributes.mpTexelsLO[q]         = mHeightFieldAttributes.mpTexelsLO[width + q];
                    mHeightFieldAttributes.mpTexelsLO[q * width] = mHeightFieldAttributes.mpTexelsLO[q * width + (1)];

                    mHeightFieldAttributes.mpTexelsHI[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsHI[(width - 2) * width + q];
                    mHeightFieldAttributes.mpTexelsHI[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsHI[q * width + (width - 2)];
                    mHeightFieldAttributes.mpTexelsHI[q]         = mHeightFieldAttributes.mpTexelsHI[width + q];
                    mHeightFieldAttributes.mpTexelsHI[q * width] = mHeightFieldAttributes.mpTexelsHI[q * width + (1)];
                }
            }

            #region dumpHeightfiled
            //{
            //   FileStream s = File.Open(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\out.raw", FileMode.OpenOrCreate, FileAccess.Write);
            //   BinaryWriter f = new BinaryWriter(s);
            //   for (int i = 0; i < width * height; i++)
            //   {
            //      f.Write(mHeightFieldAttributes.mpTexelsLO[i]);
            //      f.Write(mHeightFieldAttributes.mpTexelsHI[i]);
            //   }
            //   f.Close();
            //   s.Close();
            //}

            #endregion
        }
コード例 #26
0
        //-----------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------

        public void computeHeightFieldDirectFloat(uint width, uint height, bool includeSimMod, Vector3 upDir, bool onlyDoOneSample, ref float[] output)
        {
            copyTempD3DValues();
            TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle();
            TerrainGlobals.getVisual().destroyAllHandles();
            TerrainGlobals.getVisual().setHandleGenMode(true);
            GC.WaitForPendingFinalizers();

            ExportTo360.checkLoadRender();

            createTempTextures(width, height);

            calculateWorldBounds(includeSimMod);


            mHeightFieldAttributes = new BHeightFieldAttributes(width, height);

            Matrix       worldToView = Matrix.Identity;
            Matrix       viewToProj = Matrix.Identity;
            BBoundingBox worldBounds = new BBoundingBox();
            double       worldMinY = 0, worldMaxY = 0;

            computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY);

            float mWorldRangeY = (float)(mWorldMax.Y - mWorldMin.Y);

            uint numVals = width * height;

            if (output == null || output.Length != numVals)
            {
                output = new float[numVals];
                for (uint i = 0; i < numVals; i++)
                {
                    output[i] = float.MinValue;
                }
            }

            uint   cNumSamples = (uint)(onlyDoOneSample?1:4);
            Random rand        = new Random();

            for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++)
            {
                float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;
                float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;

                Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f);

                generateHeightBuffer(ref pHighDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod);

                #region fill & lock

                //mWorldMin.Y += 1.0f;
                //mWorldMax.Y -= 1.0f;

                unsafe
                {
                    GraphicsStream texstreamHI = pHighDepths.LockRectangle(0, LockFlags.None);
                    float *        pSrcHigh    = (float *)texstreamHI.InternalDataPointer;

                    //copy the data out so we can screw with it.
                    for (uint c = 0; c < numVals; c++)
                    {
                        output[c] = (float)Math.Max(output[c], pSrcHigh[c]);
                    }
                    pHighDepths.UnlockRectangle(0);
                }
                //find the max & min depth for this slice


                #endregion
            }



            releaseTempTextures();
            restoreTempD3DValues();
            TerrainGlobals.getVisual().setHandleGenMode(false);
            ExportTo360.checkUnloadRender();


            //#region dumpHeightfiled
            //{
            //   FileStream s = File.Open("_outHiDirect.raw", FileMode.OpenOrCreate, FileAccess.Write);
            //   BinaryWriter f = new BinaryWriter(s);
            //   for (int i = 0; i < width * height; i++)
            //   {
            //      float kp = (output[i] - mWorldMin.Y) / mWorldRangeY;
            //      ushort op = (ushort)(kp * ushort.MaxValue);
            //      f.Write(op);
            //   }
            //   f.Close();
            //   s.Close();
            //}

            //#endregion
        }
コード例 #27
0
        void writeTempModelsToZip(ZipArchive zip)
        {
            SceneObjectsXML sceneObjects = new SceneObjectsXML();

            BBoundingBox objectAABB = new BBoundingBox();

            objectAABB.empty();

            string baseDir = CoreGlobals.getWorkPaths().mGameDirectory;

            if (mIncludeObjects)
            {
                //searalize an XML file to memorystream holding position and model names

                List <EditorObject> editObjs = SimGlobals.getSimMain().getEditorObjects(false, SimMain.eFilterTypes.cFilterAll, -1, false);
                for (int objIdx = 0; objIdx < editObjs.Count; objIdx++)
                {
                    if (editObjs[objIdx] == null)
                    {
                        continue;
                    }

                    if (editObjs[objIdx].GetType() == typeof(SimObject))
                    {
                        SimObject obj = editObjs[objIdx] as SimObject;

                        if (obj.IgnoreToAO)
                        {
                            continue;
                        }


                        if (obj != null && obj.ProtoObject != null)
                        {
                            string grannyName = obj.ProtoObject.getGrannyFileName();
                            if (grannyName == "")
                            {
                                continue;
                            }

                            if (grannyName.Contains(baseDir))
                            {
                                grannyName = grannyName.Remove(0, baseDir.Length);
                            }

                            //if this GR2 isn't already listed, then list it.
                            if (!sceneObjects.objectGR2Names.Contains(grannyName))
                            {
                                sceneObjects.objectGR2Names.Add(grannyName);
                            }


                            //add our instance
                            ObjectInstanceXML inst = new ObjectInstanceXML();
                            inst.GR2Filename = grannyName;
                            inst.setOrientation(obj.getMatrix());
                            sceneObjects.objectinstances.Add(inst);


                            //add our transformed BB to the global BB list
                            if (obj != null && obj.mVisual != null)
                            {
                                if (!obj.IgnoreToAO)
                                {
                                    objectAABB.addPoint(obj.mAABB.max + obj.getPosition());
                                    objectAABB.addPoint(obj.mAABB.min + obj.getPosition());
                                }
                            }
                        }
                    }
                }

                sceneObjects.aabbmin = TextVectorHelper.ToString(objectAABB.min);
                sceneObjects.aabbmax = TextVectorHelper.ToString(objectAABB.max);
            }

            //write it to an XML stream
            AbstractFile  md     = zip.CreateFile("modelPositions.xml", true);
            Stream        stream = md.OpenWrite(true);
            XmlSerializer s      = new XmlSerializer(typeof(SceneObjectsXML), new Type[] { });

            s.Serialize(stream, sceneObjects);
            stream.Close();

            //Create a folder and copy our GR2s into it
            //AbstractFolder fold = zip.CreateFolder("models");

            //if (mIncludeObjects)
            //{
            //   for (int modelIdx = 0; modelIdx < sceneObjects.objectGR2Names.Count; modelIdx++)
            //   {
            //      if (mWorkerThread.CancellationPending)
            //         return;


            //      try
            //      {
            //         if (fullGR2Names[modelIdx] == "")
            //            continue;
            //         DiskFile modelFile = new DiskFile(fullGR2Names[modelIdx]);
            //         modelFile.CopyTo(fold, true);
            //      }
            //      catch (Exception e)
            //      {
            //         continue;
            //      }
            //   }
            //}
        }