void MeshData::generateTangents() { int pos_attr, uv_attr, len, n; float r, *pos, *uv, *tan, *bitan; vec3 pos_d1, pos_d2, uv_d1, uv_d2; pos_attr = getAttributeIndex("position"); uv_attr = getAttributeIndex("texcoord"); if (pos_attr < 0) { #ifndef PLG_RELEASE dprintf(2, "error: can't generateTangents() without position attribute\n"); #endif return; } if (uv_attr < 0) { #ifndef PLG_RELEASE dprintf(2, "error: can't generateTangents() without texcoord attribute\n"); #endif return; } pos = getVertex(pos_attr, 0); uv = getVertex(uv_attr, 0); len = getVertexCount() / 3; tan = (float *) malloc(len * 9 * sizeof(float)); bitan = (float *) malloc(len * 9 * sizeof(float)); for (n = 0; n < len; n ++) { vec3_sub(&pos_d1, (vec3 *) (pos + n * 9 + 3), (vec3 *) (pos + n * 9)); vec3_sub(&pos_d2, (vec3 *) (pos + n * 9 + 6), (vec3 *) (pos + n * 9)); uv_d1.d[0] = uv[n * 6 + 2] - uv[n * 6 + 0]; uv_d1.d[1] = uv[n * 6 + 3] - uv[n * 6 + 1]; uv_d2.d[0] = uv[n * 6 + 4] - uv[n * 6 + 0]; uv_d2.d[1] = uv[n * 6 + 5] - uv[n * 6 + 1]; r = 1.0f / (uv_d1.d[0] * uv_d2.d[1] - uv_d1.d[1] * uv_d2.d[0]); tan[n * 9 + 0] = (pos_d1.d[0] * uv_d2.d[1] - pos_d2.d[0] * uv_d1.d[1]) * r; tan[n * 9 + 1] = (pos_d1.d[1] * uv_d2.d[1] - pos_d2.d[1] * uv_d1.d[1]) * r; tan[n * 9 + 2] = (pos_d1.d[2] * uv_d2.d[1] - pos_d2.d[2] * uv_d1.d[1]) * r; tan[n * 9 + 6] = tan[n * 9 + 3] = tan[n * 9 + 0]; tan[n * 9 + 7] = tan[n * 9 + 4] = tan[n * 9 + 1]; tan[n * 9 + 8] = tan[n * 9 + 5] = tan[n * 9 + 2]; bitan[n * 9 + 0] = (pos_d2.d[0] * uv_d1.d[0] - pos_d1.d[0] * uv_d2.d[0]) * r; bitan[n * 9 + 1] = (pos_d2.d[1] * uv_d1.d[0] - pos_d1.d[1] * uv_d2.d[0]) * r; bitan[n * 9 + 2] = (pos_d2.d[2] * uv_d1.d[0] - pos_d1.d[2] * uv_d2.d[0]) * r; bitan[n * 9 + 6] = bitan[n * 9 + 3] = bitan[n * 9 + 0]; bitan[n * 9 + 7] = bitan[n * 9 + 4] = bitan[n * 9 + 1]; bitan[n * 9 + 8] = bitan[n * 9 + 5] = bitan[n * 9 + 2]; } addTangents(tan, len * 9); addBitangents(bitan, len * 9); }
inline CGoGNCodeType AttributeContainer::getTypeCode(const std::string& attribName) const { unsigned int index = getAttributeIndex(attribName) ; if(index == UNKNOWN) return CGoGNUNKNOWNTYPE ; return m_tableAttribs[index]->getTypeCode(); }
void AttributeContainer::addAttribute(const std::string& attribName, const std::string& nametype, unsigned int index) { // first check if attribute already exist if (attribName != "") { unsigned int i = getAttributeIndex(attribName) ; if (i != UNKNOWN) return ; } // create the new attribute AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, nametype); m_tableAttribs[index] = amv; amv->setOrbit(m_orbit) ; amv->setIndex(index) ; // generate a name for the attribute if no one was given if (attribName == "") { std::stringstream ss; ss << "unknown" << m_nbUnknown++; amv->setName(ss.str()); } // update the memory cost of a line m_lineCost += sizeof(T) ; // resize the new attribute so that it has the same size than others amv->setNbBlocks(uint32(m_holesBlocks.size())) ; m_nbAttributes++; }
inline AttributeMultiVectorGen* AttributeContainer::getVirtualDataVector(const std::string& attribName) { unsigned int index = getAttributeIndex(attribName) ; if(index == UNKNOWN) return NULL ; else return m_tableAttribs[index]; }
const char* XmlElement::getAttributeValue(const char* name) { int index = getAttributeIndex(name); if (index < 0) { return ""; } return getAttributeValue(index).getBase(); }
const ModelAttribute *ModelClassifier::getAttribute(const std::string &name) const { ModelAttribute *attr = nullptr; size_t index = getAttributeIndex(name); if(index != NoIndex) { attr = mAttributes[index].get(); } return attr; }
AttributeMultiVector<T>* AttributeContainer::getDataVector(const std::string& attribName) { unsigned int index = getAttributeIndex(attribName) ; if(index == UNKNOWN) return NULL ; AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[index]); assert((atm != NULL) || !"getDataVector: wrong type"); return atm; }
AttributeMultiVector<T>* AttributeContainer::addAttribute(const std::string& attribName) { // first check if attribute already exist unsigned int index ; if (attribName != "") { index = getAttributeIndex(attribName) ; if (index != UNKNOWN) { std::cout << "attribute " << attribName << " already found.." << std::endl ; return NULL ; } } // create the new attribute std::string typeName = nameOfType(T()) ; AttributeMultiVector<T>* amv = new AttributeMultiVector<T>(attribName, typeName) ; if(!m_freeIndices.empty()) { index = m_freeIndices.back() ; m_freeIndices.pop_back() ; m_tableAttribs[index] = amv ; } else { index = uint32(m_tableAttribs.size()) ; m_tableAttribs.push_back(amv) ; } amv->setOrbit(m_orbit) ; amv->setIndex(index) ; // generate a name for the attribute if no one was given if (attribName == "") { std::stringstream ss ; ss << "unknown" << m_nbUnknown++ ; amv->setName(ss.str()) ; } // update the memory cost of a line m_lineCost += sizeof(T) ; // resize the new attribute so that it has the same size than others amv->setNbBlocks(uint32(m_holesBlocks.size())) ; m_nbAttributes++ ; return amv ; }
void CPUSideTriangleMesh::generatePhongNormals() { assert( haveFaceNormals() && haveSmoothingGroups() && "Mesh should have smoothing groups - use generateSmoothingGroups"); // vertex normals math::vector_of_vector3f normals(attributeArrays[0].count); // vertex normals indices std::vector<unsigned> indices(indicesArrays[0].indices.get(), indicesArrays[0].indices.get() + indicesArrays[0].count); // vertex smoothing groups std::vector<int> vertexSMGroup(attributeArrays[0].count, -1); // average normals against faces sharing same smoothing group for (size_t iFace = 0; iFace < faceNormals.size(); ++iFace) { for (size_t iVertInd = iFace * 3; iVertInd < iFace * 3 + 3; ++iVertInd) { unsigned iVert = indices[iVertInd]; if (vertexSMGroup[iVert] == -1) { vertexSMGroup[iVert] = get_first_nonzero_bit(smoothingGroups[iFace]); normals[iVert] = faceNormals[iFace]; } else if ( (smoothingGroups[iFace] != 0) && (smoothingGroups[iFace] & (1 << (vertexSMGroup[iVert] - 1))) ) { normals[iVert] += faceNormals[iFace]; } else { indices[iVertInd] = normals.size(); normals.push_back(faceNormals[iFace]); vertexSMGroup.push_back( get_first_nonzero_bit(smoothingGroups[iFace]) ); } } } // normalize all for (size_t i = 0; i<normals.size(); ++i) { normals[i] = math::normalize(normals[i]); } // find attribute slot for normals int normalAttrIndex = getAttributeIndex("normal"); if (normalAttrIndex == -1) { normalAttrIndex = getFreeAttributeIndex(); } assert(normalAttrIndex != -1 && "No free slot for normals"); // setup normals setAttributes("normal", normalAttrIndex, 3, normals.size(), sgl::FLOAT, &normals[0]); setIndices(normalAttrIndex, indices.size(), &indices[0]); }
void Type::addAttribute(TypeAttribute attrib) { //Raises an error if the attribute has an empty name or null type if(attrib.getName().isEmpty() || attrib.getType()==PgSQLType::null) throw Exception(ERR_INS_INV_TYPE_ATTRIB,__PRETTY_FUNCTION__,__FILE__,__LINE__); //Raises an error if the passed attribute has the same type as the defining type (this) else if(PgSQLType::getUserTypeIndex(this->getName(true), this) == !attrib.getType()) throw Exception(Exception::getErrorMessage(ERR_USER_TYPE_SELF_REFERENCE).arg(this->getName(true)), ERR_USER_TYPE_SELF_REFERENCE,__PRETTY_FUNCTION__,__FILE__,__LINE__); //Raises an error when the attribute already exists else if(getAttributeIndex(attrib.getName()) >= 0) throw Exception(ERR_INS_DUPLIC_ITEMS,__PRETTY_FUNCTION__,__FILE__,__LINE__); type_attribs.push_back(attrib); setCodeInvalidated(true); }
void MeshData::getBoundingBox(float dst[6]) { uint attr, n, flags[6] = {0}; float* cur; attr = getAttributeIndex("position"); if (attr < 0) { dprintf(2, "error: can't getBoundingBox() without position attribute\n"); return; } for (n = 0; n < getVertexCount(); n++) { cur = getVertex(attr, n); if (!flags[0] || cur[0] < dst[0]) { flags[0] = 1; dst[0] = cur[0]; } if (!flags[1] || cur[0] > dst[1]) { flags[1] = 1; dst[1] = cur[0]; } if (!flags[2] || cur[1] < dst[2]) { flags[2] = 1; dst[2] = cur[1]; } if (!flags[3] || cur[1] > dst[3]) { flags[3] = 1; dst[3] = cur[1]; } if (!flags[4] || cur[2] < dst[4]) { flags[4] = 1; dst[4] = cur[2]; } if (!flags[5] || cur[2] > dst[5]) { flags[5] = 1; dst[5] = cur[2]; } } }
void MeshData::generateNormals() { int attr, len; vec3 nf, e1, e2, *p0, *p1, *p2; float *cur, *dst, *normals; attr = getAttributeIndex("position"); if (attr < 0) { #ifndef PLG_RELEASE dprintf(2, "error: can't generateNormals() without position attribute\n"); #endif return; } len = getVertexCount() * 3; normals = (float *) malloc(len * sizeof(float)); dst = normals; cur = getVertex(attr, 0); while (dst < normals + len) { p0 = (vec3 *) &cur[0], p1 = (vec3 *) &cur[3]; p2 = (vec3 *) &cur[6]; vec3_sub(&e1, p1, p2); vec3_sub(&e2, p2, p0); vec3_normalize(&e1); vec3_normalize(&e2); vec3_cross(&nf, &e1, &e2); memcpy(dst + 0, &nf, sizeof(vec3)); memcpy(dst + 3, &nf, sizeof(vec3)); memcpy(dst + 6, &nf, sizeof(vec3)); cur += 9; dst += 9; } addNormals(normals, len); }
bool AttributeContainer::removeAttribute(const std::string& attribName) { unsigned int index = getAttributeIndex(attribName) ; if (index == UNKNOWN) { std::cerr << "removeAttribute by name: attribute not found (" << attribName << ")"<< std::endl ; return false ; } // delete the attribute delete m_tableAttribs[index] ; m_tableAttribs[index] = NULL ; if (index == m_tableAttribs.size() - 1) m_tableAttribs.pop_back() ; else m_freeIndices.push_back(index) ; --m_nbAttributes ; m_lineCost -= sizeof(T); return true ; }
//----------------------------------------------------------------------- bool GLSLESProgramCommon::isAttributeValid(VertexElementSemantic semantic, uint index) { return getAttributeIndex(semantic, index) != NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX; }
//----------------------------------------------------------------------- bool GLSLLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index) { return mValidAttributes.find(getAttributeIndex(semantic, index)) != mValidAttributes.end(); }
int XmlElement::hasAttribute(const char* name) { return getAttributeIndex(name) + 1; }