当前位置: 首页>>代码示例>>C++>>正文


C++ ArrayT::PushBackEmpty方法代码示例

本文整理汇总了C++中ArrayT::PushBackEmpty方法的典型用法代码示例。如果您正苦于以下问题:C++ ArrayT::PushBackEmpty方法的具体用法?C++ ArrayT::PushBackEmpty怎么用?C++ ArrayT::PushBackEmpty使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ArrayT的用法示例。


在下文中一共展示了ArrayT::PushBackEmpty方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: GetFrameBuffer

uint32_t* SingleOpenGLWindowImplT::GetFrameBuffer(unsigned int& Width_, unsigned int& Height_)
{
    static ArrayT<uint32_t> FrameBuffer;

    FrameBuffer.Overwrite();
    FrameBuffer.PushBackEmpty(Width*Height);

    // Pixel vom BackBuffer in den FrameBuffer lesen.
    // Beachte: Die ersten beiden Parameter (0, 0) spezifizieren die linke UNTERE Ecke des gewünschten Bereichs!
    glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &FrameBuffer[0]);

    Width_ =Width;
    Height_=Height;

    // Wie oben schon erwähnt, steht der 'FrameBuffer' leider auf dem Kopf.
    // Vertausche daher alle Zeilen (vertikale Spiegelung).
    for (unsigned int y=0; y<Height_/2; y++)
    {
        uint32_t* UpperRow=&FrameBuffer[0]+         y   *Width_;
        uint32_t* LowerRow=&FrameBuffer[0]+(Height_-y-1)*Width_;

        for (unsigned int x=0; x<Width_; x++)
        {
            const uint32_t Swap=*UpperRow;

            *UpperRow=*LowerRow;
            *LowerRow=Swap;

            UpperRow++;
            LowerRow++;
        }
    }

    return &FrameBuffer[0];
}
开发者ID:mark711,项目名称:Cafu,代码行数:35,代码来源:OpenGLWindow.cpp

示例2: if

template<class T> ArrayT< Polygon3T<T> > Polygon3T<T>::GetSplits(const Plane3T<T>& SplitPlane, const T HalfPlaneThickness) const
{
    const unsigned long FRONT=0;
    const unsigned long BACK =1;

    ArrayT< Polygon3T<T> > Result;

    Result.PushBackEmpty(2);

    Result[FRONT].Plane=this->Plane;
    Result[BACK ].Plane=this->Plane;

    if (!Vertices.Size()) return Result;

    Vector3T<T> LastVertex=Vertices[Vertices.Size()-1];
    double      LastDist  =SplitPlane.GetDistance(LastVertex);

    for (unsigned long VertexNr=0; VertexNr<Vertices.Size(); VertexNr++)
    {
        const Vector3T<T>& ThisVertex=Vertices[VertexNr];
        const double       ThisDist  =SplitPlane.GetDistance(ThisVertex);

        if (ThisDist>HalfPlaneThickness)
        {
            if (LastDist<-HalfPlaneThickness)
            {
                Vector3T<T> Intersection=SplitPlane.GetIntersection(LastVertex, ThisVertex, 0);

                Result[BACK ].Vertices.PushBack(Intersection);
                Result[FRONT].Vertices.PushBack(Intersection);
            }
            else if (LastDist<=HalfPlaneThickness) Result[FRONT].Vertices.PushBack(LastVertex);

            Result[FRONT].Vertices.PushBack(ThisVertex);
        }
        else if (ThisDist<-HalfPlaneThickness)
        {
            if (LastDist>HalfPlaneThickness)
            {
                Vector3T<T> Intersection=SplitPlane.GetIntersection(LastVertex, ThisVertex, 0);

                Result[FRONT].Vertices.PushBack(Intersection);
                Result[BACK ].Vertices.PushBack(Intersection);
            }
            else if (LastDist>=-HalfPlaneThickness) Result[BACK].Vertices.PushBack(LastVertex);

            Result[BACK].Vertices.PushBack(ThisVertex);
        }
        else
        {
                 if (LastDist> HalfPlaneThickness) Result[FRONT].Vertices.PushBack(ThisVertex);
            else if (LastDist<-HalfPlaneThickness) Result[BACK ].Vertices.PushBack(ThisVertex);
        }

        LastVertex=ThisVertex;
        LastDist  =ThisDist;
    }

    return Result;
}
开发者ID:mark711,项目名称:Cafu,代码行数:60,代码来源:Polygon.cpp

示例3: CreateLeafPortals

void BspTreeBuilderT::CreateLeafPortals(unsigned long LeafNr, const ArrayT< Plane3T<double> >& NodeList)
{
    ArrayT<cf::SceneGraph::BspTreeNodeT::LeafT>& Leaves=BspTree->Leaves;

    Console->Print(cf::va("%5.1f%%\r", (double)LeafNr/Leaves.Size()*100.0));
    // fflush(stdout);      // The stdout console auto-flushes the output.

    const BoundingBox3T<double> LeafBB=Leaves[LeafNr].BB.GetEpsilonBox(MapT::RoundEpsilon);

    ArrayT< Polygon3T<double> > NewPortals;

    for (unsigned long Nr=0; Nr<NodeList.Size(); Nr++)
        if (LeafBB.WhatSide(NodeList[Nr])==BoundingBox3T<double>::Both)
        {
            NewPortals.PushBackEmpty();
            NewPortals[NewPortals.Size()-1].Plane=NodeList[Nr];
        }

    // Hier ist auch denkbar, daß Portals mit 0 Vertices zurückkommen (outer leaves)!
    // (Auch ganz normale gültige Portale in outer leaves sind denkbar!)
    Polygon3T<double>::Complete(NewPortals, MapT::RoundEpsilon);

    for (unsigned long PortalNr=0; PortalNr<NewPortals.Size(); PortalNr++)
    {
        const Polygon3T<double>& Portal=NewPortals[PortalNr];

        // In degenerierten Grenzfällen (in Gegenwart von Splittern) können auch andere ungültige Polygone entstehen
        // (z.B. mehrere Vertices quasi auf einer Edge), sodaß wir explizit die Gültigkeit prüfen.
        // if (Portal.Vertices.Size()<3) continue;    // Ist in .IsValid() enthalten!
        if (!Portal.IsValid(MapT::RoundEpsilon, MapT::MinVertexDist)) continue;


        // Another very serious problem is the fact that we sometimes self-create leaks,
        // because nearly all operations in this program suffer from rounding errors.
        // I have *NO* idea how to best combat them (except the introduction of exact arithmetic, which I'm seriously considering).
        // But for now, lets try something simpler - enforce a "minimum area" for portals.
        // Portals that are smaller than this minimum are considered degenerate, despite they were classified as valid above.
        // Note that the same is enforced below, where portals are split along the leafs faces.
        // UPDATE: As the new Polygon3T<double>::IsValid() method now enforces the MapT::MinVertexDist,
        // I believe the problem is solved the the polygon area check not longer required.
        if (Portal.GetArea()<=100.0 /* 1 cm^2 */) continue;


        // Note that rejecting portals here (i.e. adding additional test criteria) is a dangerous idea,
        // because any omitted portal might stop the subsequent flood-fill early.
        // This in turn might easily tear big holes into the world.
        // Consider my Tech-Archive notes from 2005-11-15 for a sketch that shows a problematic (but valid!) leaf
        // whose entry portal must not be omitted so that it can be entered during the flood-fill,
        // or else the left wall will be erroneously removed by the fill.


        // Okay, the portal seems to be good, so add it to the leaf.
        Leaves[LeafNr].Portals.PushBack(Portal.GetMirror());
    }
}
开发者ID:mark711,项目名称:Cafu,代码行数:55,代码来源:Portalize.cpp

示例4: ReduceSamplesTo

void CaptureStreamT::ReduceSamplesTo(unsigned int NumLeft)
{
    const unsigned int NumNow=GetNumCaptureSamples();

    if (NumNow>NumLeft)
    {
        ArrayT<unsigned char> Discard;

        Discard.PushBackEmpty((NumNow-NumLeft)*BytesPerSample(m_FORMAT));
        alcCaptureSamples(m_CaptureDevice, &Discard[0], NumNow-NumLeft);
    }
}
开发者ID:mark711,项目名称:Cafu,代码行数:12,代码来源:CaptureStream.cpp

示例5: ComputeSuperLeavesBBs

// This function computes for each SuperLeaf the bounding box over its 'SubPortals'.
// Such bounding boxes are useful when a SuperLeaf is considered in its role as a "target" SuperLeaf.
// The results are stored in the 'SuperLeavesBBs', which is assumed to be empty before this function is called.
// SuperLeaves that have no (sub-)portals (and thus, no neighbours), get the default bounding box assigned.
void ComputeSuperLeavesBBs()
{
    for (unsigned long SL=0; SL<SuperLeaves.Size(); SL++)
    {
        SuperLeavesBBs.PushBackEmpty();

        if (SuperLeaves[SL].Neighbours.Size()==0) continue;

        SuperLeavesBBs[SL]=BoundingBox3T<double>(SuperLeaves[SL].Neighbours[0].SubPortal.Vertices);

        for (unsigned long NeighbourNr=1; NeighbourNr<SuperLeaves[SL].Neighbours.Size(); NeighbourNr++)
            SuperLeavesBBs[SL].Insert(SuperLeaves[SL].Neighbours[NeighbourNr].SubPortal.Vertices);
    }

    printf("SLs Bounding Boxes  :       done\n");
}
开发者ID:mark711,项目名称:Cafu,代码行数:20,代码来源:CaPVS.cpp

示例6: CanSeeFromAToB

// This functions determines if we can see from 'MasterSL' to 'TargetSL', that is, if 'TargetSL' is visible from 'MasterSL'.
// ATTENTION 1: IT IS ASSUMED THAT THE PVS FOR ALL SUPERLEAVES IN RANGE '0..MasterSL-1' HAS ALREADY BEEN ESTABLISHED!
// ATTENTION 2: THIS FUNCTION DOES NOT WORK IF 'MasterSL==TargetSL', OR 'TargetSL' IS AN IMMEDIATE NEIGHBOUR OF 'MasterSL'!
// If mutual visibility could be established, the result is recorded in 'SuperLeavesPVS', for both "from A to B" and "from B to A".
bool CanSeeFromAToB(unsigned long MasterSL, unsigned long TargetSL)
{
    ArrayT<unsigned long> AncestorSLs;
    AncestorSLs.PushBackEmpty(2);

    // Für den alten Algorithmus war hier vermerkt, daß "outer leaves" keine Neighbours/Portals haben,
    // wegen der Eigenschaften von Portalize() und FillInside() des CaBSP Programms.
    // Der neue Algorithmus verwendet SuperLeaves, bei denen überhaupt nicht zwischen "inner" und "outer" unterschieden wird.
    // Alles was zählt, sind die Portale. Deshalb setzen sich SuperLeaves korrekt aus beliebigen Leaves eines Sub-Trees zusammen.
    for (unsigned long NeighbourNr=0; NeighbourNr<SuperLeaves[MasterSL].Neighbours.Size(); NeighbourNr++)
    {
        const unsigned long      NeighbourSL =SuperLeaves[MasterSL].Neighbours[NeighbourNr].SuperLeafNr;
        const Polygon3T<double>& MasterPortal=SuperLeaves[MasterSL].Neighbours[NeighbourNr].SubPortal;

        // Wenn für das 'NeighbourSL' schon festgestellt wurde, daß das 'TargetSL' von dort aus nicht zu sehen ist,
        // sparen wir uns die Mühe, es trotzdem zu versuchen, und machen direkt weiter.
        if (NeighbourSL<MasterSL && !IsVisible(NeighbourSL, TargetSL)) continue;

        AncestorSLs[0]=MasterSL;
        AncestorSLs[1]=NeighbourSL;

        for (unsigned long NNNr=0; NNNr<SuperLeaves[NeighbourSL].Neighbours.Size(); NNNr++)
        {
            const unsigned long      NeighboursNeighbourSL=SuperLeaves[NeighbourSL].Neighbours[NNNr].SuperLeafNr;
            const Polygon3T<double>& EnteringPortal       =SuperLeaves[NeighbourSL].Neighbours[NNNr].SubPortal;

            if (NeighboursNeighbourSL==MasterSL) continue;

            const Polygon3T<double>::SideT Side=MasterPortal.WhatSide(EnteringPortal.Plane, MapT::RoundEpsilon);

            if (Side==Polygon3T<double>::InIdentical || Side==Polygon3T<double>::InMirrored) continue;

            // Wenn für das 'NeighboursNeighbourSL' schon festgestellt wurde, daß das 'TargetSL' von dort aus nicht zu sehen ist,
            // sparen wir uns die Mühe, es trotzdem zu versuchen, und machen direkt weiter.
            if (NeighboursNeighbourSL<MasterSL && !IsVisible(NeighboursNeighbourSL, TargetSL)) continue;

            // Das TOLLE: Sobald wir festgestellt haben, daß "irgendeine" Sichtbarkeit von 'MasterSL' nach 'TargetSL' existiert,
            // können wir sofort AUFHÖREN(!!!) und mit dem nächsten SuperLeaves-Paar weitermachen!
            if (DetermineVisibility(NeighboursNeighbourSL, EnteringPortal, AncestorSLs, MasterPortal, TargetSL, SuperLeavesBBs[TargetSL])) return true;
        }
    }

    return false;
}
开发者ID:mark711,项目名称:Cafu,代码行数:48,代码来源:CaPVS.cpp

示例7: SortFacesIntoTexNameOrder

// Diese Funktion sortiert die Faces anhand ihres Texture-Namens in aufsteigender Reihenfolge.
// Dank Z-Buffering kann die Engine damit die Faces in dieser Reihenfolge mit einem Minimum von State-Changes rendern.
// Da außerdem die LightMaps der Faces in dieser Reihenfolge in die größeren LightMaps einsortiert werden
// (CreateFullBrightLightMaps()), erhalten wir den selben positiven Effekt auch für die LightMaps!
void BspTreeBuilderT::SortFacesIntoTexNameOrder()
{
    if (FaceChildren.Size()==0) return;

    Console->Print(cf::va("\n%-50s %s\n", "*** Sort Faces ***", GetTimeSinceProgramStart()));

    FaceNrs.Clear();
    for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++) FaceNrs.PushBack(FaceNr);

    // QuickSort Faces according to their texture name.
    ToDoRanges.Clear();
    ToDoRanges.PushBack(0);
    ToDoRanges.PushBack(FaceChildren.Size()-1);

    QuickSortFacesIntoTexNameOrder();

    // Verify sorting.
    for (unsigned long FaceNr=0; FaceNr+1<FaceChildren.Size(); FaceNr++)
        if (_stricmp(FaceChildren[FaceNr]->Material->Name.c_str(), FaceChildren[FaceNr+1]->Material->Name.c_str())>0) Error("Bad sorting!");

    // Wir wissen nun, daß an Stelle der Face i nun die Face FaceNrs[i] steht, wollen aber wissen, an welcher
    // Stelle nun die i-te Face steht. Führe dazu das RevFaceNrs-Array ein und fülle es entsprechend aus.
    ArrayT<unsigned long> RevFaceNrs;

    RevFaceNrs.PushBackEmpty(FaceChildren.Size());
    for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++) RevFaceNrs[FaceNrs[FaceNr]]=FaceNr;

    // Korrigiere damit die FaceSets der Leaves.
    ArrayT<cf::SceneGraph::BspTreeNodeT::LeafT>& Leaves=BspTree->Leaves;

    for (unsigned long LeafNr=0; LeafNr<Leaves.Size(); LeafNr++)
        for (unsigned long FaceNr=0; FaceNr<Leaves[LeafNr].FaceChildrenSet.Size(); FaceNr++)
            Leaves[LeafNr].FaceChildrenSet[FaceNr]=RevFaceNrs[Leaves[LeafNr].FaceChildrenSet[FaceNr]];

    Console->Print("done\n");
}
开发者ID:mark711,项目名称:Cafu,代码行数:40,代码来源:SortFaces.cpp

示例8: main


//.........这里部分代码省略.........
            printf("Unknown option '%s'.\n", ArgV[ArgNr]);
            Usage();
        }
    }


    std::string GameDirectory=ArgV[1];

    // Determine the game directory, cleverly assuming that the destination file is in "Worlds".
    {
        // Strip the file name and extention off.
        size_t i=GameDirectory.find_last_of("/\\");

        GameDirectory=GameDirectory.substr(0, i==std::string::npos ? 0 : i)+"/..";
    }


    // Setup the global MaterialManager pointer.
    static MaterialManagerImplT MatManImpl;

    MaterialManager=&MatManImpl;

    if (MaterialManager->RegisterMaterialScriptsInDir(GameDirectory+"/Materials", GameDirectory+"/").Size()==0)
    {
        printf("\nNo materials found in scripts in \"%s/Materials\".\n", GameDirectory.c_str());
        printf("No materials found.\n\n");
        Usage();
    }


    try
    {
        // General note: Robustness against the 'sharp wedge' problem is granted:
        // DetermineAdjacencyGraph() is the only place where PolygonOverlap() is called, but only once on *input* portals.
        // Everywhere else (especially in BuildPVS() and its sub-functions), only PolygonSplit() and PolygonWhatSide() are called.
        printf("*** Load World %s ***\n", ArgV[1]);

        // 1. Load the 'CaPVSWorld'.
        ModelManagerT ModelMan;
        CaPVSWorldT*  CaPVSWorld=new CaPVSWorldT(ArgV[1], ModelMan, MaxRecDepthSL, MinAreaSL);

        // 2. Create the 'SuperLeaves'.
        CaPVSWorld->CreateSuperLeaves(SuperLeaves);
        if (OnlySuperLeaves) return 0;

        // 3. Determine the adjacency graph.
        //    This completely fills-in the remaining components of the 'SuperLeaves'.
        printf("\n%-50s %s\n", "*** Initialize ***", GetTimeSinceProgramStart());
        DetermineAdjacencyGraph();

        // 4. Compute for each SuperLeaf the bounding box over its (sub-)portals.
        ComputeSuperLeavesBBs();

        // 5. Create and initialize the 'SuperLeavesPVS' (reset to complete blindness (all 0s)).
        SuperLeavesPVS.PushBackEmpty((SuperLeaves.Size()*SuperLeaves.Size()+31)/32);
        for (unsigned long Vis=0; Vis<SuperLeavesPVS.Size(); Vis++) SuperLeavesPVS[Vis]=0;

        // 6. For each SuperLeaf, flag itself and the immediate neighbours as visible.
        DetermineTrivialVisibility();

        // 7. Do some simple ray tests in order to quickly obtain a good estimation of the actual PVS.
        //    Note that calling this function is ENTIRELY OPTIONAL, and the call can be omitted without danger!
        //    (The latter might e.g. be useful for debugging.)
        DetermineRayPresampledVisibility(CaPVSWorld);

        // 8. Finally calculate the 'SuperLeavesPVS' using analytical methods.
        printf("\n%-50s %s\n", "*** Potentially Visibility Set ***", GetTimeSinceProgramStart());
        BuildPVS();

        // 9. Carry the information in 'SuperLeavesPVS' into the PVS of the 'CaPVSWorld'.
        CaPVSWorld->StorePVS(SuperLeaves, SuperLeavesPVS);

        // 10. Print some statistics and obtain a checksum.
        unsigned long CheckSum=CaPVSWorld->GetChecksumAndPrintStats();

        // 11. Save the 'CaPVSWorld' back to disk.
        printf("\n%-50s %s\n", "*** Save World ***", GetTimeSinceProgramStart());
        printf("%s\n", ArgV[1]);
        CaPVSWorld->SaveToDisk(ArgV[1]);

        // 12. Clean-up and write log file entry.
        delete CaPVSWorld;
        WriteLogFileEntry(ArgV[1], CheckSum);
        printf("\n%-50s %s\n", "COMPLETED.", GetTimeSinceProgramStart());
    }
    catch (const WorldT::LoadErrorT& E)
    {
        printf("\nFATAL ERROR: %s\n", E.Msg);
        printf("Program aborted.\n\n");
        exit(1);
    }
    catch (const WorldT::SaveErrorT& E)
    {
        printf("\nFATAL ERROR: %s\n", E.Msg);
        printf("Program aborted.\n\n");
        exit(1);
    }

    return 0;
}
开发者ID:mark711,项目名称:Cafu,代码行数:101,代码来源:CaPVS.cpp

示例9: DetermineRayPresampledVisibility

// Determines a simple pre-PVS by sampling "random" rays (and stores it in 'SuperLeavesPVS').
// The result is a subset of the analytically determined, conservative, "exact" PVS.
// This function does not handle the fact that SuperLeaves can see themselves.
// Thus, calling 'DetermineTrivialVisibility()' before (or after) calling this function is required.
void DetermineRayPresampledVisibility(const CaPVSWorldT* CaPVSWorld)
{
    ArrayT< ArrayT<VectorT> > SuperLeavesCenters;
    ArrayT< ArrayT<bool   > > SuperLeavesCenterIsValid;

    for (unsigned long SL=0; SL<SuperLeaves.Size(); SL++)
    {
        SuperLeavesCenters      .PushBackEmpty();
        SuperLeavesCenterIsValid.PushBackEmpty();

        for (unsigned long NbNr=0; NbNr<SuperLeaves[SL].Neighbours.Size(); NbNr++)
        {
            const Polygon3T<double>& SubPortal=SuperLeaves[SL].Neighbours[NbNr].SubPortal;
            VectorT                  Center   =SubPortal.Vertices[0];

            for (unsigned long VertexNr=1; VertexNr<SubPortal.Vertices.Size(); VertexNr++) Center=Center+SubPortal.Vertices[VertexNr];
            Center=scale(Center, 1.0/double(SubPortal.Vertices.Size()))+scale(SubPortal.Plane.Normal, 0.2);

            // Not really necessary, but add a little check to see if everything is in order.
            // (Or, more precisely, assert that the 'Center' is really "inside" the SuperLeaf.)
            const unsigned long LeafNr=CaPVSWorld->WhatLeaf(Center);
            unsigned long LeafSetNr;

            for (LeafSetNr=0; LeafSetNr<SuperLeaves[SL].LeafSet.Size(); LeafSetNr++)
                if (LeafNr==SuperLeaves[SL].LeafSet[LeafSetNr]) break;

            SuperLeavesCenters      [SL].PushBack(Center);
            SuperLeavesCenterIsValid[SL].PushBack(LeafSetNr<SuperLeaves[SL].LeafSet.Size());

            // if (LeafSetNr>=SuperLeaves[SL1].LeafSet.Size()) printf("WARNING: Center not in its SuperLeaf. TODO: Print more extensive diagnostics.\n");
        }
    }

    for (unsigned long SL1=0; SL1+1<SuperLeaves.Size(); SL1++)
    {
        printf("%5.1f%%\r", (double)SL1/SuperLeaves.Size()*100.0);
        fflush(stdout);

        for (unsigned long SL2=SL1+1; SL2<SuperLeaves.Size(); SL2++)
        {
            if (IsVisible(SL1, SL2)) continue;

            for (unsigned long Nb1Nr=0; Nb1Nr<SuperLeaves[SL1].Neighbours.Size(); Nb1Nr++)
            {
                if (!SuperLeavesCenterIsValid[SL1][Nb1Nr]) continue;

                for (unsigned long Nb2Nr=0; Nb2Nr<SuperLeaves[SL2].Neighbours.Size(); Nb2Nr++)
                {
                    if (!SuperLeavesCenterIsValid[SL2][Nb2Nr]) continue;

                    const VectorT& Center1=SuperLeavesCenters[SL1][Nb1Nr];
                    const VectorT& Center2=SuperLeavesCenters[SL2][Nb2Nr];

                    // This ClipLine() only considers faces, but not BPs, terrains, etc.
                    if (CaPVSWorld->ClipLine(Center1, Center2-Center1)==1.0)
                    {
                        FlagVisible(SL1, SL2);
                        FlagVisible(SL2, SL1);
                        goto DoneWithSL2;
                    }
                }
            }

            DoneWithSL2:;
        }
    }

    printf("Estimated PVS       : %10.5f\n", GetAverageVisibility());
}
开发者ID:mark711,项目名称:Cafu,代码行数:73,代码来源:CaPVS.cpp

示例10: CreatePatchMeshes

void FaceNodeT::CreatePatchMeshes(ArrayT<cf::PatchMeshT>& PatchMeshes, ArrayT< ArrayT< ArrayT<Vector3dT> > >& SampleCoords) const
{
    if (LightMapInfo.SizeS==0) return;
    if (LightMapInfo.SizeT==0) return;
    if (Polygon.Vertices.Size()<3) return;

    // A FaceNodeT creates excatly one patch mesh - namely the one that covers it.
    PatchMeshes.PushBackEmpty();
    SampleCoords.PushBackEmpty();

    PatchMeshT& PatchMesh=PatchMeshes[PatchMeshes.Size()-1];


    // Fill-in basic data.
    PatchMesh.Width =LightMapInfo.SizeS;
    PatchMesh.Height=LightMapInfo.SizeT;
    PatchMesh.Patches.PushBackEmpty(PatchMesh.Width*PatchMesh.Height);

    PatchMesh.WrapsHorz=false;
    PatchMesh.WrapsVert=false;

    PatchMesh.Node    =this;
    PatchMesh.Material=Material;

    SampleCoords[0].PushBackEmpty(PatchMesh.Width*PatchMesh.Height);


    // Compute the details for each patch.
    // Dieser Code ist sehr ähnlich zu dem Code in CaLights PostProcessBorders() Funktion!
    // Änderungen hier könnten Änderungen in dieser Funktion erforderlich machen!

    // Bestimme die Spannvektoren.
    VectorT U;
    VectorT V;

    Polygon.Plane.GetSpanVectors(U, V);

    // Finde SmallestU und SmallestV.
    double SmallestU=dot(Polygon.Vertices[0], U);
    double SmallestV=dot(Polygon.Vertices[0], V);

    for (unsigned long VertexNr=1; VertexNr<Polygon.Vertices.Size(); VertexNr++)
    {
        double u=dot(Polygon.Vertices[VertexNr], U);
        double v=dot(Polygon.Vertices[VertexNr], V);

        if (u<SmallestU) SmallestU=u;
        if (v<SmallestV) SmallestV=v;
    }

    // Bereite folgende Schleife vor.
    const VectorT UV_Origin=scale(Polygon.Plane.Normal, Polygon.Plane.Dist);
    const VectorT Safety   =scale(Polygon.Plane.Normal, 0.1);

    Polygon3T<double> PatchPoly;
    PatchPoly.Plane=dot(Polygon.Plane.Normal, cross(U, V))<0 ? Polygon.Plane : Polygon.Plane.GetMirror();

    // Nun betrachte alle Patches.
    for (unsigned long t=0; t<PatchMesh.Height; t++)
        for (unsigned long s=0; s<PatchMesh.Width; s++)
        {
            const double PATCH_SIZE=cf::SceneGraph::FaceNodeT::LightMapInfoT::PatchSize;
            cf::PatchT&  Patch     =PatchMesh.Patches[t*PatchMesh.Width+s];

            Patch.Coord     =VectorT(0, 0, 0);
            Patch.Normal    =Polygon.Plane.Normal;
            Patch.Area      =PATCH_SIZE*PATCH_SIZE;
            Patch.InsideFace=false;

            // Also assign an initial, non-zero "Where comes the energy from?"-direction.
            // The value (==length) has been chosen entirely arbitrary with the accumulative nature of the computations in CaLight
            // in mind, and in the hope to pick a reasonable value.
            // (However, tests seem to indicate the smaller values are better. I tried 0.3 first, then 0.05.)
            Patch.EnergyFromDir=Patch.Normal*0.02;

            const double s_=s;
            const double t_=t;

            PatchPoly.Vertices.Clear();
            PatchPoly.Vertices.PushBack(UV_Origin+scale(U, SmallestU+(s_-1.0)*PATCH_SIZE)+scale(V, SmallestV+(t_-1.0)*PATCH_SIZE));
            PatchPoly.Vertices.PushBack(UV_Origin+scale(U, SmallestU+ s_     *PATCH_SIZE)+scale(V, SmallestV+(t_-1.0)*PATCH_SIZE));
            PatchPoly.Vertices.PushBack(UV_Origin+scale(U, SmallestU+ s_     *PATCH_SIZE)+scale(V, SmallestV+ t_     *PATCH_SIZE));
            PatchPoly.Vertices.PushBack(UV_Origin+scale(U, SmallestU+(s_-1.0)*PATCH_SIZE)+scale(V, SmallestV+ t_     *PATCH_SIZE));

            assert(fabs(PatchPoly.GetArea()-Patch.Area)<1.0);   // This is just to make sure there is no logic error in area computation.

            if (!Polygon.Overlaps(PatchPoly, false, ROUND_EPSILON)) continue;

            if (!Polygon.Encloses(PatchPoly, true, ROUND_EPSILON))
            {
                ArrayT< Polygon3T<double> > NewPolygons;

                PatchPoly.GetChoppedUpAlong(Polygon, ROUND_EPSILON, NewPolygons);

                if (NewPolygons.Size()>0 && NewPolygons[NewPolygons.Size()-1].Vertices.Size()>0)
                {
                    PatchPoly=NewPolygons[NewPolygons.Size()-1];
                }
                else
                {
//.........这里部分代码省略.........
开发者ID:mark711,项目名称:Cafu,代码行数:101,代码来源:FaceNode.cpp


注:本文中的ArrayT::PushBackEmpty方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。