Mesh::Mesh(int _numVertices, int _numTriangles, int _numQuads, int _numUVSets, bool _vertexColors) : triangleData(0), quadData(0), selectedUVSet(0), numVertices(_numVertices), numTriangles(_numTriangles), numQuads(_numQuads), numUVSets(_numUVSets), fvf(0), vertexBuffer(0), indexBuffer(0), vertexColors(_vertexColors ? 1 : 0) { vertexStride = 6 + 2 * numUVSets + vertexColors; vertexData = new float[numVertices * vertexStride]; ZeroMemory(vertexData, sizeof(float) * numVertices * vertexStride); if (numTriangles) { triangleData = new int[numTriangles * 3]; ZeroMemory(triangleData, sizeof(int) * numTriangles * 3); } if (numQuads) { quadData = new int[numQuads * 4]; ZeroMemory(quadData, sizeof(int) * numQuads * 4); } faceSelection = new bool[getNumFaces()]; ZeroMemory(faceSelection, sizeof(bool) * getNumFaces()); //vertexSelection = new bool[numVertices]; //ZeroMemory(vertexSelection, sizeof(bool) * numVertices); }
PixelBox Image::getPixelBox(size_t face, size_t mipmap) const { if(mipmap > getNumMipmaps()) OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, "Mipmap index out of range", "Image::getPixelBox" ) ; if(face >= getNumFaces()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", "Image::getPixelBox"); // Calculate mipmap offset and size uint8 *offset = const_cast<uint8*>(getData()); size_t width = getWidth(), height=getHeight(), depth=getDepth(); size_t faceSize; // Size of one face of the image for(size_t mip=0; mip<mipmap; ++mip) { faceSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); /// Skip all faces of this mipmap offset += faceSize*getNumFaces(); /// Half size in each dimension if(width!=1) width /= 2; if(height!=1) height /= 2; if(depth!=1) depth /= 2; } // We have advanced to the desired mipmap, offset to right face faceSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); offset += faceSize*face; // Return subface as pixelbox PixelBox src(width, height, depth, getFormat(), offset); return src; }
Mesh::Mesh(const Mesh& mesh) : triangleData(0), quadData(0), selectedUVSet(mesh.selectedUVSet), numVertices(mesh.numVertices), numTriangles(mesh.numTriangles), numQuads(mesh.numQuads), numUVSets(mesh.numUVSets), fvf(0), vertexBuffer(0), indexBuffer(0), vertexColors(mesh.vertexColors) { vertexStride = 6 + 2 * numUVSets + vertexColors; vertexData = new float[numVertices * vertexStride]; memcpy(vertexData, mesh.vertexData, sizeof(float) * vertexStride * numVertices); if (numTriangles) { triangleData = new int[numTriangles * 3]; memcpy(triangleData, mesh.triangleData, sizeof(int) * numTriangles * 3); } if (numQuads) { quadData = new int[numQuads * 4]; memcpy(quadData, mesh.quadData, sizeof(int) * numQuads * 4); } faceSelection = new bool[getNumFaces()]; memcpy(faceSelection, mesh.faceSelection, sizeof(bool) * getNumFaces()); // vertexSelection = new bool[numVertices]; // memcpy(vertexSelection, mesh.vertexSelection, sizeof(bool) * numVertices); }
void CPUSideTriangleMesh::generateSmoothingGroups(float maxSmoothAngle, bool regenerateNormals, bool regenerateAdjacency) { if (regenerateNormals) { generateFaceNormals(); } if (regenerateAdjacency) { generateFaceAdjacency(); } // split faces float cSMAngle = cos(maxSmoothAngle); unsigned smGroup = 0; std::vector<unsigned> faceSMGroup(getNumFaces(), 0); //std::vector<unsigned> smGroupRepresentative(1); for (unsigned iFace = 0; iFace < getNumFaces(); ++iFace) { // sm group for face already set if (faceSMGroup[iFace] != 0) { continue; } // make new smoothing group faceSMGroup[iFace] = ++smGroup; //smGroupRepresentative.push_back(iFace); // run DFS to gather faces belonging to same smoothing group std::stack<unsigned> toVisit; toVisit.push(iFace); while ( !toVisit.empty() ) { unsigned curFace = toVisit.top(); toVisit.pop(); const unsigned* adjFaces = getAdjacentFaces(curFace); for (unsigned i = 0; i<getNumAdjacentFaces(curFace); ++i) { // if angle between normals is less than maxSmoothAngle put adjacent face into same smoothing group unsigned adjFace = adjFaces[i]; if ( faceSMGroup[adjFace] == 0 && math::dot(faceNormals[curFace], faceNormals[adjFace]) > cSMAngle ) { faceSMGroup[adjFace] = smGroup; toVisit.push(adjFace); } } } } // once smoothing groups are set try to reduce their quantity to 32 using greedy algorithm smoothingGroups.resize( getNumFaces() ); for (size_t i = 0; i<getNumFaces(); ++i) { smoothingGroups[i] = faceSMGroup[i] % 32; } }
bool MeshModel::saveOFF(std::ofstream& ofile) const { ofile << "OFF\n"; ofile << getNumVertices() << ' ' << getNumFaces() << " 0\n"; // don't bother counting edges for (unsigned int i = 0; i < getNumVertices(); i++) ofile << vertices[i][0] << ' ' << vertices[i][1] << " 0\n"; for (unsigned int i = 0; i < getNumFaces(); i++) ofile << "3 " << (*faces)[i][0] << ' ' << (*faces)[i][1] << ' ' << (*faces)[i][2] << std::endl; return true; }
void CPUSideTriangleMesh::generateFaceAdjacency() { assert(!indicesArrays[0].empty() && "No index data specified"); typedef std::pair<unsigned, unsigned> edge; typedef boost::unordered_multimap<edge, unsigned> edge_face_map; typedef std::pair<edge_face_map::iterator, edge_face_map::iterator> edge_face_map_range; // fill up edge map edge_face_map edgeFaceMap; for (unsigned iFace = 0; iFace < getNumFaces(); ++iFace) { for (int j = 0; j<3; ++j) { edge e( getFaceVertex(iFace, j), getFaceVertex(iFace, (j + 1) % 3) ); if (e.first > e.second) { std::swap(e.first, e.second); } edgeFaceMap.insert( std::make_pair(e, iFace) ); } } // add neighbor to the face if it shares edge with some other faceNeighborsStarts.resize(getNumFaces() + 1); for (unsigned iFace = 0; iFace < getNumFaces(); ++iFace) { faceNeighborsStarts[iFace] = faceNeighbors.size(); for (int j = 0; j<3; ++j) { edge e( getFaceVertex(iFace, j), getFaceVertex(iFace, (j + 1) % 3) ); if (e.first > e.second) { std::swap(e.first, e.second); } // add neighbor faces which share same edge edge_face_map_range edgeFacesRange = edgeFaceMap.equal_range(e); for (edge_face_map::iterator it = edgeFacesRange.first; it != edgeFacesRange.second; ++it) { if (it->second != iFace) { faceNeighbors.push_back(it->second); } } } } // fake end element faceNeighborsStarts[getNumFaces()] = faceNeighbors.size(); }
//--------------------------------------------------------------------------------------------- void GLTexture::_createSurfaceList() { mSurfaceList.clear(); uint32 depth = mDepth; // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr for(GLint face=0; face<static_cast<GLint>(getNumFaces()); face++) { uint32 width = mWidth; uint32 height = mHeight; for(uint32 mip=0; mip<=getNumMipmaps(); mip++) { GLHardwarePixelBuffer* buf = new GLTextureBuffer(mRenderSystem, this, face, mip, width, height, depth); mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); if (width > 1) width = width / 2; if (height > 1) height = height / 2; if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth / 2; } } }
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); //precondition: groupp MUST be null or groupp MUST contain this llassert(!groupp || groupp->hasElement(this)); /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); }*/ if (mSpatialGroupp != groupp && getVOVolume()) { //NULL out vertex buffer references for volumes on spatial group change to maintain //requirement that every face vertex buffer is either NULL or points to a vertex buffer //contained by its drawable's spatial group for (S32 i = 0; i < getNumFaces(); ++i) { LLFace* facep = getFace(i); if (facep) { facep->clearVertexBuffer(); } } } //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1 //postcondition: if next group is NOT NULL, binIndex must not be -1 llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : getBinIndex() != -1); mSpatialGroupp = groupp; }
void LLDrawable::updateTexture() { LLMemType mt(LLMemType::MTYPE_DRAWABLE); if (isDead()) { llwarns << "Dead drawable updating texture!" << llendl; return; } if (getNumFaces() != mVObjp->getNumTEs()) { //drawable is transitioning its face count return; } if (getVOVolume()) { /*if (isActive()) { if (isRoot()) { mQuietCount = 0; } else { getParent()->mQuietCount = 0; } }*/ gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE); } }
void GL3PlusTexture::_createSurfaceList() { mSurfaceList.clear(); size_t depth = mDepth; for (uint8 face = 0; face < getNumFaces(); face++) { size_t width = mWidth; size_t height = mHeight; for (uint32 mip = 0; mip <= getNumMipmaps(); mip++) { GL3PlusHardwarePixelBuffer* buf = new GL3PlusTextureBuffer(this, face, mip, width, height, depth); mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); if (width > 1) width = width / 2; if (height > 1) height = height / 2; if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth / 2; } } }
//--------------------------------------------------------------------------------------------- void GLTexture::_createSurfaceList() { mSurfaceList.clear(); // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr bool wantGeneratedMips = (mUsage & TU_AUTOMIPMAP)!=0; // Do mipmapping in software? (uses GLU) For some cards, this is still needed. Of course, // only when mipmap generation is desired. bool doSoftware = wantGeneratedMips && !mMipmapsHardwareGenerated && getNumMipmaps(); for(size_t face=0; face<getNumFaces(); face++) { for(size_t mip=0; mip<=getNumMipmaps(); mip++) { GLHardwarePixelBuffer *buf = new GLTextureBuffer(mName, getGLTextureTarget(), mTextureID, face, mip, static_cast<HardwareBuffer::Usage>(mUsage), doSoftware && mip==0, mHwGamma, mFSAA); mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); /// Check for error if(buf->getWidth()==0 || buf->getHeight()==0 || buf->getDepth()==0) { OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Zero sized texture surface on texture "+getName()+ " face "+StringConverter::toString(face)+ " mipmap "+StringConverter::toString(mip)+ ". Probably, the GL driver refused to create the texture.", "GLTexture::_createSurfaceList"); } } } }
void LLDrawable::shiftPos(const LLVector3 &shift_vector) { if (isDead()) { llwarns << "Shifting dead drawable" << llendl; return; } if (mParent) { mXform.setPosition(mVObjp->getPosition()); } else { mXform.setPosition(mVObjp->getPositionAgent()); } mXform.setRotation(mVObjp->getRotation()); mXform.setScale(1,1,1); mXform.updateMatrix(); if (isStatic()) { LLVOVolume* volume = getVOVolume(); if (!volume) { gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); } for (S32 i = 0; i < getNumFaces(); i++) { LLFace *facep = getFace(i); facep->mCenterAgent += shift_vector; facep->mExtents[0] += shift_vector; facep->mExtents[1] += shift_vector; if (!volume && facep->hasGeometry()) { facep->mVertexBuffer = NULL; facep->mLastVertexBuffer = NULL; } } mExtents[0] += shift_vector; mExtents[1] += shift_vector; mPositionGroup += LLVector3d(shift_vector); } else if (mSpatialBridge) { mSpatialBridge->shiftPos(shift_vector); } else if (isAvatar()) { mExtents[0] += shift_vector; mExtents[1] += shift_vector; mPositionGroup += LLVector3d(shift_vector); } mVObjp->onShift(shift_vector); }
void GL3PlusTexture::_createSurfaceList() { mSurfaceList.clear(); for (size_t face = 0; face < getNumFaces(); face++) { for (size_t mip = 0; mip <= getNumMipmaps(); mip++) { GL3PlusHardwarePixelBuffer *buf = new GL3PlusTextureBuffer(mName, getGL3PlusTextureTarget(), mTextureID, face, mip, static_cast<HardwareBuffer::Usage>(mUsage), mHwGamma, mFSAA); mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); // Check for error if (buf->getWidth() == 0 || buf->getHeight() == 0 || buf->getDepth() == 0) { OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Zero sized texture surface on texture "+getName()+ " face "+StringConverter::toString(face)+ " mipmap "+StringConverter::toString(mip)+ ". The GL driver probably refused to create the texture.", "GL3PlusTexture::_createSurfaceList"); } } } }
void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { llwarns << "Attempted to update distance for non-world camera." << llendl; return; } //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { if (getSpatialGroup()) { pos.set(getPositionGroup().getF32ptr()); } else { pos = getPositionAgent(); } if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { LLVector4a box; box.setSub(facep->mExtents[1], facep->mExtents[0]); box.mul(0.25f); LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { v.mV[j] -= box[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } } } else { pos = LLVector3(getPositionGroup().getF32ptr()); } pos -= camera.getOrigin(); mDistanceWRTCamera = llround(pos.magVec(), 0.01f); mVObjp->updateLOD(); } }
void CPUSideTriangleMesh::generateFaceNormals() { assert(!attributeArrays[0].empty() && "No vertex data specified"); assert(!indicesArrays[0].empty() && "No index data specified"); if ( const math::Vector3f* vertices = queryAttributeData<math::Vector3f>(0) ) { faceNormals.resize( getNumFaces() ); for (size_t i = 0; i<getNumFaces(); ++i) { const math::Vector3f& A = vertices[ getFaceVertex(i, 0) ]; const math::Vector3f& B = vertices[ getFaceVertex(i, 1) ]; const math::Vector3f& C = vertices[ getFaceVertex(i, 2) ]; faceNormals[i] = math::cross(B - A, C - A); } } else if ( const math::Vector4f* vertices = queryAttributeData<math::Vector4f>(0) ) { faceNormals.resize( getNumFaces() ); for (size_t i = 0; i<getNumFaces(); ++i) { const math::Vector4f& A = vertices[ getFaceVertex(i, 0) ]; const math::Vector4f& B = vertices[ getFaceVertex(i, 1) ]; const math::Vector4f& C = vertices[ getFaceVertex(i, 2) ]; faceNormals[i] = math::cross(math::xyz(B - A), math::xyz(C - A)); } } else { assert(!"Invalid number of vertex components"); } // normalize for (size_t i = 0; i<faceNormals.size(); ++i) { float len = math::length(faceNormals[i]); if (len < 0.0001f) { faceNormals[i] = math::Vector3f(0.0f); // in case of degenerate triangle } else { faceNormals[i] /= len; } } }
VertexArray* Lib3dsLoader::buildVao() { VertexArray* vao = 0; Lib3dsVector* verts = 0; Lib3dsVector* norms = 0; Lib3dsTexel* tex = 0; Lib3dsMesh* mesh = 0; //bool hasTexture = false; // TODO unsigned int numFaces = 0; unsigned int doneFaces = 0; numFaces = getNumFaces(); verts = new Lib3dsVector[numFaces * 3]; norms = new Lib3dsVector[numFaces * 3]; tex = new Lib3dsTexel[numFaces * 3]; mesh = model->meshes; // For all meshes, calculate normals and extract vertices. // Taken from http://www.donkerdump.nl/node/207 while(mesh != 0) { lib3ds_mesh_calculate_normals(mesh, &norms[doneFaces*3]); // For all faces for(unsigned int i = 0; i < mesh->faces; i++) { Lib3dsFace* face = &mesh->faceL[i]; for(unsigned int j = 0; j < 3; j++) { memcpy(&verts[doneFaces * 3 + j], mesh->pointL[face->points[j]].pos, sizeof(Lib3dsVector)); if(mesh->texels) { memcpy(&tex[doneFaces *3 + j], mesh->texelL[face->points[j]], sizeof(Lib3dsTexel)); } } doneFaces++; } mesh = mesh->next; } vao = new VertexArray(); vao->loadVertices(verts, numFaces); vao->loadNormals(norms, numFaces); vao->loadTextureCoords(tex, numFaces); delete[] verts; delete[] norms; delete[] tex; return vao; }
const char* FontManager::getFaceName(int faceID) { if ((faceID < 0) || (faceID > getNumFaces())) { DEBUG2("Trying to fetch name for invalid Font Face ID %d\n", faceID); return NULL; } return fontFaces[faceID].begin()->second->getFaceName(); }
//----------------------------------------------------------------------------- void Texture::copyToTexture( TexturePtr& target ) { if(target->getNumFaces() != getNumFaces()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Texture types must match", "Texture::copyToTexture"); } size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps()); if((mUsage & TU_AUTOMIPMAP) || (target->getUsage()&TU_AUTOMIPMAP)) numMips = 0; for(unsigned int face=0; face<getNumFaces(); face++) { for(unsigned int mip=0; mip<=numMips; mip++) { target->getBuffer(face, mip)->blit(getBuffer(face, mip)); } } }
int MeshModel::getFaceUnderPoint(Point2 point) const { for (unsigned int i=0; i < getNumFaces() ; i++) { Face& face = (*faces)[i]; if (PointInTriangle(point, vertices[face.a()],vertices[face.b()],vertices[face.c()])) return i; } return -1; }
void LLDrawable::moveUpdatePipeline(BOOL moved) { makeActive(); // Update the face centers. for (S32 i = 0; i < getNumFaces(); i++) { getFace(i)->updateCenterAgent(); } }
double MHexahedron::getInnerRadius() { //Only for vertically aligned elements (not inclined) double innerRadius=std::numeric_limits<double>::max(); for (int i=0; i<getNumFaces(); i++){ MQuadrangle quad(getFace(i).getVertex(0), getFace(i).getVertex(1), getFace(i).getVertex(2), getFace(i).getVertex(3)); innerRadius=std::min(innerRadius,quad.getInnerRadius()); } return innerRadius; }
void MeshModel::renderFaces() const { glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT|GL_LINE_BIT); glEnable(GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_TRIANGLES); for (unsigned int i = 0; i < getNumFaces(); i++) renderFaceInternal(i); glEnd(); glPopAttrib(); }
//--------------------------------------------------------------------------------------------- HardwarePixelBufferSharedPtr GLTexture::getBuffer(size_t face, size_t mipmap) { if(face >= getNumFaces()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", "GLTexture::getBuffer"); if(mipmap > mNumMipmaps) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", "GLTexture::getBuffer"); unsigned int idx = face*(mNumMipmaps+1) + mipmap; assert(idx < mSurfaceList.size()); return mSurfaceList[idx]; }
//--------------------------------------------------------------------- void Texture::convertToImage(Image& destImage, bool includeMipMaps) { size_t numMips = includeMipMaps? getNumMipmaps() + 1 : 1; size_t dataSize = Image::calculateSize(numMips, getNumFaces(), getWidth(), getHeight(), getDepth(), getFormat()); void* pixData = OGRE_MALLOC(dataSize, Ogre::MEMCATEGORY_GENERAL); // if there are multiple faces and mipmaps we must pack them into the data // faces, then mips void* currentPixData = pixData; for (size_t face = 0; face < getNumFaces(); ++face) { uint32 width = getWidth(); uint32 height = getHeight(); uint32 depth = getDepth(); for (size_t mip = 0; mip < numMips; ++mip) { size_t mipDataSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); Ogre::PixelBox pixBox(width, height, depth, getFormat(), currentPixData); getBuffer(face, mip)->blitToMemory(pixBox); currentPixData = (void*)((char*)currentPixData + mipDataSize); if(width != 1) width /= 2; if(height != 1) height /= 2; if(depth != 1) depth /= 2; } } // load, and tell Image to delete the memory when it's done. destImage.loadDynamicImage((Ogre::uchar*)pixData, getWidth(), getHeight(), getDepth(), getFormat(), true, getNumFaces(), numMips - 1); }
void MeshModel::renderFaceInternal(unsigned int fnum) const { if (fnum >= getNumFaces()) return; std::vector<Point2> &coords = *texCoords; Face &f = (*faces)[fnum]; for (unsigned int j = 0; j < 3; j++) { glTexCoord2f(coords[f[j]].x, coords[f[j]].y); glVertex2f(vertices[f[j]].x, vertices[f[j]].y); } }
PixelBox Image::getPixelBox(size_t face, size_t mipmap) const { // Image data is arranged as: // face 0, top level (mip 0) // face 0, mip 1 // face 0, mip 2 // face 1, top level (mip 0) // face 1, mip 1 // face 1, mip 2 // etc if(mipmap > getNumMipmaps()) OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "Mipmap index out of range", "Image::getPixelBox" ) ; if(face >= getNumFaces()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", "Image::getPixelBox"); // Calculate mipmap offset and size uint8 *offset = const_cast<uint8*>(getData()); // Base offset is number of full faces uint32 width = getWidth(), height=getHeight(), depth=getDepth(); size_t numMips = getNumMipmaps(); // Figure out the offsets size_t fullFaceSize = 0; size_t finalFaceSize = 0; uint32 finalWidth = 0, finalHeight = 0, finalDepth = 0; for(size_t mip=0; mip <= numMips; ++mip) { if (mip == mipmap) { finalFaceSize = fullFaceSize; finalWidth = width; finalHeight = height; finalDepth = depth; } fullFaceSize += PixelUtil::getMemorySize(width, height, depth, getFormat()); /// Half size in each dimension if(width!=1) width /= 2; if(height!=1) height /= 2; if(depth!=1) depth /= 2; } // Advance pointer by number of full faces, plus mip offset into offset += face * fullFaceSize; offset += finalFaceSize; // Return subface as pixelbox PixelBox src(finalWidth, finalHeight, finalDepth, getFormat(), offset); return src; }
void mesh3DS::sortFacesByMaterial() { assert(getNumFaces() != 0); assert(m_parentModel != NULL); std::vector < ushort > newMatFaces; // mark each face off as assigned to a material so // we can figure out which faces have no material std::vector < bool > assignedFaces; std::vector < bool >::iterator assignedFacesIter; assignedFaces.assign(m_faces.size() / 3, false); // loop over each material std::map < std::string, std::vector < ushort > >::iterator matFacesIter; for (matFacesIter = m_materialFaces.begin(); matFacesIter != m_materialFaces.end(); ++matFacesIter) { // std::cout<<" Faces in material '"<<matFacesIter->first<<"': // "<<matFacesIter->second.size()<<std::endl; // loop over all the faces with that material std::vector < ushort >::iterator facesIter; for (facesIter = matFacesIter->second.begin(); facesIter != matFacesIter->second.end(); ++facesIter) { newMatFaces.push_back(m_faces[((*facesIter) * 3)]); newMatFaces.push_back(m_faces[((*facesIter) * 3) + 1]); newMatFaces.push_back(m_faces[((*facesIter) * 3) + 2]); assignedFaces[*facesIter] = true; } // replace the material's face indices with the actual face vertex // indices m_materialFaces[matFacesIter->first].assign(newMatFaces.begin(), newMatFaces.end()); newMatFaces.clear(); } // Make a default material and assign any unused faces to it int numUnassignedFaces = 0; for (assignedFacesIter = assignedFaces.begin(); assignedFacesIter != assignedFaces.end(); ++assignedFacesIter) { if (*assignedFacesIter == false) { numUnassignedFaces++; // assign face to default material } } // std::cout<<"numUnassignedFaces: "<<numUnassignedFaces<<std::endl; }
void GLWidget::selectPolygon(QMouseEvent* event) { GLint x = event->pos().x(), y = event->pos().y(), viewport[4], found, selObject, numFaces = getNumFaces(); GLuint selBuffer[4 * numFaces], depth; GLfloat a = (height() == 0) ? 1.0 : GLfloat(width()) / GLfloat(height()); memset(selBuffer,4 * numFaces,sizeof(GLuint)); isBuild = false; glSelectBuffer(4 * numFaces, selBuffer); glGetIntegerv(GL_VIEWPORT, viewport); glMatrixMode(GL_PROJECTION); glPushMatrix(); glRenderMode(GL_SELECT); glLoadIdentity(); gluPickMatrix (x, viewport[3] - y, 2, 2, viewport); gluPerspective(60.0, a, 0.01 * radius, 10 * radius); glMatrixMode (GL_MODELVIEW); displayTRPObject(); found = glRenderMode(GL_RENDER); if (found > 0) { depth = selBuffer[1]; selObject = selBuffer[3]; for (int i = 1; i < found; i++) { if (selBuffer[(i * 4) + 1] < depth ) { depth = selBuffer[(i * 4) + 1]; selObject = selBuffer[(i * 4) + 3]; } } QMessageBox::about(this, tr("Выбор полигона"), tr("Выбраный полигон: %1 (%2 %3 %4 %5)").arg(selObject).arg(selBuffer[0]).arg(selBuffer[1]).arg(selBuffer[2]).arg(selBuffer[3])); } glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (GL_MODELVIEW); }
void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { volume->updateRelativeXform(); pos = volume->getRelativeXform().getTranslation(); if (isStatic()) { pos += volume->getRegion()->getOriginAgent(); } if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) { LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { v.mV[j] -= box.mV[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } } } else { pos = LLVector3(getPositionGroup()); } pos -= camera.getOrigin(); mDistanceWRTCamera = llround(pos.magVec(), 0.01f); mVObjp->updateLOD(); } }
void GLES2Texture::_createSurfaceList() { mSurfaceList.clear(); // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr bool wantGeneratedMips = (mUsage & TU_AUTOMIPMAP)!=0; // Do mipmapping in software? (uses GLU) For some cards, this is still needed. Of course, // only when mipmap generation is desired. bool doSoftware = wantGeneratedMips && !mMipmapsHardwareGenerated && getNumMipmaps(); for (size_t face = 0; face < getNumFaces(); face++) { uint32 width = mWidth; uint32 height = mHeight; uint32 depth = mDepth; for (uint8 mip = 0; mip <= getNumMipmaps(); mip++) { GLES2HardwarePixelBuffer *buf = OGRE_NEW GLES2TextureBuffer(mName, getGLES2TextureTarget(), mTextureID, width, height, depth, GLES2PixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma), GLES2PixelUtil::getGLOriginDataType(mFormat), static_cast<GLint>(face), mip, static_cast<HardwareBuffer::Usage>(mUsage), doSoftware && mip == 0, mHwGamma, mFSAA); mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); // Check for error if (buf->getWidth() == 0 || buf->getHeight() == 0 || buf->getDepth() == 0) { OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Zero sized texture surface on texture " + getName() + " face " + StringConverter::toString(face) + " mipmap " + StringConverter::toString(mip) + ". The GL driver probably refused to create the texture.", "GLES2Texture::_createSurfaceList"); } } } }