VertexMapper::VertexMapper(SubMesh* subMesh, BufferAccess access) { ErrorFlags flags(ErrorFlag_ThrowException, true); VertexBuffer* buffer = nullptr; switch (subMesh->GetAnimationType()) { case AnimationType_Skeletal: { SkeletalMesh* skeletalMesh = static_cast<SkeletalMesh*>(subMesh); buffer = skeletalMesh->GetVertexBuffer(); break; } case AnimationType_Static: { StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh); buffer = staticMesh->GetVertexBuffer(); break; } } if (!buffer) { NazaraInternalError("Animation type not handled (0x" + String::Number(subMesh->GetAnimationType(), 16) + ')'); } m_mapper.Map(buffer, access); }
void ClusterTreeWidgetItem::setRenderable(MeshCluster* c) { list<StaticMesh*> meshes = c->getMeshes(); list<StaticMesh*>::iterator it; for(it = meshes.begin(); it != meshes.end(); it++) { StaticMesh* m = *it; TriangleMeshTreeWidgetItem* item = new TriangleMeshTreeWidgetItem(TriangleMeshItem); // Setup supported render modes int modes = 0; size_t n_pn; modes |= Mesh; modes |= Wireframe; item->setName(m->Name()); item->setNumFaces(m->getNumberOfFaces()); item->setNumVertices(m->getNumberOfVertices()); item->setRenderable(m); addChild(item); } m_renderable = c; }
StaticMesh* GraphicsEngineImp::CreateStaticMesh(string filename, D3DXVECTOR3 pos, Material* material) { StaticMesh* mesh = new StaticMesh(pos, filename); // if it is in memory dont put it on another thread. if(!this->useLoadingThread && GetResourceManager()->HasMeshStripsResource(filename.c_str())) { bool success = mesh->LoadFromFile(filename); if(success) { this->dx->CreateStaticMesh(mesh); } MaloW::Array<MeshStrip*>* strips = mesh->GetStrips(); for(unsigned int i = 0; i < strips->size(); i++) { strips->get(i)->SetMaterial(material); if(i+1 < strips->size()) { material = new Material(material); } } } else { LoadMeshEvent* re = new LoadMeshEvent(filename, mesh, NULL, material); this->PutEvent(re); } return mesh; }
void XmlSceneParser::Parse (const ParseNode& decl, StaticMesh& node, Node& parent, SceneContext& context) { try { //предварительный разбор StaticMeshDeclPtr node_decl = impl->PrepareStaticMesh (decl); //настройка узла node.SetMeshName (node_decl->source.c_str ()); //set bound box only if either min or max value is present, otherwise leave infinite bound box if (node_decl->min_bound.state || node_decl->max_bound.state) { bound_volumes::aaboxf box; if (node_decl->min_bound.state) box.set_minimum (node_decl->min_bound.value); if (node_decl->max_bound.state) box.set_maximum (node_decl->max_bound.value); node.SetBoundBox (box); } //разбор родительских параметров Parse (decl, static_cast<Entity&> (node), parent, context); } catch (xtl::exception& e) { e.touch ("scene_graph::XmlSceneParser::Parse(const ParseNode&,StaticMesh&,Node&,SceneContext&)"); throw; } }
void ConstructQuadMesh(StaticMesh& mesh) { Vertex tempVertex; std::vector<Vertex> quadVertices; tempVertex.position = Vector3(-1, -1, 0); tempVertex.uv = Vector2(0, 0); quadVertices.push_back(tempVertex); tempVertex.position = Vector3(-1, 1, 0); tempVertex.uv = Vector2(0, 1); quadVertices.push_back(tempVertex); tempVertex.position = Vector3(1, -1, 0); tempVertex.uv = Vector2(1, 0); quadVertices.push_back(tempVertex); tempVertex.position = Vector3(1, 1, 0); tempVertex.uv = Vector2(1, 1); quadVertices.push_back(tempVertex); std::vector<GLuint> quadIndices; quadIndices.push_back(0); quadIndices.push_back(2); quadIndices.push_back(1); quadIndices.push_back(1); quadIndices.push_back(2); quadIndices.push_back(3); mesh.BufferData(quadVertices, quadIndices); }
void Mesh::Transform(const Matrix4f& matrix) { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Mesh not created"); return; } if (m_impl->animationType != AnimationType_Static) { NazaraError("Mesh must be static"); return; } #endif if (matrix.IsIdentity()) return; for (SubMesh* subMesh : m_impl->subMeshes) { StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh); BufferMapper<VertexBuffer> mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite); MeshVertex* vertices = static_cast<MeshVertex*>(mapper.GetPointer()); Boxf aabb(vertices->position.x, vertices->position.y, vertices->position.z, 0.f, 0.f, 0.f); unsigned int vertexCount = staticMesh->GetVertexCount(); for (unsigned int i = 0; i < vertexCount; ++i) { vertices->position = matrix.Transform(vertices->position); aabb.ExtendTo(vertices->position); vertices++; } staticMesh->SetAABB(aabb); } // Il ne faut pas oublier d'invalider notre AABB m_impl->aabbUpdated = false; }
void Mesh::Recenter() { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Mesh not created"); return; } if (m_impl->animationType != AnimationType_Static) { NazaraError("Mesh must be static"); return; } #endif // Le centre de notre mesh est le centre de l'AABB *globale* Vector3f center = GetAABB().GetCenter(); for (SubMesh* subMesh : m_impl->subMeshes) { StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh); BufferMapper<VertexBuffer> mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite); MeshVertex* vertices = static_cast<MeshVertex*>(mapper.GetPointer()); unsigned int vertexCount = staticMesh->GetVertexCount(); for (unsigned int i = 0; i < vertexCount; ++i) { vertices->position -= center; vertices++; } // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé Boxf aabb = staticMesh->GetAABB(); aabb.Translate(-center); staticMesh->SetAABB(aabb); } // Il ne faut pas oublier d'invalider notre AABB m_impl->aabbUpdated = false; }
StaticMesh* GraphicsEngineImp::CreateStaticMesh(string filename, D3DXVECTOR3 pos, const char* billboardFilePath, float distanceToSwapToBillboard) { StaticMesh* mesh = new StaticMesh(pos, filename, billboardFilePath, distanceToSwapToBillboard); // if it is in memory dont put it on another thread. if(!this->useLoadingThread && GetResourceManager()->HasMeshStripsResource(filename.c_str())) { bool success = mesh->LoadFromFile(filename); if(success) { this->dx->CreateStaticMesh(mesh); } } else { LoadMeshEvent* re = new LoadMeshEvent(filename, mesh, NULL, NULL); this->PutEvent(re); } return mesh; }
void test() { GraphicsEngine* ge = GetGraphicsEngine(); // Example of GE useage GraphicsEngine* eng = GetGraphicsEngine(); eng->GetCamera()->setPosition(D3DXVECTOR3(0, 15, -15.6f)); eng->GetCamera()->LookAt(D3DXVECTOR3(30, 10, 10)); StaticMesh* testBall = eng->CreateStaticMesh("Media/Ball.obj", D3DXVECTOR3(8, 15, 8)); StaticMesh* testCylinder = eng->CreateStaticMesh("Media/Cylinder.obj", D3DXVECTOR3(10, 10, 10)); StaticMesh* bth = eng->CreateStaticMesh("Media/bth.obj", D3DXVECTOR3(5, 20, 15)); AnimatedMesh* flag = eng->CreateAnimatedMesh("Media/FlagRed.ani", D3DXVECTOR3(8, 15, 8)); flag->LoopSeamless(); AnimatedMesh* flagb = eng->CreateAnimatedMesh("Media/FlagBlue.ani", D3DXVECTOR3(10, 15, 8)); flagb->LoopSeamless(); StaticMesh* flag1 = eng->CreateStaticMesh("Media/FlagBlue1.obj", D3DXVECTOR3(12, 15, 8)); StaticMesh* flag2 = eng->CreateStaticMesh("Media/FlagBlue2.obj", D3DXVECTOR3(14, 15, 8)); StaticMesh* flag3 = eng->CreateStaticMesh("Media/FlagBlue3.obj", D3DXVECTOR3(16, 15, 8)); StaticMesh* flag4 = eng->CreateStaticMesh("Media/FlagBlue4.obj", D3DXVECTOR3(18, 15, 8)); StaticMesh* flag5 = eng->CreateStaticMesh("Media/FlagBlue5.obj", D3DXVECTOR3(20, 15, 8)); StaticMesh* ball1 = eng->CreateStaticMesh("Media/Ball1.obj", D3DXVECTOR3(12, 30, 8)); StaticMesh* ball2 = eng->CreateStaticMesh("Media/Ball2.obj", D3DXVECTOR3(14, 30, 8)); StaticMesh* ball3 = eng->CreateStaticMesh("Media/Ball3.obj", D3DXVECTOR3(16, 30, 8)); StaticMesh* ball4 = eng->CreateStaticMesh("Media/Ball4.obj", D3DXVECTOR3(18, 30, 8)); //StaticMesh* wlmap = eng->CreateStaticMesh("Media/WarlockMap.obj", D3DXVECTOR3(100, 4, 8)); //StaticMesh* hb = eng->CreateStaticMesh("Media/HardenedBall.obj", D3DXVECTOR3(12, 15, 12)); bth->Scale(0.1f); Light* testLight = eng->CreateLight(D3DXVECTOR3(15, 30, 15)); testLight->SetLookAt(testBall->GetPosition()); //testBall->SetSpecialColor(RED_COLOR); //testCylinder->SetSpecialColor(GREEN_COLOR); //AnimatedMesh* ani = eng->CreateAnimatedMesh("Media/AniTest.ani", D3DXVECTOR3(12, 16, 12)); //ani->LoopNormal(); //ani->LoopSeamless(); SoundEngine* seng = eng->GetSoundEngine(); SoundEffect* se1 = seng->LoadSoundEffect("Media/Sounds/SoundEffects/ball_vs_ball.mp3", false); //SoundEffect* se2 = seng->LoadSoundEffect("Media/Sounds/SoundEffects/ball_vs_wall.mp3", false); //SoundSong* ss1 = seng->LoadSong("Media/Sounds/Songs/america_fuck_yeah.mp3", true); seng->SetMasterVolume(0.5f); //ss1->Play(); //eng->LoadingScreen("Media/LoadingScreen/LoadingScreenBG.png", "Media/LoadingScreen/LoadingScreenPB.png"); // going to LoadingScreen to load the above meshes //eng->LoadingScreen("Media/LoadingScreen/LoadingScreenBG.png", "Media/LoadingScreen/LoadingScreenPB.png", 0.0f, 1.0f, 1.0f, 1.0f); eng->LoadingScreen("Media/LoadingScreen/StartScreen.png", "", 0.0f, 1.0f, 1.0f, 1.0f); Text* text = eng->CreateText("Lol ", D3DXVECTOR2(500, 500), 1.0f, "Media/Fonts/1"); //Image* testImg = eng->CreateImage(D3DXVECTOR2(50, 50), D3DXVECTOR2(500, 75), "Media/PowerBall.png"); //testLight->SetPosition(testBall->GetPosition() + D3DXVECTOR3(0, 5, 0)); //testLight->SetLookAt(testLight->GetPosition() - D3DXVECTOR3(0, 5, 0)); //Light* testLight2 = eng->CreateLight(D3DXVECTOR3(3, 20, 3)); CamRecording* camRec = new CamRecording(2000, true); // How many milliseconds between each way point camRec->Init(eng->GetCamera()); /*camRec->AddCameraWaypoint(D3DXVECTOR3(0, 0, 0), D3DXVECTOR3(8, 16, 8)); camRec->AddCameraWaypoint(D3DXVECTOR3(0, 30, 0), D3DXVECTOR3(8, 16, 8)); camRec->AddCameraWaypoint(D3DXVECTOR3(30, 30, 30), D3DXVECTOR3(8, 16, 8)); camRec->AddCameraWaypoint(D3DXVECTOR3(-20, 20, 30), D3DXVECTOR3(8, 16, 8)); camRec->AddCameraWaypoint(D3DXVECTOR3(0, 50, 0), D3DXVECTOR3(8, 16, 8)); camRec->AddCameraWaypoint(D3DXVECTOR3(0, 20, 0), D3DXVECTOR3(8, 16, 8));*/ //camRec->Load(CIRCLE_AROUND); camRec->CircleAround(true, 50, 1000, 0, D3DXVECTOR3(30, 50, 0), D3DXVECTOR3(0,0,30)); bool sw = true; float size = 1.0f; bool go = true; while(eng->isRunning() && go) // Returns true as long as ESC hasnt been pressed, if it's pressed the game engine will shut down itself (to be changed) { float diff = eng->Update(); // Updates camera etc, does NOT render the frame, another process is doing that, so diff should be very low. text->SetText("Distance to Lava: " + MaloW::convertNrToString(eng->GetCamera()->getPosition().y - eng->GetLavaHeightAt(eng->GetCamera()->getPosition().x, eng->GetCamera()->getPosition().z))); //testBall->Rotate(D3DXVECTOR3(2*PI, 0, 0) * (diff/1000.0f)); // Divide diff by 1000 to get seconds since diff is in milliseconds. testBall->RotateAxis(D3DXVECTOR3(2, 0, 0), 2* PI * (diff/1000.0f)); // Divide diff by 1000 to get seconds since diff is in milliseconds. CursorControl cc; if(eng->GetKeyListener()->IsPressed('W')) eng->GetCamera()->moveForward(diff); if(eng->GetKeyListener()->IsPressed(VK_RETURN)) // For keys other than the main-chars you use the VK_ Enums, rightclick on VK_RETURN and "Go to definition" to find the list of all keys cc.SetVisibility(true); if(eng->GetKeyListener()->IsPressed('A')) eng->GetCamera()->moveLeft(diff); if(eng->GetKeyListener()->IsPressed('S')) eng->GetCamera()->moveBackward(diff); if(eng->GetKeyListener()->IsPressed('D')) eng->GetCamera()->moveRight(diff); if(eng->GetKeyListener()->IsPressed(VK_ESCAPE)) go = false; if(eng->GetKeyListener()->IsPressed(VK_BACK)) { if(sw) { //se1->Play(); text->DeleteFromEnd(1); } sw = false; } else sw = true; if(eng->GetKeyListener()->IsClicked(1)) { size += diff * 0.001f; text->SetSize(size); //ss1->SetVolume(0.5f); text->AppendText("LoL "); //ss1->Play(); } //else //se1->Play(); if(eng->GetKeyListener()->IsClicked(2)) { testBall->UseInvisibilityEffect(true); } else testBall->UseInvisibilityEffect(false); if(eng->GetKeyListener()->IsPressed('G')) { //ani->LoopNormal(); flag->LoopNormal(); flagb->LoopNormal(); eng->GetEngineParameters().FXAAQuality = 4; ge->GetEngineParameters().FXAAQuality = 4; //camRec->Play(); // Play to start moving the camera along the path } camRec->Update(diff); // update needed to move the camera when play is initialized. if(eng->GetKeyListener()->IsPressed('V')) { //ani->NoLooping(); flag->NoLooping(); flagb->NoLooping(); } if(eng->GetKeyListener()->IsPressed('B')) { //ani->LoopSeamless(); flag->LoopSeamless(); flagb->LoopSeamless(); eng->GetEngineParameters().FXAAQuality = 0; //ge->GetEngineParameters().FXAAQuality = 0; for(int i = 0; i < 200; i++) { //se1->Play(); } } } // Delete camera recording delete camRec; }
void DxManager::CalculateCulling() { D3DXMATRIX view = this->camera->GetViewMatrix(); D3DXMATRIX proj = this->camera->GetProjectionMatrix(); /* float zMinimum = -proj._43 / proj._33; float r = this->params.FarClip / (this->params.FarClip - zMinimum); proj._33 = r; proj._43 = -r * zMinimum; */ D3DXMATRIX VP; D3DXMatrixMultiply(&VP, &view, &proj); // Calculate near plane of frustum. FrustrumPlanes[0].a = VP._14 + VP._13; FrustrumPlanes[0].b = VP._24 + VP._23; FrustrumPlanes[0].c = VP._34 + VP._33; FrustrumPlanes[0].d = VP._44 + VP._43; D3DXPlaneNormalize(&FrustrumPlanes[0], &FrustrumPlanes[0]); // Calculate far plane of frustum. FrustrumPlanes[1].a = VP._14 - VP._13; FrustrumPlanes[1].b = VP._24 - VP._23; FrustrumPlanes[1].c = VP._34 - VP._33; FrustrumPlanes[1].d = VP._44 - VP._43; D3DXPlaneNormalize(&FrustrumPlanes[1], &FrustrumPlanes[1]); // Calculate left plane of frustum. FrustrumPlanes[2].a = VP._14 + VP._11; FrustrumPlanes[2].b = VP._24 + VP._21; FrustrumPlanes[2].c = VP._34 + VP._31; FrustrumPlanes[2].d = VP._44 + VP._41; D3DXPlaneNormalize(&FrustrumPlanes[2], &FrustrumPlanes[2]); // Calculate right plane of frustum. FrustrumPlanes[3].a = VP._14 - VP._11; FrustrumPlanes[3].b = VP._24 - VP._21; FrustrumPlanes[3].c = VP._34 - VP._31; FrustrumPlanes[3].d = VP._44 - VP._41; D3DXPlaneNormalize(&FrustrumPlanes[3], &FrustrumPlanes[3]); // Calculate top plane of frustum. FrustrumPlanes[4].a = VP._14 - VP._12; FrustrumPlanes[4].b = VP._24 - VP._22; FrustrumPlanes[4].c = VP._34 - VP._32; FrustrumPlanes[4].d = VP._44 - VP._42; D3DXPlaneNormalize(&FrustrumPlanes[4], &FrustrumPlanes[4]); // Calculate bottom plane of frustum. FrustrumPlanes[5].a = VP._14 + VP._12; FrustrumPlanes[5].b = VP._24 + VP._22; FrustrumPlanes[5].c = VP._34 + VP._32; FrustrumPlanes[5].d = VP._44 + VP._42; D3DXPlaneNormalize(&FrustrumPlanes[5], &FrustrumPlanes[5]); //Terrain for(int i = 0; i < this->terrains.size(); i++) { Terrain* terr = this->terrains.get(i); float scale = max(terr->GetScale().x, max(terr->GetScale().y, terr->GetScale().z)); if(pe.FrustrumVsSphere(this->FrustrumPlanes, terr->GetBoundingSphere(), terr->GetWorldMatrix(), scale)) { terr->SetCulled(false); } else { terr->SetCulled(true); } } //Static meshes for(int i = 0; i < this->objects.size(); i++) { StaticMesh* ms = this->objects.get(i); MaloW::Array<MeshStrip*>* strips = ms->GetStrips(); for(int u = 0; u < strips->size(); u++) { MeshStrip* s = strips->get(u); float scale = max(ms->GetScaling().x, max(ms->GetScaling().y, ms->GetScaling().z)); if(pe.FrustrumVsSphere(this->FrustrumPlanes, s->GetBoundingSphere(), ms->GetWorldMatrix(), scale)) { s->SetCulled(false); } else { s->SetCulled(true); } } } //Animated meshes for(int i = 0; i < this->animations.size(); i++) { AnimatedMesh* ms = this->animations.get(i); MeshStrip* s = ms->GetStrips()->get(0); float scale = max(ms->GetScaling().x, max(ms->GetScaling().y, ms->GetScaling().z)); if(pe.FrustrumVsSphere(this->FrustrumPlanes, s->GetBoundingSphere(), ms->GetWorldMatrix(), scale)) { s->SetCulled(false); } else { s->SetCulled(true); } } }
//! Loads and returns a static model from a file. StaticModel* ModelImporter::LoadStaticModel(string filename) { // Is the model already loaded? if(mStaticModelMap.find(filename) != mStaticModelMap.end()) return mStaticModelMap[filename]; Assimp::Importer importer; mFilename = filename; StaticModel* model = NULL; // Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together. // Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this. importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE); // Load scene from the file. const aiScene* scene = importer.ReadFile(filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_SplitLargeMeshes | aiProcess_ConvertToLeftHanded | aiProcess_SortByPType); // Successfully loaded the scene. if(scene) { // Create the model that is getting filled out. model = new StaticModel(); // Loop through all meshes. for(int i = 0; i < scene->mNumMeshes; i++) { aiMesh* assimpMesh = scene->mMeshes[i]; vector<Vertex> vertices; vector<UINT> indices; // Add vertices to the vertex list. for(int i = 0; i < assimpMesh->mNumVertices; i++) { aiVector3D v = assimpMesh->mVertices[i]; aiVector3D n = assimpMesh->mNormals[i]; aiVector3D t = aiVector3D(0, 0, 0); if(assimpMesh->HasTextureCoords(0)) t = assimpMesh->mTextureCoords[0][i]; n = n.Normalize(); Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y); vertices.push_back(vertex); } // Add indices to the index list. for(int i = 0; i < assimpMesh->mNumFaces; i++) for(int j = 0; j < assimpMesh->mFaces[i].mNumIndices; j++) indices.push_back(assimpMesh->mFaces[i].mIndices[j]); // Get the path to the texture in the directory. aiString path; aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex]; material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); FindValidPath(&path); // Extract all the ambient, diffuse and specular colors. aiColor4D ambient, diffuse, specular; material->Get(AI_MATKEY_COLOR_AMBIENT, ambient); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); material->Get(AI_MATKEY_COLOR_SPECULAR, specular); // Create the mesh and its primitive. StaticMesh* mesh = new StaticMesh(); Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices); mesh->SetPrimitive(primitive); mesh->SetVertices(vertices); mesh->SetIndices(indices); mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive); // Any texture? if(_stricmp(path.C_Str(), "") != 0) mesh->LoadTexture(path.C_Str()); // Any normal map? aiString nmap; material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap); FindValidPath(&nmap); if(_stricmp(nmap.C_Str(), "") != 0) mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str())); // [NOTE] The material is set to white. mesh->SetMaterial(Material(Colors::White)); // Was before [NOTE] model->SetFilename(filename); // Add the mesh to the model. model->AddMesh(mesh); } // Add to the model map and return it. mStaticModelMap[filename] = model; return mStaticModelMap[filename]; } else { char buffer[246]; sprintf(buffer, "Error loading model: %s", filename.c_str()); MessageBox(0, buffer, "Error!", 0); mStaticModelMap[filename] = LoadStaticModel("models/box.obj"); return mStaticModelMap[filename]; } }