bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const { if (testee.getVertexCount() != getVertexCount()) { return false; } int vertextCount = getVertexCount(); // find which testee vertex matches our first polygon vertex. glm::vec2 polygonVertex = getVertex(0); int originIndex = 0; for(int i = 0; i < vertextCount; i++) { glm::vec2 testeeVertex = testee.getVertex(i); // if they match, we found our origin. if (testeeVertex == polygonVertex) { originIndex = i; break; } } // Now, starting at the originIndex, walk the vertices of both the testee and ourselves for(int i = 0; i < vertextCount; i++) { glm::vec2 testeeVertex = testee.getVertex((i + originIndex) % vertextCount); glm::vec2 polygonVertex = getVertex(i); if (testeeVertex != polygonVertex) { return false; // we don't match, therefore we're not the same } } return true; // all of our vertices match, therefore we're the same }
bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const { OctreeProjectedPolygon::pointInside_calls++; // first check the bounding boxes, the point must be fully within the boounding box of this polygon if ((point.x > getMaxX()) || (point.y > getMaxY()) || (point.x < getMinX()) || (point.y < getMinY())) { return false; } // consider each edge of this polygon as a potential separating axis // check the point against each edge for (int i = 0; i < getVertexCount(); i++) { glm::vec2 start = getVertex(i); glm::vec2 end = getVertex((i + 1) % getVertexCount()); float a = start.y - end.y; float b = end.x - start.x; float c = a * start.x + b * start.y; if (a * point.x + b * point.y < c) { return false; } } return true; }
//----------------------------------------------------------------------- bool Polygon::operator == (const Polygon& rhs) const { if ( getVertexCount() != rhs.getVertexCount() ) return false; // Compare vertices. They may differ in its starting position. // find start size_t start = 0; bool foundStart = false; for (size_t i = 0; i < getVertexCount(); ++i ) { if (getVertex(0).positionEquals(rhs.getVertex(i))) { start = i; foundStart = true; break; } } if (!foundStart) return false; for (size_t i = 0; i < getVertexCount(); ++i ) { const Vector3& vA = getVertex( i ); const Vector3& vB = rhs.getVertex( ( i + start) % getVertexCount() ); if (!vA.positionEquals(vB)) return false; } return true; }
// // Tests the edges of this polygon as potential separating axes for this polygon and the // specified other. // // @return false if the polygons are disjoint on any of this polygon's axes, true if they // intersect on all axes. // // Note: this only works on convex polygons // // bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& testee) const { // consider each edge of this polygon as a potential separating axis for (int i = 0; i < getVertexCount(); i++) { glm::vec2 start = getVertex(i); glm::vec2 end = getVertex((i + 1) % getVertexCount()); float a = start.y - end.y; float b = end.x - start.x; float c = a * start.x + b * start.y; // if all vertices fall outside the edge, the polygons are disjoint // points that are ON the edge, are considered to be "outside" for (int j = 0; j < testee.getVertexCount(); j++) { glm::vec2 testeeVertex = testee.getVertex(j); // in comparison below: // >= will cause points on edge to be considered inside // > will cause points on edge to be considered outside float c2 = a * testeeVertex.x + b * testeeVertex.y; if (c2 >= c) { goto CONTINUE_OUTER; } } return false; CONTINUE_OUTER: ; } return true; }
bool VoxelProjectedPolygon::pointInside(const glm::vec2& point) const { // first check the bounding boxes, the point must be fully within the boounding box of this shadow if ((point.x > getMaxX()) || (point.y > getMaxY()) || (point.x < getMinX()) || (point.y < getMinY())) { return false; } float e = (getMaxX() - getMinX()) / 100.0f; // some epsilon // We need to have one ray that goes from a known outside position to the point in question. We'll pick a // start point just outside of our min X glm::vec2 r1p1(getMinX() - e, point.y); glm::vec2 r1p2(point); glm::vec2 r2p1(getVertex(getVertexCount()-1)); // start with last vertex to first vertex glm::vec2 r2p2; // Test the ray against all sides int intersections = 0; for (int i = 0; i < getVertexCount(); i++) { r2p2 = getVertex(i); if (doLineSegmentsIntersect(r1p1, r1p2, r2p1, r2p2)) { intersections++; } r2p1 = r2p2; // set up for next side } // If odd number of intersections, we're inside return ((intersections & 1) == 1); }
void VoxelProjectedPolygon::printDebugDetails() const { printf("VoxelProjectedPolygon..."); printf(" minX=%f maxX=%f minY=%f maxY=%f\n", getMinX(), getMaxX(), getMinY(), getMaxY()); printf(" vertex count=%d distance=%f\n", getVertexCount(), getDistance()); for (int i = 0; i < getVertexCount(); i++) { glm::vec2 point = getVertex(i); printf(" vertex[%d] = %f, %f \n", i, point.x, point.y); } }
void CubeProjectedPolygon::printDebugDetails() const { qCDebug(shared, "CubeProjectedPolygon..." " minX=%f maxX=%f minY=%f maxY=%f", (double)getMinX(), (double)getMaxX(), (double)getMinY(), (double)getMaxY()); qCDebug(shared, " vertex count=%d distance=%f", getVertexCount(), (double)getDistance()); for (int i = 0; i < getVertexCount(); i++) { glm::vec2 point = getVertex(i); qCDebug(shared, " vertex[%d] = %f, %f ", i, (double)point.x, (double)point.y); } }
//----------------------------------------------------------------------- void Polygon::removeDuplicates( void ) { for ( size_t i = 0; i < getVertexCount(); ++i ) { const Vector3& a = getVertex( i ); const Vector3& b = getVertex( (i + 1)%getVertexCount() ); if (a.positionEquals(b)) { deleteVertex(i); --i; } } }
void ApexVertexBuffer::applyTransformation(const PxMat44& transformation) { RenderDataFormat::Enum format; void* buf; uint32_t index; // Positions index = (uint32_t)getFormat().getBufferIndexFromID(getFormat().getSemanticID(RenderVertexSemantic::POSITION)); buf = getBuffer(index); if (buf) { format = getFormat().getBufferFormat(index); transformRenderBuffer(buf, buf, format, getVertexCount(), transformation); } // Normals index = (uint32_t)getFormat().getBufferIndexFromID(getFormat().getSemanticID(RenderVertexSemantic::NORMAL)); buf = getBuffer(index); if (buf) { // PH: the Cofactor matrix now also handles negative determinants, so it does the same as multiplying with the inverse transpose of transformation.M. const Cof44 cof(transformation); format = getFormat().getBufferFormat(index); transformRenderBuffer(buf, buf, format, getVertexCount(), cof.getBlock33()); } // Tangents index = (uint32_t)getFormat().getBufferIndexFromID(getFormat().getSemanticID(RenderVertexSemantic::TANGENT)); buf = getBuffer(index); if (buf) { format = getFormat().getBufferFormat(index); const PxMat33 tm(transformation.column0.getXYZ(), transformation.column1.getXYZ(), transformation.column2.getXYZ()); transformRenderBuffer(buf, buf, format, getVertexCount(), tm); } // Binormals index = (uint32_t)getFormat().getBufferIndexFromID(getFormat().getSemanticID(RenderVertexSemantic::BINORMAL)); buf = getBuffer(index); if (buf) { format = getFormat().getBufferFormat(index); const PxMat33 tm(transformation.column0.getXYZ(), transformation.column1.getXYZ(), transformation.column2.getXYZ()); transformRenderBuffer(buf, buf, format, getVertexCount(), tm); } }
void cGraph::getVertexLocation( double& x, double& y, int i ) { if( 0 > i || i >= getVertexCount() ) return; x = myGraph[ *vertices(myGraph).first + i ].getLocationX(); y = myGraph[ *vertices(myGraph).first + i ].getLocationY(); }
BoundingVolume* AbstractMesh::computeBoundingVolume() const { const int vertexCount = getVertexCount(); if (vertexCount <= 0) { return NULL; } double minX = 1e12; double minY = 1e12; double minZ = 1e12; double maxX = -1e12; double maxY = -1e12; double maxZ = -1e12; for (int i=0; i < vertexCount; i++) { const int i3 = i * 3; const double x = _vertices->get(i3 ) + _center._x; const double y = _vertices->get(i3 + 1) + _center._y; const double z = _vertices->get(i3 + 2) + _center._z; if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; if (z < minZ) minZ = z; if (z > maxZ) maxZ = z; } return new Box(Vector3D(minX, minY, minZ), Vector3D(maxX, maxY, maxZ)); }
unsigned int Mesh::addVertex(const Vertex& vertex) { unsigned int index = getVertexCount(); vertices.push_back(vertex); vertexLookupTable[vertex] = index; return index; }
//----------------------------------------------------------------------- bool Polygon::isPointInside(const Vector3& point) const { // sum the angles Real anglesum = 0; size_t n = getVertexCount(); for (size_t i = 0; i < n; i++) { const Vector3& p1 = getVertex(i); const Vector3& p2 = getVertex((i + 1) % n); Vector3 v1 = p1 - point; Vector3 v2 = p2 - point; Real len1 = v1.length(); Real len2 = v2.length(); if (Math::RealEqual(len1 * len2, 0.0f, 1e-4f)) { // We are on a vertex so consider this inside return true; } else { Real costheta = v1.dotProduct(v2) / (len1 * len2); anglesum += acos(costheta); } } // result should be 2*PI if point is inside poly return Math::RealEqual(anglesum, Math::TWO_PI, 1e-4f); }
//----------------------------------------------------------------------- void Polygon::updateNormal( void ) const { OgreAssertDbg( getVertexCount() >= 3, "Insufficient vertex count!" ); if (mIsNormalSet) return; // vertex order is ccw const Vector3& a = getVertex( 0 ); const Vector3& b = getVertex( 1 ); const Vector3& c = getVertex( 2 ); // used method: Newell mNormal.x = 0.5f * ( (a.y - b.y) * (a.z + b.z) + (b.y - c.y) * (b.z + c.z) + (c.y - a.y) * (c.z + a.z)); mNormal.y = 0.5f * ( (a.z - b.z) * (a.x + b.x) + (b.z - c.z) * (b.x + c.x) + (c.z - a.z) * (c.x + a.x)); mNormal.z = 0.5f * ( (a.x - b.x) * (a.y + b.y) + (b.x - c.x) * (b.y + c.y) + (c.x - a.x) * (c.y + a.y)); mNormal.normalise(); mIsNormalSet = true; }
//------------------------------------------------------------------------------------------------ Ogre::Vector3 VertexIndexToShape::getSize() { const unsigned int vCount = getVertexCount(); if (mBounds == Ogre::Vector3(-1,-1,-1) && vCount > 0) { const Ogre::Vector3 * const v = getVertices(); Ogre::Vector3 vmin(v[0]); Ogre::Vector3 vmax(v[0]); for(unsigned int j = 1; j < vCount; j++) { vmin.x = std::min(vmin.x, v[j].x); vmin.y = std::min(vmin.y, v[j].y); vmin.z = std::min(vmin.z, v[j].z); vmax.x = std::max(vmax.x, v[j].x); vmax.y = std::max(vmax.y, v[j].y); vmax.z = std::max(vmax.z, v[j].z); } mBounds.x = vmax.x - vmin.x; mBounds.y = vmax.y - vmin.y; mBounds.z = vmax.z - vmin.z; } return mBounds; }
void StaticGeometryBuffer::build( DrawHint drawHint ) { if(getVertexProperties() & TANGENTS) _generateTangents(); _generateIndices(); if( _vertexBufferHandle == 0 ) glGenBuffers( 1, &_vertexBufferHandle ); if( _indexBufferHandle == 0 ) glGenBuffers( 1, &_indexBufferHandle ); int vCount = getVertexCount(); int iCount = getIndexCount(); glBindBuffer( GL_ARRAY_BUFFER, _vertexBufferHandle ); glBufferData( GL_ARRAY_BUFFER, sizeof( Vertex ) * _vertexList.size(), &_vertexList[ 0 ], drawHint ); //glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof( Vertex ) * _vertexList.size(), &_vertexList[ 0 ] ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, _indexBufferHandle ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( GLuint ) * _indexList.size(), &_indexList[ 0 ] , drawHint ); // glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, sizeof( GLuint ) * _indexList.size(), &_indexList[ 0 ] ); }
void VertexGenerator::Mesh2D::dumpInfo() { LOG_INFO("<-Dumpping Mesh2D information->\n"); LOG_INFO("Vertex Point Count: %d, Vertex Size: %d, TexCoords Size: %d, Byte Stride: %d\n", getVertexCount(), getVertexSize(), getTexCoordsSize(), getByteStride()); for(size_t i = 0; i < getVertexCount(); ++i) { float* position = getPositions() + getStride() * i; LOG_INFO("VertexPosition[%d]: %f, %f\n", i, *position, *(position + 1)); } for(size_t i = 0; i < getVertexCount(); ++i) { float* texCoords = getTexCoords() + getStride() * i; LOG_INFO("TexCoords[%d]: %f, %f\n", i, *texCoords, *(texCoords + 1)); } }
void CC3MeshParticleEmitter::initializeParticle( CC3Particle* aParticle ) { // The vertex offsets depend on particleCount, which has not yet been incremented. ((CC3MeshParticle*)aParticle)->setFirstVertexOffset( getVertexCount() ); ((CC3MeshParticle*)aParticle)->setFirstVertexIndexOffset( getVertexIndexCount() ); copyTemplateContentToParticle( ((CC3MeshParticle*)aParticle) ); }
void Mesh::forAllIndices(std::function<void(int iter, int index)> func) { if (!mIndices) { for (int i = 0; i < getVertexCount(); ++i) { func(i, i); } } else if (mIndices->getIndexSize() == 2) { const unsigned short* indexData = reinterpret_cast<const unsigned short *>(mIndices->getIndexData()); for (int i = 0; i < mIndices->getIndexCount(); ++i) { int v = *(indexData + i); func(i, v); } } else { const unsigned int* indexData = reinterpret_cast<const unsigned int *>(mIndices->getIndexData()); for (int i = 0; i < mIndices->getIndexCount(); ++i) { int v = *(indexData + i); func(i, v); } } }
void Spline::addVertex(const unsigned int index, const sf::Vector2f position) { if (index < getVertexCount()) m_vertices.insert(m_vertices.begin() + index, Vertex(position)); else addVertex(position); }
void ApexVertexBuffer::applyScale(float scale) { uint32_t index = (uint32_t)getFormat().getBufferIndexFromID(getFormat().getSemanticID(RenderVertexSemantic::POSITION)); void* buf = getBuffer(index); RenderDataFormat::Enum format = getFormat().getBufferFormat(index); transformRenderBuffer(buf, buf, format, getVertexCount(), scale); }
void Scene::onPolyhedronChanged() { // Update Polyhedron auto symbol = "#" + wild::conversion_cast<std::string>(wild::mod(_index, 80) + 1); _pgeometry->setSymbol(symbol); _pgeometry->setFaceMask(static_cast<osgKaleido::PolyhedronGeometry::FaceMask>(_faces)); auto polyhedron = _pgeometry->getOrCreatePolyhedron(); OSG_INFO << polyhedron->getName() << " (" << polyhedron->getDualName() << "*)" << std::endl; OSG_INFO << polyhedron->getWythoffSymbol() << std::endl; OSG_INFO << polyhedron->getVertexConfiguration() << std::endl; OSG_INFO << polyhedron->getVertexCount() << std::endl; OSG_INFO << polyhedron->getFaceCount() << std::endl; // Update Vertices osg::ref_ptr<osg::Vec3Array> vertices = osgKaleido::createVertexArray(*polyhedron); auto stateSet = _vgeode->getOrCreateStateSet(); auto offsets = stateSet->getUniform("offsets"); copy(offsets, vertices, osg::Vec3()); // Update Text _text->setText(polyhedron->getName() + "\n" + polyhedron->getWythoffSymbol()); }
cVertex& cGraph::getVertex( int i ) { if( 0 > i || i >= getVertexCount() ) { static cVertex vertex_null; return vertex_null; } return myGraph[ *vertices(myGraph).first + i ]; }
//----------------------------------------------------------------------- void Polygon::setVertex(const Vector3& vdata, size_t vertex ) { // TODO: optional: check planarity OgreAssertDbg(vertex < getVertexCount(), "Search position out of range" ); // set new vertex mVertexList[ vertex ] = vdata; }
void cGraph::setFreeLocation( int i ) { if( 0 > i || i >= getVertexCount() ) return; graph_t::vertex_descriptor v = *vertices(myGraph).first; myGraph[v+i].myFixedLocation = false; SaveToDB(); }
//----------------------------------------------------------------------- const Vector3& Polygon::getNormal( void ) const { OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" ); updateNormal(); return mNormal; }
// can be optimized with new pointInside() bool OctreeProjectedPolygon::occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView) const { OctreeProjectedPolygon::occludes_calls++; // if we are completely out of view, then we definitely don't occlude! // if the occludee is completely out of view, then we also don't occlude it // // this is true, but unfortunately, we're not quite handling projects in the // case when SOME points are in view and others are not. So, we will not consider // occlusion for any shadows that are partially in view. if (checkAllInView && (!getAllInView() || !occludee.getAllInView())) { return false; } // first check the bounding boxes, the occludee must be fully within the boounding box of this shadow if ((occludee.getMaxX() > getMaxX()) || (occludee.getMaxY() > getMaxY()) || (occludee.getMinX() < getMinX()) || (occludee.getMinY() < getMinY())) { return false; } // we need to test for identity as well, because in the case of identity, none of the points // will be "inside" but we don't want to bail early on the first non-inside point bool potentialIdenity = false; if ((occludee.getVertexCount() == getVertexCount()) && (getBoundingBox().contains(occludee.getBoundingBox())) ) { potentialIdenity = true; } // if we got this far, then check each vertex of the occludee, if all those points // are inside our polygon, then the tested occludee is fully occluded int pointsInside = 0; for(int i = 0; i < occludee.getVertexCount(); i++) { bool vertexMatched = false; if (!pointInside(occludee.getVertex(i), &vertexMatched)) { // so the point we just tested isn't inside, but it might have matched a vertex // if it didn't match a vertext, then we bail because we can't be an identity // or if we're not expecting identity, then we also bail early, no matter what if (!potentialIdenity || !vertexMatched) { return false; } } else { pointsInside++; } } // we're only here if all points are inside matched and/or we had a potentialIdentity we need to check if (pointsInside == occludee.getVertexCount()) { return true; } // If we have the potential for identity, then test to see if we match, if we match, we occlude if (potentialIdenity) { return matches(occludee); } return false; // if we got this far, then we're not occluded }
//----------------------------------------------------------------------- void Polygon::deleteVertex( size_t vertex ) { OgreAssertDbg( vertex < getVertexCount(), "Search position out of range" ); VertexList::iterator it = mVertexList.begin(); std::advance(it, vertex); mVertexList.erase( it ); }
void cGraph::setFixedLocation( int i, double x, double y ) { if( 0 > i || i >= getVertexCount() ) return ; graph_t::vertex_descriptor v = *vertices(myGraph).first; myGraph[v+i].myFixedLocation = true; myGraph[v+i].setFixedLocation( x, y ); SaveToDB(); }
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); }