дневник templar

Ответить
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

дневник templar

Сообщение Зеленк »

___http://krasnaya-zastava.ru/forum/viewtopic.php?t=5148&start=30

Теперь я буду вести свой дневник создания opeb source движка тут, потому что я на самом деле Тапл.., программист а не Стрекозец. Хотя кто знает. Вобще наверно больше бы подошел ник - Trailer
Изображение

Но такой ник и аватар я выбрал не случайно ибо Иисусова молитва Всегда защищает меня от сил зла.
Mirror
Лечение общением
Сообщения: 2223
Зарегистрирован: 27.06.2008, 06:55
Откуда: Россия

Re: Дневник Templar

Сообщение Mirror »

а что за движок?
http://www.schiza.org - Форум больных шизофренией.
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

Изображение
Ну обычный open source 3d движок для C++ типа irrlicht или ogre, но гораздо лучше, т.к. они слишком запутанные, мне самому больше всего просто бесплатные Blitz3D SDK(этот дешево стоит) или Dark GDK нравится я такого типа и делаю.
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

Теперь что бы добавить физику PhysX не только для столкновения ландшафта с кубикам, а ещё 3d моделей с кубиками
Я решил соединить вот эти два куска кода посредством собственного класса CMeshBuilder

Код: Выделить всё

static void InitTerrain()
{
   // Initialize terrain vertices
   gTerrainVerts = new NxVec3[TERRAIN_NB_VERTS];
   for(NxU32 y=0;y<TERRAIN_SIZE;y++)
   {
      for(NxU32 x=0;x<TERRAIN_SIZE;x++)
      {
         NxVec3 v;
         v.set(NxF32(x)-(NxF32(TERRAIN_SIZE-1)*0.5f), 0.0f, NxF32(y)-(NxF32(TERRAIN_SIZE-1)*0.5f));
         v *= TERRAIN_WIDTH;
         gTerrainVerts[x+y*TERRAIN_SIZE] = v;
      }
   }

   struct Local
   {
      static void _Compute(bool* done, NxVec3* field, NxU32 x0, NxU32 y0, NxU32 size, NxF32 value)
      {
         // Compute new size
         size>>=1;
         if(!size) return;

         // Compute new heights
         NxF32 v0 = value * trand();
         NxF32 v1 = value * trand();
         NxF32 v2 = value * trand();
         NxF32 v3 = value * trand();
         NxF32 v4 = value * trand();

         NxU32 x1 = (x0+size)      % TERRAIN_SIZE;
         NxU32 x2 = (x0+size+size)   % TERRAIN_SIZE;
         NxU32 y1 = (y0+size)      % TERRAIN_SIZE;
         NxU32 y2 = (y0+size+size)   % TERRAIN_SIZE;

         if(!done[x1 + y0*TERRAIN_SIZE])   field[x1 + y0*TERRAIN_SIZE].y = v0 + 0.5f * (field[x0 + y0*TERRAIN_SIZE].y + field[x2 + y0*TERRAIN_SIZE].y);
         if(!done[x0 + y1*TERRAIN_SIZE])   field[x0 + y1*TERRAIN_SIZE].y = v1 + 0.5f * (field[x0 + y0*TERRAIN_SIZE].y + field[x0 + y2*TERRAIN_SIZE].y);
         if(!done[x2 + y1*TERRAIN_SIZE])   field[x2 + y1*TERRAIN_SIZE].y = v2 + 0.5f * (field[x2 + y0*TERRAIN_SIZE].y + field[x2 + y2*TERRAIN_SIZE].y);
         if(!done[x1 + y2*TERRAIN_SIZE])   field[x1 + y2*TERRAIN_SIZE].y = v3 + 0.5f * (field[x0 + y2*TERRAIN_SIZE].y + field[x2 + y2*TERRAIN_SIZE].y);
         if(!done[x1 + y1*TERRAIN_SIZE])   field[x1 + y1*TERRAIN_SIZE].y = v4 + 0.5f * (field[x0 + y1*TERRAIN_SIZE].y + field[x2 + y1*TERRAIN_SIZE].y);

         done[x1 + y0*TERRAIN_SIZE] = true;
         done[x0 + y1*TERRAIN_SIZE] = true;
         done[x2 + y1*TERRAIN_SIZE] = true;
         done[x1 + y2*TERRAIN_SIZE] = true;
         done[x1 + y1*TERRAIN_SIZE] = true;

         // Recurse through 4 corners
         value *= 0.5f;
         _Compute(done, field, x0,   y0,   size, value);
         _Compute(done, field, x0,   y1,   size, value);
         _Compute(done, field, x1,   y0,   size, value);
         _Compute(done, field, x1,   y1,   size, value);
      }
   };

   // Fractalize
   bool* done = new bool[TERRAIN_NB_VERTS];
   memset(done,0,TERRAIN_NB_VERTS);
   gTerrainVerts[0].y = 10.0f;
   gTerrainVerts[TERRAIN_SIZE-1].y = 10.0f;
   gTerrainVerts[TERRAIN_SIZE*(TERRAIN_SIZE-1)].y = 10.0f;
   gTerrainVerts[TERRAIN_NB_VERTS-1].y = 10.0f;
   Local::_Compute(done, gTerrainVerts, 0, 0, TERRAIN_SIZE, TERRAIN_CHAOS);
   for(NxU32 i=0;i<TERRAIN_NB_VERTS;i++)   
      gTerrainVerts[i].y += TERRAIN_OFFSET;

   delete[] done;

   // Initialize terrain faces
   gTerrainFaces = new NxU32[TERRAIN_NB_FACES*3];

   NxU32 k = 0;
   for(NxU32 j=0;j<TERRAIN_SIZE-1;j++)
   {
      for(NxU32 i=0;i<TERRAIN_SIZE-1;i++)
      {
         // Create first triangle
         gTerrainFaces[k] = i   + j*TERRAIN_SIZE;
         gTerrainFaces[k+1] = i   + (j+1)*TERRAIN_SIZE;
         gTerrainFaces[k+2] = i+1 + (j+1)*TERRAIN_SIZE;

         //while we're at it do some smoothing of the random terrain because its too rough to do a good demo of this effect.
         smoothTriangle(gTerrainFaces[k],gTerrainFaces[k+1],gTerrainFaces[k+2]);
         k+=3;
         // Create second triangle
         gTerrainFaces[k] = i   + j*TERRAIN_SIZE;
         gTerrainFaces[k+1] = i+1 + (j+1)*TERRAIN_SIZE;
         gTerrainFaces[k+2] = i+1 + j*TERRAIN_SIZE;

         smoothTriangle(gTerrainFaces[k],gTerrainFaces[k+1],gTerrainFaces[k+2]);
         k+=3;
      }
   }

   //allocate terrain materials -- one for each face.
   gTerrainMaterials = new NxMaterialIndex[TERRAIN_NB_FACES];

   for(NxU32 f=0;f<TERRAIN_NB_FACES;f++)
      {
      //new: generate material indices for all the faces
      chooseTrigMaterial(f);
      }
   // Build vertex normals
   gTerrainNormals = new NxVec3[TERRAIN_NB_VERTS];
   NxBuildSmoothNormals(TERRAIN_NB_FACES, TERRAIN_NB_VERTS, gTerrainVerts, gTerrainFaces, NULL, gTerrainNormals, true);


   // Build physical model
   NxTriangleMeshDesc terrainDesc;
   terrainDesc.numVertices               = TERRAIN_NB_VERTS;
   terrainDesc.numTriangles            = TERRAIN_NB_FACES;
   terrainDesc.pointStrideBytes         = sizeof(NxVec3);
   terrainDesc.triangleStrideBytes         = 3*sizeof(NxU32);
   terrainDesc.points                  = gTerrainVerts;
   terrainDesc.triangles               = gTerrainFaces;                     
   terrainDesc.flags                  = 0;
   //add the mesh material data:
   terrainDesc.materialIndexStride         = sizeof(NxMaterialIndex);
   terrainDesc.materialIndices            = gTerrainMaterials;

   terrainDesc.heightFieldVerticalAxis      = NX_Y;
   terrainDesc.heightFieldVerticalExtent   = -1000.0f;

   NxTriangleMeshShapeDesc terrainShapeDesc;
   terrainShapeDesc.shapeFlags |= NX_SF_FEATURE_INDICES;

   bool status = InitCooking();
   if (!status) {
      printf("Unable to initialize the cooking library. Please make sure that you have correctly installed the latest version of the AGEIA PhysX SDK.");
      exit(1);
   }

    MemoryWriteBuffer buf;
     status = CookTriangleMesh(terrainDesc, buf);
   if (!status) {
      printf("Unable to cook a triangle mesh.");
      exit(1);
   }
     MemoryReadBuffer readBuffer(buf.data);
     terrainShapeDesc.meshData = gPhysicsSDK->createTriangleMesh(readBuffer);

   //
   // Please note about the created Triangle Mesh, user needs to release it when no one uses it to save memory. It can be detected
   // by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseTriangleMesh(*meshData);"
   //

   NxActorDesc ActorDesc;
   ActorDesc.shapes.pushBack(&terrainShapeDesc);
   gTerrain = gScene->createActor(ActorDesc);
   gMeshShape = (NxTriangleMeshShape*)gTerrain->getShapes()[0];
   gTerrain->userData = (void*)0;

   CloseCooking();
}


В этом больше всего кода занимает генерация ландшафта которая вобщем и не нужна для 3d модели

А этот примерно то чем я заменю но отдельно, генерацию ландшафта.

Код: Выделить всё

HRESULT SplitIntoSeperateTriangles( IDirect3DDevice9* pd3dDevice, ID3DXMesh* pInMesh, CDXUTXFileMesh* pOutMesh )
{
    HRESULT hr;
    DWORD dwNumFaces = pInMesh->GetNumFaces();
    DWORD dwOutNumVerts = dwNumFaces * 3;
    D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
    pInMesh->GetDeclaration( decl );

    ID3DXMesh* pNewMesh = NULL;
    hr = D3DXCreateMesh( dwNumFaces, dwOutNumVerts, D3DXMESH_32BIT | D3DXMESH_MANAGED, decl, pd3dDevice, &pNewMesh );
    if( FAILED( hr ) )
        return hr;

    WORD* pInIndexData;
    DWORD* pNewIndexData;
    DROID_VERTEX* pInVertexData;
    DROID_VERTEX* pNewVertexData;
    DWORD* pInAttribData;
    DWORD* pNewAttribData;
    pInMesh->LockAttributeBuffer( D3DLOCK_READONLY, ( DWORD** )&pInAttribData );
    pInMesh->LockVertexBuffer( D3DLOCK_READONLY, ( VOID** )&pInVertexData );
    pInMesh->LockIndexBuffer( D3DLOCK_READONLY, ( VOID** )&pInIndexData );
    {
        pNewMesh->LockAttributeBuffer( 0, ( DWORD** )&pNewAttribData );
        pNewMesh->LockIndexBuffer( 0, ( VOID** )&pNewIndexData );
        pNewMesh->LockVertexBuffer( 0, ( VOID** )&pNewVertexData );
        for( DWORD iFace = 0; iFace < dwNumFaces; iFace++ )
        {
            DWORD iV1 = pInIndexData[ iFace * 3 + 0 ];
            DWORD iV2 = pInIndexData[ iFace * 3 + 1 ];
            DWORD iV3 = pInIndexData[ iFace * 3 + 2 ];

            pNewAttribData[ iFace ] = 0;

            D3DXVECTOR3 vA = pInVertexData[ iV1 ].pos - pInVertexData[ iV2 ].pos;
            D3DXVECTOR3 vB = pInVertexData[ iV1 ].pos - pInVertexData[ iV3 ].pos;
            D3DXVECTOR3 vFaceNormal;
            D3DXVec3Cross( &vFaceNormal, &vA, &vB );
            D3DXVec3Normalize( &vFaceNormal, &vFaceNormal );

            pNewIndexData[ iFace * 3 + 0 ] = iFace * 3 + 0;
            pNewVertexData[ iFace * 3 + 0 ].pos = pInVertexData[ iV1 ].pos;
            pNewVertexData[ iFace * 3 + 0 ].normal = vFaceNormal; // pInVertexData[ iV1 ].normal;
            pNewVertexData[ iFace * 3 + 0 ].uv = pInVertexData[ iV1 ].uv;

            pNewIndexData[ iFace * 3 + 1 ] = iFace * 3 + 1;
            pNewVertexData[ iFace * 3 + 1 ].pos = pInVertexData[ iV2 ].pos;
            pNewVertexData[ iFace * 3 + 1 ].normal = vFaceNormal; // pInVertexData[ iV2 ].normal;
            pNewVertexData[ iFace * 3 + 1 ].uv = pInVertexData[ iV2 ].uv;

            pNewIndexData[ iFace * 3 + 2 ] = iFace * 3 + 2;
            pNewVertexData[ iFace * 3 + 2 ].pos = pInVertexData[ iV3 ].pos;
            pNewVertexData[ iFace * 3 + 2 ].normal = vFaceNormal; // pInVertexData[ iV3 ].normal;
            pNewVertexData[ iFace * 3 + 2 ].uv = pInVertexData[ iV3 ].uv;
        }
        pNewMesh->UnlockIndexBuffer();
        pNewMesh->UnlockVertexBuffer();
        pNewMesh->UnlockAttributeBuffer();
    }
    pInMesh->UnlockAttributeBuffer();
    pInMesh->UnlockVertexBuffer();
    pInMesh->UnlockIndexBuffer();

    DWORD dwMaterials = 1;
    D3DXMATERIAL d3dxMaterials[1];
    d3dxMaterials[0].MatD3D = g_Render.meshDroid.m_pMaterials[0];
    d3dxMaterials[0].pTextureFilename = "media\\droid\\EvilDrone_Diff.jpg";

    hr = pOutMesh->Create( pd3dDevice, pNewMesh, d3dxMaterials, dwMaterials );
    SAFE_RELEASE( pNewMesh );

    return hr;
}
Аватара пользователя
tikshoret
Шизофрения
Сообщения: 72
Зарегистрирован: 02.04.2009, 04:27

Re: Дневник Templar

Сообщение tikshoret »

Ничего себе, ты шаришь в программировании?
У одного священика спросили: Бог нам дает болезни в наказание?- На что он ответил: Что Вы, Бог нас любит и дает болезни нам в помощь!
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

tikshoret писал(а):Ничего себе, ты шаришь в программировании?

Ага.

Вторую функцию уже переделал для класса CMeshBuilder

Код: Выделить всё

HRESULT LoadFromCXFMesh(CXFMesh *pCMesh)
{
   ID3DXMesh* pInMesh=pCMesh->xfMesh.GetMesh();

    numF = pInMesh->GetNumFaces();
    numI = numF * 3;
   numV = pInMesh->GetNumVertices();

   tempV=new CVertex[numV];
   tempI=new DWORD[numI];

    WORD* pInIndexData;
    CVertex* pInVertexData;
    DWORD* pInAttribData;
    pInMesh->LockAttributeBuffer( D3DLOCK_READONLY, ( DWORD** )&pInAttribData );
    pInMesh->LockVertexBuffer( D3DLOCK_READONLY, ( VOID** )&pInVertexData );
    pInMesh->LockIndexBuffer( D3DLOCK_READONLY, ( VOID** )&pInIndexData );
    {
        for( DWORD iFace = 0; iFace < numF; iFace++ )
        {
            DWORD iV0 = pInIndexData[ iFace * 3 + 0 ];
            DWORD iV1 = pInIndexData[ iFace * 3 + 1 ];
            DWORD iV2 = pInIndexData[ iFace * 3 + 2 ];

         tempI[ iFace * 3 + 0 ]=iV0;
         tempI[ iFace * 3 + 1 ]=iV1;
         tempI[ iFace * 3 + 2 ]=iV2;

         tempV[iV0].pos = pInVertexData[ iV0 ].pos;
         tempV[iV1].pos = pInVertexData[ iV1 ].pos;
         tempV[iV2].pos = pInVertexData[ iV2 ].pos;
        }
    }
    pInMesh->UnlockAttributeBuffer();
    pInMesh->UnlockVertexBuffer();
    pInMesh->UnlockIndexBuffer();


    return S_OK;
}

для использования моделей в OpenGL это тоже пригодится
теперь буду добавлять в него первую для PhysX
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

Вот так я переделал функцию инициализации ландшафта. Кстати, я выкладываю код который я уже проверял на работоспособность.

Код: Выделить всё

NxTriangleMeshShapeDesc pxMeshShapeDesc;

HRESULT BuildPXMesh()
{
   NxMaterialIndex *pMaterials = new NxMaterialIndex[numF];
   for(NxU32 f=0;f<(NxU32)numF;f++)
      pMaterials[f]=materialRock;

   NxVec3* pVerts = new NxVec3[numV];
   for(NxU32 v=0;v<(NxU32)numV;v++)
      pVerts[v]=(NxVec3)tempV[v].pos;

   // Build physical model
   NxTriangleMeshDesc pxMeshDesc;
   pxMeshDesc.numVertices               = numV;
   pxMeshDesc.numTriangles            = numF;
   pxMeshDesc.pointStrideBytes         = sizeof(NxVec3);
   pxMeshDesc.triangleStrideBytes         = 3*sizeof(NxU32);
   pxMeshDesc.points                  = pVerts;
   pxMeshDesc.triangles               = tempI;                     
   pxMeshDesc.flags                  = 0;
   //add the mesh material data:
   pxMeshDesc.materialIndexStride         = sizeof(NxMaterialIndex);
   pxMeshDesc.materialIndices            = pMaterials;

   //pxMeshDesc.heightFieldVerticalAxis      = NX_Y;
   //pxMeshDesc.heightFieldVerticalExtent   = -1000.0f;


   //////
   pxMeshShapeDesc.shapeFlags |= NX_SF_FEATURE_INDICES;

   bool status = InitCooking(); if (!status) { printf("Unable to initialize the cooking library. Please make sure that you have correctly installed the latest version of the AGEIA PhysX SDK."); exit(1); }

    MemoryWriteBuffer buf;
     status = CookTriangleMesh(pxMeshDesc, buf); if (!status) { printf("Unable to cook a triangle mesh."); exit(1); }
     MemoryReadBuffer readBuffer(buf.data);
     
   pxMeshShapeDesc.meshData = gPhysicsSDK->createTriangleMesh(readBuffer);

   //
   // Please note about the created Triangle Mesh, user needs to release it when no one uses it to save memory. It can be detected
   // by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseTriangleMesh(*meshData);"
   //

   CloseCooking();

   return S_OK;
}


и это как сейчас выглядит сам класс CMeshBuilder

Код: Выделить всё

#include "CMeshBuilder_BuildDXMesh.h"
#include "DXDrawMesh.h"

class CMeshBuilder : public CMesh
{
public:
   CVertex *tempV;
   DWORD *tempI;
   int numV, numI, numF;

   #include "CMeshBuilder_LoadFromCXFMesh.h"
   #include "CMeshBuilder_BuildPXMesh.h"
   void Init(int tempSize)
   {
      tempV=new CVertex[tempSize];
      tempI=new DWORD[tempSize];
      numI=0; numV=0;
   }

   void Init(CXFMesh *pMesh)
   {
      LoadFromCXFMesh(pMesh);
   }
//------------------------------------
   void AddVertex(CVertex v)
   {
      tempV[numI]=v;
      tempI[numI]=numI; numI++; numV++;
   }

   void AddQuad(CVertex v0, CVertex v1, CVertex v2, CVertex v3)
   {
      //12
      //03
      AddVertex(v0); AddVertex(v1); AddVertex(v2);
      AddVertex(v0); AddVertex(v2); AddVertex(v3);
   }

//------------------------
   HRESULT Build()
   {
      HRESULT hr;
      V_RETURN( BuildDXMesh(&pMesh, tempV, tempI, numV, numI, g_aVertDecl) );
      //D3DXComputeNormals(pMesh, 0);
      return S_OK;
   }
   void EndBuild()
   {
      delete [] tempV;
      delete [] tempI;
   }


   void Scale(float x, float y, float z)
   {
      for(int v=0; v<numV; v++)
      {
         tempV[v].pos.x*=x;
         tempV[v].pos.y*=y;
         tempV[v].pos.z*=z;
      }
   }
};
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

скриншот с физикой
Изображение
теперь можно чтонибудь более вразумительно выглядящее делать
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

Ну вот и все, Аллилуйя, Иисус совсем не в восторге от моего public programming значит можно и даже нужно дальше не продолжать(для public в любых отношениях включая коммерческие проекты.)
Зеленк
Лечение общением
Сообщения: 1910
Зарегистрирован: 02.04.2009, 09:22

Re: Дневник Templar

Сообщение Зеленк »

Я думаю если я покрещущь в православного тамплиера, то Бог сможет мне прямо запретить а если не запретит то значит можно будет продолжать дальше. Без крещения мне не известно, нарушение ли(программирование почти без образования плюс с шизофренией) это воли атеистов. Пока я буду делать эмулятор OpenGL на DirectX это упростит создание движка, сразу для двух этих библиотек.
Ответить

Вернуться в «Дневник Templar»