CLightProbe::CLightProbe( const CXMLTreeNode& aXMLNode ) { for ( int i = 0, l_NumChilds = aXMLNode.GetNumChildren(); i < l_NumChilds; ++i ) { CXMLTreeNode& l_CurrentNode = aXMLNode( i ); std::string lTagName( l_CurrentNode.GetName() ); if (lTagName == "center") mPosition = l_CurrentNode.GetAttribute<Math::Vect3f>( "pos", Math::Vect3f(0.0f) ); if (lTagName == "vertexs") { for ( int j = 0, l_NumVertexs = l_CurrentNode.GetNumChildren(); j < l_NumVertexs; ++j ) { CXMLTreeNode l_VertexNode = l_CurrentNode( j ); std::string lVertexTag( l_VertexNode.GetName() ); if (lVertexTag == "vertex") { Math::Vect3f lPos( l_VertexNode.GetAttribute<Math::Vect3f>( "pos", Math::Vect3f(0.0f) )); Math::Vect2f lUV( l_VertexNode.GetAttribute<Math::Vect2f>( "uv", Math::Vect2f(0.0f) )); Math::Vect3f lDir( lPos - mPosition ); lDir.Normalize(); CLightProbeVertex* v = new CLightProbeVertex(lPos, lUV); std::string lKey( "" ); if (lDir.x > 0.9f) lKey = "x"; if (lDir.x < -0.9f) lKey = "-x"; if (lDir.y > 0.9f) lKey = "y"; if (lDir.y < -0.9f) lKey = "-y"; if (lDir.z > 0.9f) lKey = "z"; if (lDir.z < -0.9f) lKey = "-z"; ASSERT(lKey != "", "LightProbe incorrect.") mVertexs[lKey] = v; } } } } }
GLvoid CLightingManager::addLightSource(vector2i position, GLint lightSourceType) { // depending on the block position we need to setup from 1 to 4 lights CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); GLint faces[4]; GLint bfVis = lManager->getBlock(position)->getFreeFaces(faces); vector3f lPoss[] = { vector3f(CV_BLOCK_WIDTH/2,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH+CV_BLOCK_DEPTH/10.0f), // front vector3f(CV_BLOCK_WIDTH/2,CV_BLOCK_HEIGHT,-CV_BLOCK_DEPTH/10.0f), // back vector3f(CV_BLOCK_WIDTH+CV_BLOCK_DEPTH/10.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f), // left vector3f(-CV_BLOCK_DEPTH/10.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f), // right vector3f(CV_BLOCK_DEPTH/2.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f) // middle }; if (bfVis==-1) { bfVis=1; faces[0]=4; } for (GLint i=0; i<bfVis; i++) { // get a light from the light pool //CLightSource *light = lightSourcePool[lightSourceType].popObject(); CLightSource *light = new CLightSource(lightIndexName[lightSourceType]); if (light) { // set its position light->setPosition(lManager->getBlock(position)->getRealPosition()+lPoss[faces[i]]); // append to block //blockLightData[position[1]][position[0]].add(light); //blockLightData[position[1]][position[0]].add(light,lManager->getBlock(position)); // and add to the global list of used lights lightSources.push_back(light); GLint lightRadius = (int)ceil(light->getRadius()/CV_BLOCK_WIDTH)+2; // +2 is there for extended radius comparison //vector2i lightPos = CConversions::realToLogical(light->getPosition()); // now for every block of this light, add references of this light to influenced neighbour blocks. for (GLint y=-lightRadius; y<=lightRadius; y++) { for (GLint x=-lightRadius; x<=lightRadius; x++) { if (position[1]+y<0 || position[0]+x<0 || position[1]+y>=84 || position[0]+x>=84) { continue; } if (faces[i]==CBlock::BFS_FRONT && y<0) { continue; } if (faces[i]==CBlock::BFS_BACK && y>0) { continue; } if (faces[i]==CBlock::BFS_LEFT && x<0) { continue; } if (faces[i]==CBlock::BFS_RIGHT && x>0) { continue; } CBlock *block = lManager->getBlock(position[0]+x,position[1]+y); vector3f lPos(light->getPosition()[0],0.0f,light->getPosition()[2]); GLfloat d1 = (block->getRealPosition()-lPos).length(); GLfloat d2 = ((block->getRealPosition()+vector3f(CV_BLOCK_WIDTH,0.0f,0.0f))-lPos).length(); GLfloat d3 = ((block->getRealPosition()+vector3f(CV_BLOCK_WIDTH,0.0f,CV_BLOCK_DEPTH))-lPos).length(); GLfloat d4 = ((block->getRealPosition()+vector3f(0.0f,0.0f,CV_BLOCK_DEPTH))-lPos).length(); GLfloat rad =light->getRadius(); if (d1<=rad || d2<=rad || d3<=rad || d4<=rad) { blockLightData[position[1]+y][position[0]+x].add(light,block); } } } } } }