Intersection Disc::GetIntersection(Ray r) { //Transform the ray Ray r_loc = r.GetTransformedCopy(transform.invT()); Intersection result; //Ray-plane intersection float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - r_loc.origin)) / glm::dot(glm::vec3(0,0,1), r_loc.direction); glm::vec4 P = glm::vec4(t * r_loc.direction + r_loc.origin, 1); //Check that P is within the bounds of the disc (not bothering to take the sqrt of the dist b/c we know the radius) float dist2 = (P.x * P.x + P.y * P.y); if(t > 0 && dist2 <= 0.25f) { result.point = glm::vec3(transform.T() * P); result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0))); result.object_hit = this; result.t = glm::distance(result.point, r.origin); //was interp result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(P)), material->texture); //Compute tangent and bitangent glm::vec3 T = glm::normalize(glm::cross(glm::vec3(0,1,0), ComputeNormal(glm::vec3(P)))); glm::vec3 B = glm::cross(ComputeNormal(glm::vec3(P)), T); result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(T, 0))); result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(B, 0))); } return result; }
Intersection SquarePlane::GetIntersection(Ray r) { //Transform the ray Ray r_loc = r.GetTransformedCopy(transform.invT()); Intersection result; //Ray-plane intersection float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - r_loc.origin)) / glm::dot(glm::vec3(0,0,1), r_loc.direction); glm::vec4 P = glm::vec4(t * r_loc.direction + r_loc.origin, 1); //Check that P is within the bounds of the square if(t > 0 && P.x >= -0.5f && P.x <= 0.5f && P.y >= -0.5f && P.y <= 0.5f) { result.point = glm::vec3(transform.T() * P); result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0))); result.object_hit = this; result.t = glm::distance(result.point, r.origin); result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture); // Store the tangent and bitangent glm::vec3 tangent; glm::vec3 bitangent; ComputeTangents(ComputeNormal(glm::vec3(P)), tangent, bitangent); result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(tangent, 0))); result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(bitangent, 0))); return result; } return result; }
Intersection SquarePlane::GetIntersection(Ray r) { //Transform the ray Ray rLocal = r.GetTransformedCopy(transform.invT()); Intersection result; //Ray-plane intersection float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - rLocal.origin)) / glm::dot(glm::vec3(0,0,1), rLocal.direction); glm::vec4 P = glm::vec4(t * rLocal.direction + rLocal.origin, 1); //Check that P is within the bounds of the square if(t > 0 && P.x >= -0.5f && P.x <= 0.5f && P.y >= -0.5f && P.y <= 0.5f) { result.point = glm::vec3(transform.T() * P); result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0))); result.object_hit = this; result.t = glm::distance(result.point, r.origin); //was interp result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(P)), material->texture); glm::vec3 T = glm::normalize(glm::cross(glm::vec3(0,1,0), ComputeNormal(glm::vec3(P)))); glm::vec3 B = glm::cross(ComputeNormal(glm::vec3(P)), T); result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(T, 0))); result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(B, 0))); return result; } return result; }
glm::vec3 Face::computeNormal() const { // note: this face might be non-planar, so average the two triangle normals glm::vec3 a = (*this)[0]->get(); glm::vec3 b = (*this)[1]->get(); glm::vec3 c = (*this)[2]->get(); glm::vec3 d = (*this)[3]->get(); return 0.5f * (ComputeNormal(a,b,c) + ComputeNormal(a,c,d)); }
Vec3f Face::computeNormal() const { // note: this face might be non-planar, so average the two triangle normals Vec3f a = (*this)[0]->get(); Vec3f b = (*this)[1]->get(); Vec3f c = (*this)[2]->get(); Vec3f d = (*this)[3]->get(); return 0.5 * (ComputeNormal(a,b,c) + ComputeNormal(a,c,d)); }
void Triangle::ReplaceVertex(Vertex *vold,Vertex *vnew) { assert(vold && vnew); assert(vold==vertex[0] || vold==vertex[1] || vold==vertex[2]); assert(vnew!=vertex[0] && vnew!=vertex[1] && vnew!=vertex[2]); if(vold==vertex[0]){ vertex[0]=vnew; } else if(vold==vertex[1]){ vertex[1]=vnew; } else { assert(vold==vertex[2]); vertex[2]=vnew; } Remove(vold->face,this); assert(!Contains(vnew->face,this)); vnew->face.push_back(this); for (int i = 0; i<3; i++) { vold->RemoveIfNonNeighbor(vertex[i]); vertex[i]->RemoveIfNonNeighbor(vold); } for (int i = 0; i<3; i++) { assert(Contains(vertex[i]->face,this)==1); for(int j=0;j<3;j++) if(i!=j) { AddUnique(vertex[i]->neighbor,vertex[j]); } } ComputeNormal(); }
bool OpenglProject::GetNormalFromIDs(int idx1, int idz1, int idx2, int idz2, int idx3, int idz3, int xResolution, int zResolution, Vector3& normal, float* vertex_array) { if( idx1 >= 0 && idx1 < xResolution && idx2 >= 0 && idx2 < xResolution && idx3 >= 0 && idx3 < xResolution && idz1 >= 0 && idz1 < zResolution && idz2 >= 0 && idz2 < zResolution && idz3 >= 0 && idz3 < zResolution ) { float fx1 = vertex_array[ ( idx1 * zResolution + idz1) * 3]; float fy1 = vertex_array[ ( idx1 * zResolution + idz1) * 3 + 1]; float fz1 = vertex_array[ ( idx1 * zResolution + idz1) * 3 + 2]; float fx2 = vertex_array[ ( idx2 * zResolution + idz2) * 3]; float fy2 = vertex_array[ ( idx2 * zResolution + idz2) * 3 + 1]; float fz2 = vertex_array[ ( idx2 * zResolution + idz2) * 3 + 2]; float fx3 = vertex_array[ ( idx3 * zResolution + idz3) * 3]; float fy3 = vertex_array[ ( idx3 * zResolution + idz3) * 3 + 1]; float fz3 = vertex_array[ ( idx3 * zResolution + idz3) * 3 + 2]; normal = ComputeNormal(Vector3(fx1, fy1, fz1), Vector3(fx2, fy2, fz2), Vector3(fx3, fy3, fz3)); normal = normalize(normal); return true; } return false; }
void ObjMesh::Init() { ReadFromFile(filePath.c_str(), scale_factor); ComputeNormal(); ApplyTransformation(); ComputeAABB(); }
RadianceShape::RadianceShape(std::vector<Vector3f> vertexList, std::vector<int> indiceList) : Element() { _vertices = new Vertex[vertexList.size()]; _normal = new Vector3f[vertexList.size()]; _indices = new int[indiceList.size()]; _nbVertices = vertexList.size(); _nbIndices = indiceList.size(); for (int i = 0 ; i < (int) _nbVertices ; ++i) { _vertices[i].position = glm::vec3(vertexList[i]._x, vertexList[i]._y, vertexList[i]._z); } for (int i = 0; i < (int) _nbIndices; ++i) { _indices[i] = indiceList[i]; } ComputeNormal(); }
void Triangle::ReplaceVertex(Vertex *vold,Vertex *vnew) { ASSERT(vold && vnew); ASSERT(vold==vertex[0] || vold==vertex[1] || vold==vertex[2]); ASSERT(vnew!=vertex[0] && vnew!=vertex[1] && vnew!=vertex[2]); if( vold==vertex[0] ) vertex[0]=vnew; else if( vold==vertex[1] ) vertex[1]=vnew; else vertex[2]=vnew; vold->face.removeSearch(this); ASSERT(vnew->face.search(this) < 0); vnew->face.push(this); int i =0; for(;i<3;i++) { vold->RemoveIfNonNeighbor(vertex[i]); vertex[i]->RemoveIfNonNeighbor(vold); } for(i=0;i<3;i++) { ASSERT( vertex[i]->face.search(this) >= 0 ); for(int j=0;j<3;j++) if(i!=j) vertex[i]->neighbor.pushUnique( vertex[j] ); } ComputeNormal(); }
/* Determine the polygon normal and project vertices onto the plane * of the polygon. */ void __gl_projectPolygon( GLUtesselator *tess ) { GLUvertex *v, *vHead = &tess->mesh->vHead; GLdouble norm[3]; GLdouble *sUnit, *tUnit; int i, computedNormal = FALSE; norm[0] = tess->normal[0]; norm[1] = tess->normal[1]; norm[2] = tess->normal[2]; if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { ComputeNormal( tess, norm ); computedNormal = TRUE; } sUnit = tess->sUnit; tUnit = tess->tUnit; i = LongAxis( norm ); #if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT) /* Choose the initial sUnit vector to be approximately perpendicular * to the normal. */ Normalize( norm ); sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; /* Now make it exactly perpendicular */ w = Dot( sUnit, norm ); sUnit[0] -= w * norm[0]; sUnit[1] -= w * norm[1]; sUnit[2] -= w * norm[2]; Normalize( sUnit ); /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1]; tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2]; tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0]; Normalize( tUnit ); #else /* Project perpendicular to a coordinate axis -- better numerically */ sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; tUnit[i] = 0; tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y; tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X; #endif /* Project the vertices onto the sweep plane */ for( v = vHead->next; v != vHead; v = v->next ) { v->s = Dot( v->coords, sUnit ); v->t = Dot( v->coords, tUnit ); } if( computedNormal ) { CheckOrientation( tess ); } }
Intersection SquarePlane::GetSampledIntersection(float randX, float randY, const glm::vec3 &isx_normal) { glm::vec4 point = glm::vec4(-0.5 + randX, -0.5 + randY, 0.f, 1.f); Intersection result; result.point = glm::vec3(transform.T() * point); result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(point)), 0))); result.object_hit = this; result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(point)), material->texture); return result; }
void Face::computeCachedNormal() { // note: this face might be non-planar, so average the two triangle normals Vec3f a = (*this)[0]->get(); Vec3f b = (*this)[1]->get(); Vec3f c = (*this)[2]->get(); Vec3f d = (*this)[3]->get(); //Checks to make sure we don't have three points that we are using here to check the normal be linear -- that could cause errors!! if(isLinear(a,b,c)){ cached_normal = new Vec3f(ComputeNormal(a,c,d)); return; } if(isLinear(a,c,d)){ cached_normal = new Vec3f(ComputeNormal(a,b,c)); return; } cached_normal = new Vec3f(0.5 * (ComputeNormal(a,b,c) + ComputeNormal(a,c,d))); return; }
Triangle::Triangle(Vertex *v0,Vertex *v1,Vertex *v2){ assert(v0!=v1 && v1!=v2 && v2!=v0); vertex[0]=v0; vertex[1]=v1; vertex[2]=v2; ComputeNormal(); triangles.push_back(this); for(int i=0;i<3;i++) { vertex[i]->face.push_back(this); for(int j=0;j<3;j++) if(i!=j) { AddUnique(vertex[i]->neighbor, vertex[j]); } } }
void Shape::UpdateOutline() { unsigned int count = myVertices.GetVertexCount() - 2; myOutlineVertices.Resize((count + 1) * 2); for (unsigned int i = 0; i < count; ++i) { unsigned int index = i + 1; // Get the two segments shared by the current point Vector2f p0 = (i == 0) ? myVertices[count].Position : myVertices[index - 1].Position; Vector2f p1 = myVertices[index].Position; Vector2f p2 = myVertices[index + 1].Position; // Compute their normal Vector2f n1 = ComputeNormal(p0, p1); Vector2f n2 = ComputeNormal(p1, p2); // Combine them to get the extrusion direction float factor = 1.f + (n1.x * n2.x + n1.y * n2.y); Vector2f normal = -(n1 + n2) / factor; // Update the outline points myOutlineVertices[i * 2 + 0].Position = p1; myOutlineVertices[i * 2 + 1].Position = p1 + normal * myOutlineThickness; } // Duplicate the first point at the end, to close the outline myOutlineVertices[count * 2 + 0].Position = myOutlineVertices[0].Position; myOutlineVertices[count * 2 + 1].Position = myOutlineVertices[1].Position; // Update outline colors UpdateOutlineColors(); // Update the shape's bounds myBounds = myOutlineVertices.GetBounds(); }
void Mesh::SetupFloor() { Vec3f diff = bbox.getMax()-bbox.getMin(); // create vertices just a bit bigger than the bounding box Vec3f a = bbox.getMin() + Vec3f(-0.75*diff.x(),0,-0.75*diff.z()); Vec3f b = bbox.getMin() + Vec3f( 1.75*diff.x(),0,-0.75*diff.z()); Vec3f c = bbox.getMin() + Vec3f(-0.75*diff.x(),0, 1.75*diff.z()); Vec3f d = bbox.getMin() + Vec3f( 1.75*diff.x(),0, 1.75*diff.z()); Vec3f normal = ComputeNormal(a,c,d); floor_quad_verts.push_back(VBOPosNormal(a,normal)); floor_quad_verts.push_back(VBOPosNormal(c,normal)); floor_quad_verts.push_back(VBOPosNormal(d,normal)); floor_quad_verts.push_back(VBOPosNormal(b,normal)); glBindBuffer(GL_ARRAY_BUFFER,floor_quad_verts_VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPosNormal)*4,&floor_quad_verts[0],GL_STATIC_DRAW); }
SliceOrdering::SliceOrdering(ServerIndex& index, const std::string& seriesId) : index_(index), seriesId_(seriesId), isVolume_(false) { ComputeNormal(); CreateInstances(); if (!SortUsingPositions() && !SortUsingIndexInSeries()) { LOG(ERROR) << "Unable to order the slices of the series " << seriesId; throw OrthancException(ErrorCode_CannotOrderSlices); } }
Intersection Disc::GetSampledIntersection(float randX, float randY, const glm::vec3 &isx_normal) { float r = sqrtf(randX); float theta = 2.f * M_PI * randY; glm::vec4 point = glm::vec4( r*cosf(theta), r*sinf(theta), 0.f, 1.f ); Intersection result; result.point = glm::vec3(transform.T() * point); result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(point)), 0))); result.object_hit = this; result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(point)), material->texture); return result; }
Triangle::Triangle(Vertex *v0,Vertex *v1,Vertex *v2) { ASSERT(v0!=v1 && v1!=v2 && v2!=v0); vertex[0]=v0; vertex[1]=v1; vertex[2]=v2; ComputeNormal(); s_Triangles.push(this); for(int i=0;i<3;i++) { vertex[i]->face.push(this); for(int j=0;j<3;j++) if(i != j) vertex[i]->neighbor.pushUnique( vertex[j] ); } }
CPolygon::CPolygon(vector<CVector>& verts, vector<tex_coord_t>& tex_coords) { assert(verts.size() == tex_coords.size()); //Looks a little messy, but it's so we only use one iterator instead of two. vector<CVector>::iterator vert_itr; unsigned int i = 0; for(vert_itr = verts.begin(); vert_itr!= verts.end(); vert_itr++) { m_verts.push_back(*vert_itr); m_tex_coords.push_back((tex_coords)[i]); i++; } //make sure it was all copied over correctly assert(m_verts.size() == m_tex_coords.size()); ComputeNormal(); m_cached_midpoint = GetMidpoint(); }
void Terrain::Initialize(const char* sTexture, const char* sHeightMap, const char* sNormalMap, float fHeight) { SetHeight(fHeight); ImageBMP* image = new ImageBMP(m_OpenGL); image->Load(sHeightMap); m_Texture = new Texture(m_OpenGL); TextureID = m_Texture->GetTexture2D(sTexture); iWidth = image->GetWidth(); iHeight = image->GetHeight(); hs = new float*[image->GetHeight()]; Normal = new Vector3f*[image->GetHeight()]; NormalTemp = new Vector3f*[image->GetHeight()]; for (unsigned int i = 0; i < image->GetHeight(); ++i) { hs[i] = new float[image->GetWidth()]; Normal[i] = new Vector3f[image->GetWidth()]; NormalTemp[i] = new Vector3f[image->GetWidth()]; } for (unsigned int y = 0; y < image->GetHeight(); y++) { for (unsigned int x = 0; x < image->GetWidth(); x++) { unsigned char color = (unsigned char)image->GetData()[3 * (y * image->GetWidth() + x)]; float h = ((color / 255.0f) - 0.5f); SetHeight(x, y, h); } } ComputeNormal(); GenerateTerrain(); Bind(); vPosition = Vector3f(0, -20, 0); }
void Mesh::SetupMesh(triangleshashtype &triSet, GLuint VBO, std::vector<VBOPosNormal> &VBO_verts_vector) { for (auto iter = triSet.begin(); iter != triSet.end(); iter++) { Triangle *t = iter->second; Vec3f a = (*t)[0]->getPos(); Vec3f b = (*t)[1]->getPos(); Vec3f c = (*t)[2]->getPos(); Vec3f na = ComputeNormal(a,b,c); Vec3f nb = na; Vec3f nc = na; if (args->gouraud_normals) { na = (*t)[0]->getGouraudNormal(); nb = (*t)[1]->getGouraudNormal(); nc = (*t)[2]->getGouraudNormal(); } VBO_verts_vector.push_back(VBOPosNormal(a,na)); VBO_verts_vector.push_back(VBOPosNormal(b,nb)); VBO_verts_vector.push_back(VBOPosNormal(c,nc)); } glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(VBOPosNormal) * numTriangles(triSet) * 3, &VBO_verts_vector[0], GL_STATIC_DRAW); }
/* __gl_renderCache( tess ) takes a single contour and tries to render it * as a triangle fan. This handles convex polygons, as well as some * non-convex polygons if we get lucky. * * Returns TRUE if the polygon was successfully rendered. The rendering * output is provided as callbacks (see the api). */ GLboolean __gl_renderCache( GLUtesselator *tess ) { CachedVertex *v0 = tess->cache; CachedVertex *vn = v0 + tess->cacheCount; CachedVertex *vc; GLdouble norm[3]; int sign; if( tess->cacheCount < 3 ) { /* Degenerate contour -- no output */ return TRUE; } norm[0] = tess->normal[0]; norm[1] = tess->normal[1]; norm[2] = tess->normal[2]; if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { ComputeNormal( tess, norm, FALSE ); } sign = ComputeNormal( tess, norm, TRUE ); if( sign == SIGN_INCONSISTENT ) { /* Fan triangles did not have a consistent orientation */ return FALSE; } if( sign == 0 ) { /* All triangles were degenerate */ return TRUE; } /* Make sure we do the right thing for each winding rule */ switch( tess->windingRule ) { case GLU_TESS_WINDING_ODD: case GLU_TESS_WINDING_NONZERO: break; case GLU_TESS_WINDING_POSITIVE: if( sign < 0 ) return TRUE; break; case GLU_TESS_WINDING_NEGATIVE: if( sign > 0 ) return TRUE; break; case GLU_TESS_WINDING_ABS_GEQ_TWO: return TRUE; } CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN : GL_TRIANGLES ); CALL_VERTEX_OR_VERTEX_DATA( v0->data ); if( sign > 0 ) { for( vc = v0+1; vc < vn; ++vc ) { CALL_VERTEX_OR_VERTEX_DATA( vc->data ); } } else { for( vc = vn-1; vc > v0; --vc ) { CALL_VERTEX_OR_VERTEX_DATA( vc->data ); } } CALL_END_OR_END_DATA(); return TRUE; }
//================================================================================== void HullLibrary::AddConvexTriangle(ConvexHullTriangleInterface *callback,const float *p1,const float *p2,const float *p3) { ConvexHullVertex v1,v2,v3; #define TSCALE1 (1.0f/4.0f) v1.mPos[0] = p1[0]; v1.mPos[1] = p1[1]; v1.mPos[2] = p1[2]; v2.mPos[0] = p2[0]; v2.mPos[1] = p2[1]; v2.mPos[2] = p2[2]; v3.mPos[0] = p3[0]; v3.mPos[1] = p3[1]; v3.mPos[2] = p3[2]; float n[3]; ComputeNormal(n,p1,p2,p3); v1.mNormal[0] = n[0]; v1.mNormal[1] = n[1]; v1.mNormal[2] = n[2]; v2.mNormal[0] = n[0]; v2.mNormal[1] = n[1]; v2.mNormal[2] = n[2]; v3.mNormal[0] = n[0]; v3.mNormal[1] = n[1]; v3.mNormal[2] = n[2]; const float *tp1 = p1; const float *tp2 = p2; const float *tp3 = p3; int32_t i1 = 0; int32_t i2 = 0; float nx = fabsf(n[0]); float ny = fabsf(n[1]); float nz = fabsf(n[2]); if ( nx <= ny && nx <= nz ) i1 = 0; if ( ny <= nx && ny <= nz ) i1 = 1; if ( nz <= nx && nz <= ny ) i1 = 2; switch ( i1 ) { case 0: if ( ny < nz ) i2 = 1; else i2 = 2; break; case 1: if ( nx < nz ) i2 = 0; else i2 = 2; break; case 2: if ( nx < ny ) i2 = 0; else i2 = 1; break; } v1.mTexel[0] = tp1[i1]*TSCALE1; v1.mTexel[1] = tp1[i2]*TSCALE1; v2.mTexel[0] = tp2[i1]*TSCALE1; v2.mTexel[1] = tp2[i2]*TSCALE1; v3.mTexel[0] = tp3[i1]*TSCALE1; v3.mTexel[1] = tp3[i2]*TSCALE1; callback->ConvexHullTriangle(v3,v2,v1); }
const CVector& CPolygon::GetNormal() { ComputeNormal(); return m_normal; }