void ContinuousCollision1(DemoEntityManager* const scene) { scene->CreateSkyBox(); // just see ground. it's not a rigid body. char fileName[2048]; GetWorkingFileName("flatPlane.ngd", fileName); scene->LoadScene(fileName); dVector pos(0.0f); pos.m_x = 0.0f; pos.m_y = 50.0f; pos.m_z = 0.0f; dQuaternion rot(dVector(1.f,0.f,0.f),(dFloat)M_PI/4.0f); scene->SetCameraMatrix(rot, pos); CreateBackgroundWallsAndCellingBody(scene->GetNewton()); new CCDInputManager(scene); // compel to change debug display mode. just for convenience. NewtonDemos* const mainWindow = scene->GetRootWindow(); mainWindow->m_debugDisplayMode = 2; }
void BasicBoxStacks (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); CreateLevelMesh (scene, "flatPlane.ngd", 1); // load the scene from a ngd file format #if 0 char fileName[2048]; //GetWorkingFileName ("boxStacks_1.ngd", fileName); //GetWorkingFileName ("boxStacks_3.ngd", fileName); //GetWorkingFileName ("boxStacks.ngd", fileName); //GetWorkingFileName ("pyramid20x20.ngd", fileName); GetWorkingFileName ("pyramid40x40.ngd", fileName); scene->LoadScene (fileName); #else int high = 30; PrimitiveType selection[] = {_BOX_PRIMITIVE, _CYLINDER_PRIMITIVE, _TAPERED_CYLINDER_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE}; for (int i = 0; i < 1; i ++) { int index = i % (sizeof (selection) / sizeof (selection[0])); //index = 0; dMatrix shapeMatrix (dRollMatrix(0.5f * 3.14159f)); if (selection[index] == _BOX_PRIMITIVE) { shapeMatrix = dGetIdentityMatrix(); } // BuildPyramid (scene, 10.0f, dVector(-10.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, selection[index], shapeMatrix); BuildPyramid (scene, 10.0f, dVector( 0.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _BOX_PRIMITIVE); // BuildPyramid (scene, 10.0f, dVector( 10.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _CYLINDER_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); // BuildPyramid (scene, 10.0f, dVector( 20.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _TAPERED_CYLINDER_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); // BuildPyramid (scene, 10.0f, dVector( 30.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _REGULAR_CONVEX_HULL_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); } high = 20; for (int i = 0; i < 1; i ++) { for (int j = 0; j < 1; j ++) { // BuildJenga (scene, 5.0f, dVector(-15.0f + j * 8, 0.0f, 10.0f + i * 8, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high); } } #endif // place camera into position dQuaternion rot; dVector origin (-40.0f, 10.0f, 0.0f, 0.0f); //origin.m_x = -10.0f; origin.m_x = -20.0f; origin.m_y = 8.0f; scene->SetCameraMatrix(rot, origin); // ExportScene (scene->GetNewton(), "../../../media/test1.ngd"); }
static DemoEntityManager::dListNode* LoadScene(DemoEntityManager* const scene, const char* const name, const dMatrix& location) { char fileName[2048]; GetWorkingFileName (name, fileName); DemoEntityManager::dListNode* const lastEnt = scene->GetLast(); scene->LoadScene (fileName); for (DemoEntityManager::dListNode* node = lastEnt->GetNext(); node; node = node->GetNext()) { DemoEntity* const entity = node->GetInfo(); dMatrix matrix (entity->GetNextMatrix() * location); entity->ResetMatrix(*scene, matrix); } return lastEnt->GetNext(); }
void SaveNewtonMesh (NewtonMesh* const mesh, const char* const name) { char fileName[2048]; GetWorkingFileName (name, fileName); FILE* const file = fopen (fileName, "wb"); if (file) { const char* const header = D_MESH_HEADER; fwrite (header, strlen(D_MESH_HEADER), 1, file); int size = strlen(name); fwrite (&size, sizeof (int), 1, file); fwrite (name, size, 1, file); NewtonMeshSerialize (mesh, DemoEntityManager::SerializeFile, file); fclose (file); } }
void ShaderPrograms::LoadShaderCode (const char* filename, char *buffer) { int size; FILE* file; char fullPathName[2048]; GetWorkingFileName (filename, fullPathName); file = fopen (fullPathName, "rb"); fseek (file, 0, SEEK_END); size = ftell (file); fseek (file, 0, SEEK_SET); fread (buffer, size, 1, file); fclose (file); buffer[size] = 0; buffer[size + 1] = 0; }
static void AddStaticMesh(DemoEntityManager* const scene) { char fileName[2048]; NewtonWorld* const world = scene->GetNewton(); GetWorkingFileName ("ramp.off", fileName); NewtonMesh* const ntMesh = NewtonMeshLoadOFF(world, fileName); dMatrix matrix (dGetIdentityMatrix()); DemoMesh* mesh = new DemoMesh(ntMesh); DemoEntity* const entity = new DemoEntity(matrix, NULL); entity->SetMesh(mesh, dGetIdentityMatrix()); mesh->Release(); scene->Append(entity); CreateLevelMeshBody (world, entity, true); NewtonMeshDestroy (ntMesh); }
NewtonMesh* LoadNewtonMesh (NewtonWorld* const world, const char* const name) { char fileName[2048]; GetWorkingFileName (name, fileName); NewtonMesh* mesh = NULL; FILE* const file = fopen (fileName, "rb"); if (file) { char name[2048]; fread (name, strlen(D_MESH_HEADER), 1, file); if (!strncmp (name, D_MESH_HEADER, strlen(D_MESH_HEADER))) { int size; fread (&size, sizeof (int), 1, file); dAssert (size < int (sizeof (name))); fread (name, size, 1, file); name[size] = 0; mesh = NewtonMeshCreateFromSerialization (world, DemoEntityManager::DeserializeFile, file); } fclose (file); } return mesh; }
NewtonBody* CreateLevelMesh (DemoEntityManager* const scene, const char* const name, bool optimized) { // load the scene from a ngd file format char fileName[2048]; GetWorkingFileName (name, fileName); scene->LoadScene (fileName); NewtonBody* levelBody = NULL; NewtonWorld* const world = scene->GetNewton(); for (DemoEntityManager::dListNode* node = scene->GetLast(); node; node = node->GetPrev()) { DemoEntity* const ent = node->GetInfo(); DemoMesh* const mesh = (DemoMesh*) ent->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); if (mesh) { if (mesh->GetName() == "levelGeometry_mesh") { levelBody = CreateLevelMeshBody (world, ent, optimized); break; } } } return levelBody; }
void DemoEntityManager::CreateOpenGlFont() { FT_Library library; FT_Error error = FT_Init_FreeType (&library); if ( !error ) { char fileName[2048]; //GetWorkingFileName ("arial.ttf", fileName); //GetWorkingFileName ("calibri.ttf", fileName); GetWorkingFileName ("courbd.ttf", fileName); FT_Face face[96]; int withInPixels = 12; int heightInPixels = 16; int width = 0; int height = 0; for (int ch = 0; ch < 96; ch ++) { // Load The Glyph For Our Character. error = FT_New_Face( library, fileName, 0, &face[ch] ); dAssert (!error); FT_Face bitmap = face[ch]; error = FT_Set_Char_Size(bitmap, withInPixels * 64, heightInPixels * 64, 96, 96); dAssert (!error); FT_UInt index = FT_Get_Char_Index( face[ch], ch + ' '); //FT_UInt index = FT_Get_Char_Index (bitmap, 'A'); error = FT_Load_Glyph (bitmap, index, FT_LOAD_DEFAULT ); dAssert (!error); error = FT_Render_Glyph (bitmap->glyph, FT_RENDER_MODE_NORMAL); dAssert (!error); const FT_Glyph_Metrics& metrics = bitmap->glyph->metrics; int w = metrics.width / 64; int h = metrics.height / 64; width += w; height = (height > h) ? height : h; } int imageWidth = TwosPower (width); int imageHeight = TwosPower (height); char* const image = new char[2 * imageWidth * imageHeight]; memset (image, 0, 2 * imageWidth * imageHeight); int maxWidth = 0; int imageBase = 0; for (int ch = 0; ch < 96; ch ++) { FT_Face bitmap = face[ch]; FT_GlyphSlot slot = bitmap->glyph; const FT_Glyph_Metrics& metrics = slot->metrics; int w = metrics.width / 64; int h = metrics.height / 64; maxWidth = (w > maxWidth) ? w : maxWidth; if (w) { const unsigned char* const buffer = slot->bitmap.buffer; int pitch = slot->bitmap.pitch; int posit = imageBase; for (int j = 0; j < h; j ++) { for (int i = 0; i < w; i ++) { int color = buffer[j * pitch + i]; image[posit + i * 2 + 0] = color; image[posit + i * 2 + 1] = color; } posit += imageWidth * 2; } imageBase += w * 2; } } // make th open gl display list here m_fontImage = LoadImage("fontTexture", image, imageWidth, imageHeight, m_luminace); m_font = glGenLists(96); glBindTexture(GL_TEXTURE_2D, m_fontImage); imageBase = 0; for (int ch = 0; ch < 96; ch ++) { FT_Face bitmap = face[ch]; FT_GlyphSlot slot = bitmap->glyph; const FT_Glyph_Metrics& metrics = slot->metrics; glNewList(m_font + ch, GL_COMPILE); glPushMatrix(); // glTranslatef(slot->bitmap_left, 64 - slot->bitmap_top, 0); glTranslatef(slot->bitmap_left, - slot->bitmap_top, 0); dFloat w = dFloat (metrics.width / 64); dFloat h = dFloat (metrics.height / 64); if (w) { dFloat u0 = dFloat (imageBase) / imageWidth; dFloat u1 = dFloat (imageBase + w - 1.0f) / imageWidth; dFloat v0 = 0.0f; dFloat v1 = (h - 1.0f) / imageHeight; glBegin(GL_QUADS); glTexCoord2d (u0, v0); glVertex2i(0, 0); glTexCoord2d (u0, v1); glVertex2i(0, h - 1); glTexCoord2d (u1, v1); glVertex2i (w - 1, h - 1); glTexCoord2d (u1, v0); glVertex2i (w - 1, 0); glEnd(); imageBase += w; } glPopMatrix(); //glTranslatef(maxWidth, 0, 0); glTranslatef(metrics.horiAdvance / 64, 0, 0); glEndList(); FT_Done_Face(bitmap); } delete[] image; // destroy the free type library FT_Done_FreeType (library); } }
// Loads the texture from the specified file and stores it in iTexture. Note // that we're using the GLAUX library here, which is generally discouraged, // but in this case spares us having to write a bitmap loading routine. GLuint LoadTexture(const char* const filename) { #pragma pack(1) struct TGAHEADER { GLbyte identsize; // Size of ID field that follows header (0) GLbyte colorMapType; // 0 = None, 1 = palette GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle unsigned short colorMapStart; // First color map entry unsigned short colorMapLength; // Number of colors unsigned char colorMapBits; // bits per palette entry unsigned short xstart; // image x origin unsigned short ystart; // image y origin unsigned short width; // width in pixels unsigned short height; // height in pixels GLbyte bits; // bits per pixel (8 16, 24, 32) GLbyte descriptor; // image descriptor }; #pragma pack(8) char fullPathName[TERXTURE_PATH_NAME_SIZE ]; GetWorkingFileName (filename, fullPathName); TextureCache& cache = TextureCache::GetChache(); GLuint texture = cache.GetTexture(fullPathName); if (!texture) { FILE* const pFile = fopen (fullPathName, "rb"); if(pFile == NULL) { return 0; } //_ASSERTE (sizeof (TGAHEADER) == 18); // Read in header (binary) sizeof(TGAHEADER) = 18 TGAHEADER tgaHeader; // TGA file header fread(&tgaHeader, 18, 1, pFile); // Do byte swap for big vs little Indian tgaHeader.colorMapStart = SWAP_INT16(tgaHeader.colorMapStart); tgaHeader.colorMapLength = SWAP_INT16(tgaHeader.colorMapLength); tgaHeader.xstart = SWAP_INT16(tgaHeader.xstart); tgaHeader.ystart = SWAP_INT16(tgaHeader.ystart); tgaHeader.width = SWAP_INT16(tgaHeader.width); tgaHeader.height = SWAP_INT16(tgaHeader.height); // Get width, height, and depth of texture GLint iWidth = tgaHeader.width; GLint iHeight = tgaHeader.height; short sDepth = tgaHeader.bits / 8; _ASSERTE ((sDepth == 3) || (sDepth == 4)); // Put some validity checks here. Very simply, I only understand // or care about 8, 24, or 32 bit targa's. if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32) { fclose(pFile); return 0; } // Calculate size of image buffer unsigned lImageSize = tgaHeader.width * tgaHeader.height * sDepth; // Allocate memory and check for success GLbyte* const pBits = new GLbyte [tgaHeader.width * tgaHeader.height * 4]; if(pBits == NULL) { fclose(pFile); return 0; } // Read in the bits // Check for read error. This should catch RLE or other // weird formats that I don't want to recognize if(fread(pBits, lImageSize, 1, pFile) != 1) { fclose(pFile); delete[] pBits; return 0; } GLenum eFormat = GL_RGBA; GLint iComponents = 4; switch(sDepth) { // intel arch case 3: // Most likely case //eFormat = GL_BGR_EXT; eFormat = GL_BGR; //iComponents = GL_RGB; iComponents = 4; break; case 4: eFormat = GL_BGRA; //eFormat = GL_BGRA_EXT; //iComponents = GL_RGBA; iComponents = 4; break; case 1: eFormat = GL_LUMINANCE; iComponents = 1; break; }; texture = 0; glGenTextures(1, &texture); if (texture) { //GLenum errr = glGetError (); glBindTexture(GL_TEXTURE_2D, texture); // select modulate to mix texture with color for shading glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits); // when texture area is small, bilinear filter the closest mipmap // glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); // when texture area is small, trilinear filter mipmaped glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // when texture area is large, bilinear filter the first mipmap glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // build our texture mipmaps gluBuild2DMipmaps (GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBits); // Done with File fclose(pFile); delete[] pBits; cache.InsertText (fullPathName, texture); } } return texture; }
void AddCollisionTreeMesh (DemoEntityManager* const scene) { // open the level data char fullPathName[2048]; GetWorkingFileName ("playground.ngd", fullPathName); scene->LoadScene (fullPathName); // find the visual mesh and make a collision tree NewtonWorld* const world = scene->GetNewton(); DemoEntity* const entity = scene->GetLast()->GetInfo(); DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0); NewtonTreeCollisionBeginBuild(tree); dFloat* const vertex = mesh->m_vertex; for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){ DemoSubMesh* const subMesh = &node->GetInfo(); unsigned int* const indices = subMesh->m_indexes; int trianglesCount = subMesh->m_indexCount; for (int i = 0; i < trianglesCount; i += 3) { dVector face[3]; int index = indices[i + 0] * 3; face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 1] * 3; face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 2] * 3; face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); int matID = 0; //matID = matID == 2 ? 1 : 2 ; NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID); } } NewtonTreeCollisionEndBuild (tree, 0); // add the collision tree to the collision scene void* const proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, tree); // destroy the original tree collision NewtonDestroyCollision (tree); // set the parameter on the added collision share dMatrix matrix (entity->GetCurrentMatrix()); NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(collisionTree, mesh); // set the application level callback #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces); #endif mesh->AddRef(); scene->RemoveEntity (entity); #ifdef USE_TEST_ALL_FACE_USER_RAYCAST_CALLBACK // set a ray cast callback for all face ray cast NewtonTreeCollisionSetUserRayCastCallback (collisionTree, AllRayHitCallback); dVector p0 (0, 100, 0, 0); dVector p1 (0, -100, 0, 0); dVector normal(0.0f); dLong id; dFloat parameter; parameter = NewtonCollisionRayCast (collisionTree, &p0[0], &p1[0], &normal[0], &id); #endif }