Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Terrain Assert

Help
AdamL
2007-11-17
2013-05-02
  • AdamL
    AdamL
    2007-11-17

    I'm adding a DirectX Terrain to the simulator and it asserts on scenery.cpp line 782.

    When I walk into the line.

    [code]
    neTreeNode * node = tree->nodes.Alloc();
    [/code]

    I see that growBy == 0 so it returns NULL.

    [code]
        NEINLINE T * Alloc()
        {
            if (nextFree >= (data + size))
            {
                if (growBy == 0)
                    return NULL;

    ......
    [/code]

    I can't really figure out how this would work since it always seems to return NULL.

    My mesh is fairly large though so I'm wondering if that has something to do with it.  Its 66,049 verts and 131,072 triangles.  I break it up into 33 x 33 mesh chunks for rendering, but i'm feeding the whole thing into the physics engine.

    Heres some of my code maybe it will help track this down.

    [code]
    //After the grid is generated
    ....
            // Declare a terrain mesh for the floor
            neTriangleMesh *triMesh = new neTriangleMesh;
            // The array of vertices
            neV3 *triVertices = new neV3[numVerts];
            // The array of triangles
            neTriangle *triData = new neTriangle[numTris];

            triMesh->vertexCount = numVerts;
            triMesh->triangleCount = numTris;

            float w = m_width;
            float d = m_depth;
            for(UINT i = 0; i < mesh->GetNumVertices(); ++i)
            {
                // We store the grid vertices in a linear array, but we can
                // convert the linear array index to an (r, c) matrix index.
                int r = i / m_vertCols;
                int c = i % m_vertCols;

                v[i].pos   = verts[i];
                v[i].pos.y = m_heightmap(r, c );

                triVertices[i].Set( v[i].pos.x, v[i].pos.y, v[i].pos.z );

                v[i].tex0.x = (v[i].pos.x + (0.5f*w)) / w;
                v[i].tex0.y = (v[i].pos.z - (0.5f*d)) / -d;
            }

            triMesh->vertices = triVertices;

            m_device->SetLoadProgress( 0.2f );

            // Write triangle data so we can compute normals.

            DWORD* indexBuffPtr = 0;
            mesh->LockIndexBuffer(0, (void**)&indexBuffPtr);
            if( mesh->GetNumFaces() != numTris )
            {
                LogPrintf("Error: Faces do not equal calculated triangle size");
            }

            for(UINT i = 0; i < mesh->GetNumFaces(); ++i)
            {
                indexBuffPtr[i*3+0] = indices[i*3+0];
                indexBuffPtr[i*3+1] = indices[i*3+1];
                indexBuffPtr[i*3+2] = indices[i*3+2];

                triData[i].indices[0] = indices[i * 3 + 0];
                triData[i].indices[1] = indices[i * 3 + 1];
                triData[i].indices[2] = indices[i * 3 + 2];
                triData[i].materialID = 1;
                triData[i].flag = neTriangle::NE_TRI_TRIANGLE;
            }
            mesh->UnlockIndexBuffer();

            triMesh->triangles = triData;
            CPhysicsEngine::Instance()->SetTerrainMesh( triMesh );

    [/code]

    And here is the callstack

    >    msvcr80d.dll!_wassert(const wchar_t * expr=0x006313a4, const wchar_t * filename=0x00631380, unsigned int lineno=782)  Line 384    C
         GoldHunter.exe!TreeBuild(neTriangleTree * tree=0x00f7c4f4, int nodeIndex=-1, neSimpleArray<int,1> & triIndex={...}, int level=0)  Line 782 + 0x1a bytes    C++
         GoldHunter.exe!neTriangleTree::BuildTree(neV3 * _vertices=0x04070040, int _vertexCount=66049, neTriangle * tris=0x04180040, int triCount=131072, neAllocatorAbstract * _alloc=0x00f7ae30)  Line 883 + 0x11 bytes    C++
         GoldHunter.exe!neRegion::MakeTerrain(neTriangleMesh * tris=0x00f89498)  Line 469    C++
         GoldHunter.exe!neFixedTimeStepSimulator::SetTerrainMesh(neTriangleMesh * tris=0x00f89498)  Line 2003    C++
         GoldHunter.exe!neSimulator::SetTerrainMesh(neTriangleMesh * tris=0x00f89498)  Line 2154    C++
         GoldHunter.exe!CPhysicsEngine::SetTerrainMesh(neTriangleMesh * tMesh=0x00f89498)  Line 57 + 0x32 bytes    C++
         GoldHunter.exe!CTerrain::Create()  Line 184    C++
         GoldHunter.exe!CTerrain::CTerrain(std::basic_string<char,std::char_traits<char>,std::allocator<char> > heightmap="Assets/castlehm257.raw", CGraphicsDevice * pDevice=0x00f712f0, CCamera * camera=0x00f63388)  Line 30    C++
         GoldHunter.exe!Level1::Load()  Line 109 + 0x6c bytes    C++
         GoldHunter.exe!CGameApp::AddState(CGameState * state=0x00f72968, bool changeTo=true)  Line 45 + 0x15 bytes    C++
         GoldHunter.exe!WinMain(HINSTANCE__ * instance=0x00400000, HINSTANCE__ * prev=0x00000000, char * cmdLine=0x00151f23, int cmdShow=1)  Line 24    C++
         GoldHunter.exe!__tmainCRTStartup()  Line 589 + 0x35 bytes    C
         GoldHunter.exe!WinMainCRTStartup()  Line 414    C
         kernel32.dll!7c816fd7()    
         [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]   

     

    Related

    Code: code

    • AdamL
      AdamL
      2007-11-17

      I was able to solve the crashing issue, I found another post after searching an hour or so on the old forum.  Basically I needed to increase sizeInfo.terrainNodesStartCount to at least the number of triangles in my mesh.  Hopefully this helps someone in the future.

      Anyway i add my neTriangleMesh to the simulator and it doesn't crash or anything now, although everything falls right through it.  I have no idea what could be wrong, as I've been debugging this for the last 2 hours.

      I did a log of the information i'm passing in, and i'm wondering if there is a specific order it needs.

      Here is a short log of what I'm passing in.

      Triangle Indices: = 0 1 257 Verts = -255.999985 16.650000 255.999985 :: -253.999985 16.516668 255.999985 :: -255.999985 16.699999 253.999985
      Triangle Indices: = 257 1 258 Verts = -255.999985 16.699999 253.999985 :: -253.999985 16.516668 255.999985 :: -253.999985 16.622223 253.999985
      Triangle Indices: = 1 2 258 Verts = -253.999985 16.516668 255.999985 :: -251.999985 16.216667 255.999985 :: -253.999985 16.622223 253.999985
      Triangle Indices: = 258 2 259 Verts = -253.999985 16.622223 253.999985 :: -251.999985 16.216667 255.999985 :: -251.999985 16.400000 253.999985
      Triangle Indices: = 2 3 259 Verts = -251.999985 16.216667 255.999985 :: -249.999985 15.950000 255.999985 :: -251.999985 16.400000 253.999985
      Triangle Indices: = 259 3 260 Verts = -251.999985 16.400000 253.999985 :: -249.999985 15.950000 255.999985 :: -249.999985 16.211113 253.999985
      Triangle Indices: = 3 4 260 Verts = -249.999985 15.950000 255.999985 :: -247.999985 15.766666 255.999985 :: -249.999985 16.211113 253.999985
      Triangle Indices: = 260 4 261 Verts = -249.999985 16.211113 253.999985 :: -247.999985 15.766666 255.999985 :: -247.999985 16.055555 253.999985
      Triangle Indices: = 4 5 261 Verts = -247.999985 15.766666 255.999985 :: -245.999985 15.766666 255.999985 :: -247.999985 16.055555 253.999985
      Triangle Indices: = 261 5 262 Verts = -247.999985 16.055555 253.999985 :: -245.999985 15.766666 255.999985 :: -245.999985 15.988888 253.999985
      Triangle Indices: = 5 6 262 Verts = -245.999985 15.766666 255.999985 :: -243.999985 16.050001 255.999985 :: -245.999985 15.988888 253.999985
      Triangle Indices: = 262 6 263 Verts = -245.999985 15.988888 253.999985 :: -243.999985 16.050001 255.999985 :: -243.999985 16.144445 253.999985
      Triangle Indices: = 6 7 263 Verts = -243.999985 16.050001 255.999985 :: -241.999985 16.533335 255.999985 :: -243.999985 16.144445 253.999985
      Triangle Indices: = 263 7 264 Verts = -243.999985 16.144445 253.999985 :: -241.999985 16.533335 255.999985 :: -241.999985 16.522224 253.999985
      Triangle Indices: = 7 8 264 Verts = -241.999985 16.533335 255.999985 :: -239.999985 17.233334 255.999985 :: -241.999985 16.522224 253.999985

      Here is how I initialize my Physics Engine

      [code]
          neSimulatorSizeInfo sizeInfo;

          sizeInfo.rigidBodiesCount        = NUM_RIGID_BODIES;
          sizeInfo.animatedBodiesCount    = NUM_ANIMATED_BODIES;
          sizeInfo.rigidParticleCount        = 0;
          sizeInfo.controllersCount        = 0;

          sizeInfo.overlappedPairsCount    = 2000;
          sizeInfo.geometriesCount        = NUM_RIGID_BODIES + NUM_ANIMATED_BODIES;
          sizeInfo.constraintsCount        = 200;
          sizeInfo.constraintSetsCount    = 200;
          sizeInfo.constraintBufferSize    = 2000;
          sizeInfo.sensorsCount            = 100;
          sizeInfo.terrainNodesStartCount    = 131072 * 3;
          sizeInfo.terrainNodesGrowByCount = 0;

          neV3 gravity;
          gravity.Set(0.0f, -4.0f, 0.0f);  //set gravity vector

          g_simulator = neSimulator::CreateSimulator( sizeInfo, 0, &gravity);
      [/code]

      I add one rigid body object using this code

      [code]
              RigidObject *temp = new RigidObject;
              temp->body = g_simulator->CreateRigidBody();
              neGeometry *cubeGeom = temp->body->AddGeometry();
              neV3 sizeOfCube;
              sizeOfCube.Set(obj->size.x, obj->size.y, obj->size.z);
              cubeGeom->SetBoxSize( sizeOfCube );

              f32 massOfCube = obj->mass;
              temp->body->SetMass ( massOfCube );
              temp->body->SetInertiaTensor( neBoxInertiaTensor (sizeOfCube, massOfCube) );

              neV3 positionOfCube;
              positionOfCube.Set(obj->pos.x, obj->pos.y, obj->pos.z);
              temp->body->SetPos( positionOfCube );

              neM3 rotationOfCube;
              neV3 rot;
              rot.Set(obj->rot.x, obj->rot.y, obj->rot.z);
              rotationOfCube.RotateXYZ(rot);
              temp->body->SetRotation( rotationOfCube );

              temp->body->UpdateBoundingInfo();
              m_rigid.push_back(temp);
              return temp->body;
      [/code]

      So the item keeps falling to eternity here is a log of the position of the item.

      Position = 0.000000 3.161972 0.001855
      Position = 0.000000 2.869194 0.001855
      Position = 0.000000 2.575304 0.001855
      Position = 0.000000 2.280303 0.001855
      Position = 0.000000 1.984191 0.001855
      Position = 0.000000 1.686968 0.001855
      Position = 0.000000 1.388634 0.001855
      Position = 0.000000 1.089188 0.001855
      Position = 0.000000 0.788632 0.001855
      Position = 0.000000 0.486964 0.001855
      Position = 0.000000 0.184185 0.001855
      Position = 0.000000 -0.119705 0.001855
      Position = 0.000000 -0.424706 0.001855
      Position = 0.000000 -0.730818 0.001855
      Position = 0.000000 -1.038041 0.001855
      Position = 0.000000 -1.346376 0.001855
      Position = 0.000000 -1.655821 0.001855
      Position = 0.000000 -1.966378 0.001855
      Position = 0.000000 -2.278046 0.001855
      Position = 0.000000 -2.590825 0.001855
      Position = 0.000000 -2.904715 0.001855

      My terrain height at X = 0.0f and Z = 0.0f is ~ 6.0f units.  I start the object at 35 units above the terrain, once the game starts it just falls to eternity.

      So if anyone can help me it would be greatly appreciated.  I'll keep working on it, but it doesn't look to be an easy fix.

      Thanks Again Adam.

       

      Related

      Code: code

      • manthrax
        manthrax
        2007-11-25

        Hi Adam,
        Off the top of my head (having just rebuilt a similar setup)..
        Try running your sim with only a tiny amount of gravity and see if the collision still misses.
        If it doesn't miss then It means the object is gettting too much velocity before collision. You can fix that by damping, changing masses, or changing gravity..
        The last time I encountered a similar baffling problem was when I was only passing in a part of my collision mesh, mistakenly. I think I had swapped vertex count for trianglecount or something in my terrain building loop..
        Another problem that can arise is making sure your triangle mesh data is initialized to a known safe state like zeroes. I had a situation once where the triangle data werent being initialized and starting with random values.
        Another potential problem is what is set in the collision table... Make sure your triangles and colliding stuff is all set to a known collision ID and that that collision material type is set to generate a response, not be ignored. I'm pretty sure tokamak initializes that table to a known state, but its worth checking any code you have around that..
        Other than that.. break your scene down to the simplest possible one, a quad colliding with a rigid body, and then work your way up..
        Also, making a routine to draw debugging information in wireframe has helped me visualize problems like this... basically just a stack of line segments that get rendered ontop of the scene at the end of the frame. Instead of a stack, you can also use a list and let the segments persist for some X number of frames.. that can help debug collisions or events that happen too quickly to be seen.
        Good luck!

         
    • David Lam
      David Lam
      2007-11-19

      What is the size of your falling object? It could be too small.

      Also, try to replace your complex terrain with just one quad (two triangles).

      If that also fails, try replace the terrain with a rectangular block animated object to make sure that object-to-object collides, and that your basic setup is correct.

      The Tokamak library is supplied with source and VC++ project files. You should be able to build and trace to the point where collision should have occured.

       
    • AdamL
      AdamL
      2007-11-25

      Your right my object was too small.  It's size was X = 0.5f, Y = 0.25f and Z = 2.25f.  Once I made these a minimum of 1.0f it collided fine.  Thanks for the help David.