void FPoly::Scale ( const FVector& PreSubtract, const FVector& Scale ) { if (Scale.X == 1.f && Scale.Y == 1.f && Scale.Z == 1.f) { return; } // Scale the vertices. for (int32 Vertex = 0; Vertex < Vertices.Num(); Vertex++) { Vertices[Vertex] = PreSubtract + (Vertices[Vertex] - PreSubtract) * Scale; } Base = PreSubtract + (Base - PreSubtract) * Scale; // Scale the texture vectors. TextureU *= Scale; TextureV *= Scale; // Recalculate the normal. Non-uniform scale or mirroring requires this. CalcNormal(true); }
LineSeg::LineSeg(const Vertex2D& p1, const Vertex2D& p2, const float _zlow, const float _zhigh) : v1(p1), v2(p2) { m_rcHitRect.zlow = _zlow; m_rcHitRect.zhigh = _zhigh; CalcNormal(); }
void CGWorldTriangleStrip::SetRotationStripNormals() { //Sets normal vectors for all the triangles assuming that //the represent a rectangular solid between two stations. ASSERT(m_iNumVertices==10); //if not,this is some other shape //Could go to 11, but if the user f****d up the call into here //at least this won't crash //The pattern we used is aimed at given normals to the //vertices which are between the two flat surfaces. Best is to //simply draw the pattern and figure out how this works for //yourself. for (int i=0; i<m_iNumVertices; i++) { int iOne,iThree; int iTwo=i; if (i%2==0) //even { iOne=i-3; iThree=i+1; } else { iOne=i-1; iThree=i+3; } if (iOne<0) iOne+=10; if (iThree>=10) iThree-=10; CalcNormal(m_pVertices[iOne].m_fPos,m_pVertices[iTwo].m_fPos,m_pVertices[iThree].m_fPos,m_pVertices[i].m_fNormal); } }
int CPolyMesh3::CalcOrgNormal() { int fno; for( fno = 0; fno < m_facenum; fno++ ){ int n3p = fno * 3; N3P* curn3p = m_n3p + n3p; D3DXVECTOR3 vpos[3]; int indexno; for( indexno = 0; indexno < 3; indexno++ ){ int vertno = (curn3p + indexno)->pervert->vno; vpos[indexno] = *( m_pointbuf + vertno ); } D3DXVECTOR3 nvec; CalcNormal( &nvec, vpos, vpos + 1, vpos + 2 ); for( indexno = 0; indexno < 3; indexno++ ){ (curn3p + indexno)->perface->facenormal = nvec; (curn3p + indexno)->pervert->smnormal = nvec; } } return 0; }
void TriObject::applyNormals() { if (numfaces == 0) return; delete[]nx; delete[]ny; delete[]nz; nx = new float[numfaces / 3]; ny = new float[numfaces / 3]; nz = new float[numfaces / 3]; if (nx == NULL || ny == NULL || nz == NULL) { delete[]nx; delete[]ny; delete[]nz; normalapplied = FALSE; return; } float normal[3]; for (int i = 0; i < numfaces / 3; i++) { CalcNormal(3 * i, normal); ReduceToUnit(normal); nx[i] = normal[0]; ny[i] = normal[1]; nz[i] = normal[2]; } normalapplied = TRUE; }
bool HypercomplexZ3FractalRules::Iterate(const Vector3d& IPoint, const Fractal *HCompl, const Vector3d& Direction, DBL *Dist, DBL **IterStack) const { int i; DBL xx, yy, zz, ww; DBL Exit_Value, F_Value, Step; DBL x, y, z, w; Vector3d H_Normal; x = IterStack[X][0] = IPoint[X]; y = IterStack[Y][0] = IPoint[Y]; z = IterStack[Z][0] = IPoint[Z]; w = IterStack[W][0] = (HCompl->SliceDist - HCompl->Slice[X]*x - HCompl->Slice[Y]*y - HCompl->Slice[Z]*z)/HCompl->Slice[T]; Exit_Value = HCompl->Exit_Value; for (i = 1; i <= HCompl->Num_Iterations; ++i) { F_Value = x * x + y * y + z * z + w * w; if (F_Value > Exit_Value) { CalcNormal(H_Normal, i - 1, HCompl, IterStack); Step = dot(H_Normal, Direction); if (Step < -Fractal_Tolerance) { Step = -2.0 * Step; if ((F_Value > HCompl->Precision * Step) && (F_Value < 30 * HCompl->Precision * Step)) { *Dist = F_Value / Step; return (false); } } *Dist = HCompl->Precision; return (false); } /*************** Case: z->z^2+c *********************/ HSqr(xx, yy, zz, ww, x, y, z, w); x = IterStack[X][i] = xx + HCompl->Julia_Parm[X]; y = IterStack[Y][i] = yy + HCompl->Julia_Parm[Y]; z = IterStack[Z][i] = zz + HCompl->Julia_Parm[Z]; w = IterStack[W][i] = ww + HCompl->Julia_Parm[T]; } *Dist = HCompl->Precision; return (true); }
Intersection *Sphere::IntersectsRay(Ray r, STTransform4 transMatrix) { float a, b, c; a = pow(r.direction.x,2) + pow(r.direction.y,2) + pow(r.direction.z,2); b = 2*((r.start.x - center.x)*r.direction.x + (r.start.y - center.y)*r.direction.y + (r.start.z - center.z)*r.direction.z); c = pow(r.start.x - center.x,2) + pow(r.start.y - center.y,2) + pow(r.start.z - center.z,2) - pow(radius,2); float discriminant = pow(b,2) - 4*a*c; if (discriminant < 0.0) return NULL; if (discriminant == 0.0) { float t = -b / (2*a); if (r.invalidT(t)) return NULL; STVector3 interRay = (*(r.InterpolatedRay(t))); STVector3 normal = CalcNormal(interRay, r); Intersection *rt = new Intersection(t, interRay, normal, r.TransformRay(transMatrix.Inverse())); return rt; } float t1 = (-b - sqrt(discriminant)) / (2*a); float t2 = (-b + sqrt(discriminant)) / (2*a); if (r.invalidT(t1) && !r.invalidT(t2)) { STVector3 interRay = (*(r.InterpolatedRay(t2))); STVector3 normal = CalcNormal(interRay, r); Intersection *rt = new Intersection(t2, interRay, normal, r.TransformRay(transMatrix.Inverse())); return rt; } if (!r.invalidT(t1) && r.invalidT(t2)) { STVector3 interRay = (*(r.InterpolatedRay(t1))); STVector3 normal = CalcNormal(interRay, r); Intersection *rt = new Intersection(t1, interRay, normal, r.TransformRay(transMatrix.Inverse())); return rt; } if (r.invalidT(t1) && r.invalidT(t2)) return NULL; STVector3 interRay = (*(r.InterpolatedRay(fmin(t1,t2)))); STVector3 normal = CalcNormal(interRay, r); Intersection *rt = new Intersection(fmin(t1,t2), interRay, normal, r.TransformRay(transMatrix.Inverse())); return rt; }
void CGWorldTriangleStrip::SetRectNormals() { //Sets normal vectors for all the triangles assuming that //the represent a flat rectangle ASSERT(m_iNumVertices==4); //if not,this is some other shape float fNormal[3]; CalcNormal(m_pVertices[0].m_fPos,m_pVertices[1].m_fPos,m_pVertices[2].m_fPos,fNormal); for (int i=0; i<m_iNumVertices; i++) { m_pVertices[i].m_fNormal[0]=fNormal[0]; m_pVertices[i].m_fNormal[1]=fNormal[1]; m_pVertices[i].m_fNormal[2]=fNormal[2]; } }
bool ribi::Geometry::IsCounterClockwiseCartesian( const Coordinats3D& points, const Coordinat3D& observer ) const noexcept { // const bool verbose{false}; const int n_points{static_cast<int>(points.size())}; assert(n_points == 3 || n_points == 4); if (n_points == 3) { const auto a = points[0]; const auto b = points[1]; const auto c = points[2]; const auto normal = CalcNormal(a,b,c); const double direction{CalcDotProduct(normal,a - observer)}; const bool is_counter_clockwise{direction > 0.0}; //Difference between CW ('<') and CCW ('>') return is_counter_clockwise; } else { assert(n_points == 4); //See if the points in the projection are in the same direction assert(Geometry().IsPlane(points)); const std::unique_ptr<Plane> plane(new Plane(points[0],points[1],points[2])); assert(plane); const auto v = plane->CalcProjection( { points[0], points[1], points[2], points[3] } ) ; //If the points are messed up, they cannot be clockwise if (!IsClockwiseCartesianHorizontal(v) && !IsCounterClockwiseCartesianHorizontal(v)) return false; //The neatly orderder point have the same winding as the first three std::remove_const<std::remove_reference<decltype(points)>::type>::type a; std::copy(points.begin() + 0,points.begin() + 3,std::back_inserter(a)); return IsCounterClockwiseCartesian(a,observer); } }
bool FPoly::IsCoplanar() { // 3 or fewer vertices is automatically coplanar if( Vertices.Num() <= 3 ) { return 1; } CalcNormal(1); for( int32 x = 0 ; x < Vertices.Num() ; ++x ) { if( !OnPlane( Vertices[x] ) ) { return 0; } } // If we got this far, the poly has to be coplanar. return 1; }
void DrawGLScene() { stVec p1,p2,p3,Norm; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor4f(1.0f,0.0f,0.0f,0.25f); glLoadIdentity(); glTranslatef(0.0f,0.0f,-5.0f); glRotatef(xrot,0.1f,0.1f,0.0f); glRotatef(yrot,0.0f,0.001f,0.0f); glRotatef(zrot,0.0f,0.0f,0.001f); //glMaterialfv(GL_FRONT, GL_AMBIENT, LightColor); //glMaterialfv(GL_FRONT, GL_SPECULAR, LightColor); //glutSolidTeapot(0.2f); glBegin(GL_TRIANGLES); // Calc the top face normal p3.x= 0.0f; p3.y= 0.0f; p3.z= -1.0f; p2.x= 0.5f; p2.y= -0.5f; p2.z= 0.0f; p1.x= 0.5f; p1.y= 0.5f; p1.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); //glColor4f(0.0f,1.0f,1.0f,1.0f); glVertex3f(0.0f, 0.0f, -1.0f); glVertex3f(0.5f, -0.5f, 0.0f); glVertex3f(0.5f, 0.5f, 0.0f); // Calc the top face normal p1.x= 0.0f; p1.y= 0.0f; p1.z= -1.0f; p2.x= -0.5f; p2.y= -0.5f; p2.z= 0.0f; p3.x= -0.5f; p3.y= 0.5f; p3.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); //glColor4f(1.0f,1.0f,0.0f,1.0f); glVertex3f(0.0f, 0.0f, -1.0f); glVertex3f(-0.5f, -0.5f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.0f); // Calc the top face normal p3.x= 0.0f; p3.y= 0.0f; p3.z= -1.0f; p2.x= -0.5f; p2.y= -0.5f; p2.z= 0.0f; p1.x= 0.5f; p1.y= -0.5f; p1.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); //glColor4f(0.0f,1.0f,0.0f,1.0f); glVertex3f(0.0f, 0.0f, -1.0f); glVertex3f(-0.5f, -0.5f, 0.0f); glVertex3f(0.5f, -0.5f, 0.0f); // Calc the top face normal p1.x= 0.0f; p1.y= 0.0f; p1.z= -1.0f; p2.x= -0.5f; p2.y= 0.5f; p2.z= 0.0f; p3.x= 0.5f; p3.y= 0.5f; p3.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); //glColor4f(1.0f,0.0f,0.0f,1.0f); glVertex3f(0.0f, 0.0f, -1.0f); glVertex3f(-0.5f, 0.5f, 0.0f); glVertex3f(0.5f, 0.5f, 0.0f); glEnd(); glBegin(GL_QUADS); // Calc the top face normal p1.x= 0.25f; p1.y= 0.25f; p1.z= 0.5f; p2.x= -0.25f; p2.y= 0.25f; p2.z= 0.5f; p3.x= -0.25f; p3.y= -0.25f; p3.z= 0.5f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); glVertex3f(0.25f, 0.25f ,0.5f); glVertex3f(-0.25f, 0.25f ,0.5f); glVertex3f(-0.25f, -0.25f ,0.5f); glVertex3f(0.25f, -0.25f ,0.5f); // Calc the top face normal p3.x= 0.25f; p3.y= -0.25f; p3.z= 0.5f; p2.x= 0.25f; p2.y= 0.25f; p2.z= 0.5f; p1.x= 0.50f; p1.y= 0.50f; p1.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); glVertex3f(0.25f, -0.25f ,0.5f); glVertex3f(0.25f, 0.25f ,0.5f); glVertex3f(0.50f, 0.50f ,0.0f); glVertex3f(0.50f, -0.50f ,0.0f); // Calc the top face normal p3.x= -0.25f; p3.y= -0.25f; p3.z= 0.5f; p2.x= 0.25f; p2.y= -0.25f; p2.z= 0.5f; p1.x= 0.50f; p1.y= -0.50f; p1.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); glVertex3f(-0.25f, -0.25f ,0.5f); glVertex3f(0.25f, -0.25f ,0.5f); glVertex3f(0.50f, -0.50f ,0.0f); glVertex3f(-0.50f, -0.50f ,0.0f); // Calc the top face normal p1.x= -0.25f; p1.y= -0.25f; p1.z= 0.5f; p2.x= -0.25f; p2.y= 0.25f; p2.z= 0.5f; p3.x= -0.50f; p3.y= 0.50f; p3.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); glVertex3f(-0.25f, -0.25f ,0.5f); glVertex3f(-0.25f, 0.25f ,0.5f); glVertex3f(-0.50f, 0.50f ,0.0f); glVertex3f(-0.50f, -0.50f ,0.0f); // Calc the top face normal p1.x= -0.25f; p1.y= 0.25f; p1.z= 0.5f; p2.x= 0.25f; p2.y= 0.25f; p2.z= 0.5f; p3.x= 0.50f; p3.y= 0.50f; p3.z= 0.0f; Norm=CalcNormal(p1,p2,p3); glNormal3f(Norm.x,Norm.y,Norm.z); glVertex3f(-0.25f, 0.25f ,0.5f); glVertex3f(0.25f, 0.25f ,0.5f); glVertex3f(0.50f, 0.50f ,0.0f); glVertex3f(-0.50f, 0.50f ,0.0f); glEnd(); xrot+=0.01f; yrot+=0.01f; zrot+=0.01f; glutSwapBuffers(); }
bool LoadObjAndConvert(float bmin[3], float bmax[3], std::vector<DrawObject>* drawObjects, std::vector<tinyobj::material_t>& materials, std::map<std::string, GLuint>& textures, const char* filename) { tinyobj::attrib_t attrib; std::vector<tinyobj::shape_t> shapes; timerutil tm; tm.start(); std::string err; bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, NULL); if (!err.empty()) { std::cerr << err << std::endl; } tm.end(); if (!ret) { std::cerr << "Failed to load " << filename << std::endl; return false; } printf("Parsing time: %d [ms]\n", (int)tm.msec()); printf("# of vertices = %d\n", (int)(attrib.vertices.size()) / 3); printf("# of normals = %d\n", (int)(attrib.normals.size()) / 3); printf("# of texcoords = %d\n", (int)(attrib.texcoords.size()) / 2); printf("# of materials = %d\n", (int)materials.size()); printf("# of shapes = %d\n", (int)shapes.size()); // Append `default` material materials.push_back(tinyobj::material_t()); // Load diffuse textures { for (size_t m = 0; m < materials.size(); m++) { tinyobj::material_t* mp = &materials[m]; if (mp->diffuse_texname.length() > 0) { // Only load the texture if it is not already loaded if (textures.find(mp->diffuse_texname) == textures.end()) { GLuint texture_id; int w, h; int comp; unsigned char* image = stbi_load(mp->diffuse_texname.c_str(), &w, &h, &comp, STBI_default); if (image == nullptr) { std::cerr << "Unable to load texture: " << mp->diffuse_texname << std::endl; exit(1); } glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (comp == 3) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image); } else if (comp == 4) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); } glBindTexture(GL_TEXTURE_2D, 0); stbi_image_free(image); textures.insert(std::make_pair(mp->diffuse_texname, texture_id)); } } } } bmin[0] = bmin[1] = bmin[2] = std::numeric_limits<float>::max(); bmax[0] = bmax[1] = bmax[2] = -std::numeric_limits<float>::max(); { for (size_t s = 0; s < shapes.size(); s++) { DrawObject o; std::vector<float> vb; // pos(3float), normal(3float), color(3float) for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) { tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0]; tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1]; tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2]; int current_material_id = shapes[s].mesh.material_ids[f]; if ((current_material_id < 0) || (current_material_id >= static_cast<int>(materials.size()))) { // Invaid material ID. Use default material. current_material_id = materials.size() - 1; // Default material is added to the last item in `materials`. } //if (current_material_id >= materials.size()) { // std::cerr << "Invalid material index: " << current_material_id << std::endl; //} // float diffuse[3]; for (size_t i = 0; i < 3; i++) { diffuse[i] = materials[current_material_id].diffuse[i]; } float tc[3][2]; if (attrib.texcoords.size() > 0) { assert(attrib.texcoords.size() > 2 * idx0.texcoord_index + 1); assert(attrib.texcoords.size() > 2 * idx1.texcoord_index + 1); assert(attrib.texcoords.size() > 2 * idx2.texcoord_index + 1); tc[0][0] = attrib.texcoords[2 * idx0.texcoord_index]; tc[0][1] = 1.0f - attrib.texcoords[2 * idx0.texcoord_index + 1]; tc[1][0] = attrib.texcoords[2 * idx1.texcoord_index]; tc[1][1] = 1.0f - attrib.texcoords[2 * idx1.texcoord_index + 1]; tc[2][0] = attrib.texcoords[2 * idx2.texcoord_index]; tc[2][1] = 1.0f - attrib.texcoords[2 * idx2.texcoord_index + 1]; } else { std::cerr << "Texcoordinates are not defined" << std::endl; exit(2); } float v[3][3]; for (int k = 0; k < 3; k++) { int f0 = idx0.vertex_index; int f1 = idx1.vertex_index; int f2 = idx2.vertex_index; assert(f0 >= 0); assert(f1 >= 0); assert(f2 >= 0); v[0][k] = attrib.vertices[3 * f0 + k]; v[1][k] = attrib.vertices[3 * f1 + k]; v[2][k] = attrib.vertices[3 * f2 + k]; bmin[k] = std::min(v[0][k], bmin[k]); bmin[k] = std::min(v[1][k], bmin[k]); bmin[k] = std::min(v[2][k], bmin[k]); bmax[k] = std::max(v[0][k], bmax[k]); bmax[k] = std::max(v[1][k], bmax[k]); bmax[k] = std::max(v[2][k], bmax[k]); } float n[3][3]; if (attrib.normals.size() > 0) { int f0 = idx0.normal_index; int f1 = idx1.normal_index; int f2 = idx2.normal_index; assert(f0 >= 0); assert(f1 >= 0); assert(f2 >= 0); for (int k = 0; k < 3; k++) { n[0][k] = attrib.normals[3 * f0 + k]; n[1][k] = attrib.normals[3 * f1 + k]; n[2][k] = attrib.normals[3 * f2 + k]; } } else { // compute geometric normal CalcNormal(n[0], v[0], v[1], v[2]); n[1][0] = n[0][0]; n[1][1] = n[0][1]; n[1][2] = n[0][2]; n[2][0] = n[0][0]; n[2][1] = n[0][1]; n[2][2] = n[0][2]; } for (int k = 0; k < 3; k++) { vb.push_back(v[k][0]); vb.push_back(v[k][1]); vb.push_back(v[k][2]); vb.push_back(n[k][0]); vb.push_back(n[k][1]); vb.push_back(n[k][2]); // Combine normal and diffuse to get color. float normal_factor = 0.2; float diffuse_factor = 1 - normal_factor; float c[3] = { n[k][0] * normal_factor + diffuse[0] * diffuse_factor, n[k][1] * normal_factor + diffuse[1] * diffuse_factor, n[k][2] * normal_factor + diffuse[2] * diffuse_factor }; float len2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]; if (len2 > 0.0f) { float len = sqrtf(len2); c[0] /= len; c[1] /= len; c[2] /= len; } vb.push_back(c[0] * 0.5 + 0.5); vb.push_back(c[1] * 0.5 + 0.5); vb.push_back(c[2] * 0.5 + 0.5); vb.push_back(tc[k][0]); vb.push_back(tc[k][1]); } } o.vb = 0; o.numTriangles = 0; // OpenGL viewer does not support texturing with per-face material. if (shapes[s].mesh.material_ids.size() > 0 && shapes[s].mesh.material_ids.size() > s) { // Base case o.material_id = shapes[s].mesh.material_ids[s]; } else { o.material_id = materials.size() - 1; // = ID for default material. } if (vb.size() > 0) { glGenBuffers(1, &o.vb); glBindBuffer(GL_ARRAY_BUFFER, o.vb); glBufferData(GL_ARRAY_BUFFER, vb.size() * sizeof(float), &vb.at(0), GL_STATIC_DRAW); o.numTriangles = vb.size() / (3 + 3 + 3 + 2) * 3; printf("shape[%d] # of triangles = %d\n", static_cast<int>(s), o.numTriangles); } drawObjects->push_back(o); } } printf("bmin = %f, %f, %f\n", bmin[0], bmin[1], bmin[2]); printf("bmax = %f, %f, %f\n", bmax[0], bmax[1], bmax[2]); return true; }
//================================================================================================= void Terrain::SmoothNormals(VTerrain* v) { assert(state > 0); assert(v); Vec3 normal, normal2; uint sum; // 1,3 4 //(0,1) (1,1) // O-----------O // |\ | // | \ | // | \ | // | \ | // | \ | // | \| // O-----------O //(0,0) (1,0) // 0 2,5 #undef W #define W(xx,zz,idx) v[(x+(xx)+(z+(zz))*n_tiles)*6+(idx)] #define CalcNormal(xx,zz,i0,i1,i2) CalculateNormal(normal2,W(xx,zz,i0).pos,W(xx,zz,i1).pos,W(xx,zz,i2).pos);\ normal += normal2 // wyg³adŸ normalne for(uint z = 0; z < n_tiles; ++z) { for(uint x = 0; x < n_tiles; ++x) { bool has_left = (x > 0), has_right = (x < n_tiles - 1), has_bottom = (z > 0), has_top = (z < n_tiles - 1); //------------------------------------------ // PUNKT (0,0) sum = 1; normal = W(0, 0, 0).normal; if(has_left) { CalcNormal(-1, 0, 0, 1, 2); CalcNormal(-1, 0, 3, 4, 5); sum += 2; if(has_bottom) { CalcNormal(-1, -1, 3, 4, 5); ++sum; } } if(has_bottom) { CalcNormal(0, -1, 0, 1, 2); CalcNormal(0, -1, 3, 4, 5); sum += 2; } normal *= (1.f / sum); W(0, 0, 0).normal = normal; //------------------------------------------ // PUNKT (0,1) normal = W(0, 0, 1).normal; normal += W(0, 0, 3).normal; sum = 2; if(has_left) { CalcNormal(-1, 0, 3, 4, 5); ++sum; if(has_top) { CalcNormal(-1, 1, 0, 1, 2); CalcNormal(-1, 1, 3, 4, 5); sum += 2; } } if(has_top) { CalcNormal(0, 1, 0, 1, 2); ++sum; } normal *= (1.f / sum); W(0, 0, 1).normal = normal; W(0, 0, 3).normal = normal; //------------------------------------------ // PUNKT (1,0) normal = W(0, 0, 2).normal; normal += W(0, 0, 5).normal; sum = 2; if(has_right) { CalcNormal(1, 0, 0, 1, 2); ++sum; if(has_bottom) { CalcNormal(1, -1, 0, 1, 2); CalcNormal(1, -1, 3, 4, 5); sum += 2; } } if(has_bottom) { CalcNormal(0, -1, 3, 4, 5); ++sum; } normal *= (1.f / sum); W(0, 0, 2).normal = normal; W(0, 0, 5).normal = normal; //------------------------------------------ // PUNKT (1,1) normal = W(0, 0, 4).normal; sum = 1; if(has_right) { CalcNormal(1, 0, 0, 1, 2); CalcNormal(1, 0, 3, 4, 5); sum += 2; if(has_top) { CalcNormal(1, 1, 0, 1, 2); ++sum; } } if(has_top) { CalcNormal(0, 1, 0, 1, 2); CalcNormal(0, 1, 3, 4, 5); sum += 2; } normal *= (1.f / sum); W(0, 0, 4).normal = normal; } } }
void BuildGeometry (unsigned int surface, unsigned int colorScheme, unsigned int subdivisions, unsigned int xyRatio, GLuint * polyList, GLuint * lineList, GLuint * pointList) { long i,j, index; long maxI = subdivisions * xyRatio, maxJ = subdivisions; double u, v, delta=0.001; recVec p1,p2; recVec *vertexPos = NULL,*vertexNormal = NULL; recColor *vertexColor = NULL; recTexCoord *vertexTexCoord = NULL; // set valid surface and color scheme surface %= kSurfaces; colorScheme %= kColorSchemes; // delete existing list if (*polyList) glDeleteLists (*polyList, 1); if (*lineList) glDeleteLists (*lineList, 1); if (*pointList) glDeleteLists (*pointList, 1); *polyList = *lineList = *pointList = 0; if (surface == kCube) // build the standard color cube (disregard color, subdivisions, and xyRatio) BuildCube (polyList, lineList, pointList, colorScheme); else { // build buffers vertexPos = (recVec*) malloc ((maxI) * (maxJ) * sizeof (recVec)); if (vertexNormal) free (vertexNormal); vertexNormal = (recVec*) malloc ((maxI) * (maxJ) * sizeof (recVec)); if (vertexColor) free (vertexColor); vertexColor = (recColor*) malloc ((maxI) * (maxJ) * sizeof (recColor)); if (vertexTexCoord) free (vertexTexCoord); vertexTexCoord = (recTexCoord*) malloc ((maxI) * (maxJ) * sizeof (recTexCoord)); if (!vertexPos || !vertexNormal || !vertexColor || !vertexTexCoord) return; // build surface for (i = 0; i < maxI; i++) { for (j = 0; j < maxJ; j++) { index = i * maxJ + j; u = -PI + (i % maxI) * TWOPI / maxI; v = -PI + (j % maxJ) * TWOPI / maxJ; vertexPos[index] = Eval(u,v, surface); p1 = Eval(u + delta, v, surface); p2 = Eval(u, v + delta, surface); vertexNormal[index] = CalcNormal(vertexPos[index],p1,p2); vertexColor[index] = getColor(u, -PI, PI, colorScheme); vertexTexCoord[index].s = (float) i * 5.0f / (float) maxI; vertexTexCoord[index].t = (float) j * 1.0f/ (float) maxJ; } } *polyList = glGenLists (1); glNewList(*polyList, GL_COMPILE); for (i=0; i< maxI; i++) { glBegin(GL_TRIANGLE_STRIP); for (j = 0; j <= maxJ; j++) { index = (i % maxI) * maxJ + (j % maxJ); glColor3fv (&vertexColor[index].r); glNormal3fv (&vertexNormal[index].x); glTexCoord2fv (&vertexTexCoord[index].s); glVertex3fv (&vertexPos[index].x); index = ((i + 1) % maxI) * maxJ + (j % maxJ); glColor3fv (&vertexColor[index].r); glNormal3fv (&vertexNormal[index].x); glTexCoord2fv (&vertexTexCoord[index].s); glVertex3fv (&vertexPos[index].x); // index = ((i - 1) % maxI) * maxJ + (j % maxJ); } glEnd (); } glEndList (); *lineList = glGenLists (1); glNewList(*lineList, GL_COMPILE); for (i=0; i< maxI; i++) { glBegin(GL_LINE_STRIP); for (j = 0; j < maxJ; j++) { index = i * maxJ + j; glColor3fv (&vertexColor[index].r); glVertex3fv (&vertexPos[index].x); } index = i * maxJ + 0; glColor3fv (&vertexColor[index].r); glVertex3fv (&vertexPos[index].x); glEnd (); } for (j=0; j< maxJ; j++) { glBegin(GL_LINE_STRIP); for (i = 0; i < maxI; i++) { index = i * maxJ + j; glColor3fv (&vertexColor[index].r); glVertex3fv (&vertexPos[index].x); } index = 0 + j; glColor3fv (&vertexColor[index].r); glVertex3fv (&vertexPos[index].x); glEnd (); } glEndList (); *pointList = glGenLists (1); glNewList(*pointList, GL_COMPILE); glBegin(GL_POINTS); for (i=0; i< maxI; i++) { for (j = 0; j < maxJ; j++) { index = i * maxJ + j; glColor3fv (&vertexColor[index].r); glVertex3fv (&vertexPos[index].x); } } glEnd (); glEndList (); free (vertexPos); free (vertexNormal); free (vertexColor); } }
inline void COMap::CallResponse(long id[], long nType[], CrestObjects *pObjects) { int nCollisionType=-1; vertex velocity[2]; tCRNode* pCRNodes, *pCRNodes1; CrestInstrumentInfo *pIInfo;//tInstrumentLink* pInstrument1; ResponseData *pResponse; long nWhichI, nWhichR, nWhichT, nWhichN, nWhichS; bool bMedial; vertex loc; long i; //vertex adjust0, adjust1, loc; // vertex v[3][2]; // float dx[3][3]; CalcNormal(m_tp[0].pos, m_tp[0].pos+1, m_tp[0].pos+2, &(m_tp[0].n)); CalcNormal(m_tp[1].pos, m_tp[1].pos+1, m_tp[1].pos+2, &(m_tp[1].n)); // Instrument involved if(nType[0] == INSTRUMENT_TYPE || nType[1] == INSTRUMENT_TYPE) { if(nType[0] == INSTRUMENT_TYPE && nType[1] == INSTRUMENT_TYPE) { nCollisionType=I2I; } else if(nType[0] == INSTRUMENT_TYPE && nType[1] == TISSUE_TYPE) { nWhichI=0; nWhichT=1; nCollisionType=I2T; } else if(nType[0] == TISSUE_TYPE && nType[1] == INSTRUMENT_TYPE) { nWhichI=1; nWhichT=0; nCollisionType=I2T; } }// Tissue to tissue else if(nType[0] == TISSUE_TYPE && nType[1] == TISSUE_TYPE) { nCollisionType=T2T; } switch(nCollisionType) { case I2T: { if(INSTRUMENT_TYPE != pObjects->GetObjectInfo(id[nWhichI])->nObjectType) return; else pIInfo = &(pObjects->GetObjectInfo(id[nWhichI])->IInfo); if(TISSUE_TYPE != pObjects->GetObjectInfo(id[nWhichT])->nObjectType) return; else pResponse = &(pObjects->GetObjectInfo(id[nWhichT])->Response); //if( NULL == (pIInfo = pObjects->GetObjectInfo(id[nWhichI])->pIInfo) ) return; //if( NULL == (pResponse = pObjects->GetObjectInfo(id[nWhichT])->pResponse) ) return; //pInstrument1->geoModel.GetDisplacement(m_tp[nWhichI].id[0], m_tp[nWhichI].v); //pInstrument1->geoModel.GetDisplacement(m_tp[nWhichI].id[1], m_tp[nWhichI].v+1); //pInstrument1->geoModel.GetDisplacement(m_tp[nWhichI].id[2], m_tp[nWhichI].v+2); // //m_tp[nWhichI].v[0]=pInstrument1->velocity; // //m_tp[nWhichI].v[1]=pInstrument1->velocity; // //m_tp[nWhichI].v[2]=pInstrument1->velocity; //m_tp[nWhichT].v[0]=(pD[nWhichT]->m_CurrentSys)[m_tp[nWhichT].id[0]].v; //m_tp[nWhichT].v[1]=(pD[nWhichT]->m_CurrentSys)[m_tp[nWhichT].id[1]].v; //m_tp[nWhichT].v[2]=(pD[nWhichT]->m_CurrentSys)[m_tp[nWhichT].id[2]].v; bMedial = pIInfo->IsMedial(m_tp[nWhichI].id[0]); bMedial |= pIInfo->IsMedial(m_tp[nWhichI].id[1]); bMedial |= pIInfo->IsMedial(m_tp[nWhichI].id[2]); if(bMedial && pIInfo->GetStatus()==1) { long &nCount=pResponse->nCPos[id[nWhichI]]; pCRNodes=pResponse->CPos[id[nWhichI]]; for(i=0;i<3;i++) { if( nCount< CNODES_MAX && pResponse->IsNewCRNode(m_tp[nWhichT].id[i], FALSE)) { //VectorDifference(m_tp[nWhichT].pos+i, m_tp[nWhichI].pos+i, &(pCRNodes[nCount].vector)); pCRNodes[nCount].vector=*(m_tp[nWhichI].pos+i); pCRNodes[nCount].id=m_tp[nWhichT].id[i]; pCRNodes[nCount].id_instrument=id[nWhichI]; pCRNodes[nCount++].id_iNode=m_tp[nWhichI].id[i]; } } } else{ long &nCount=pResponse->nRVelocity; pCRNodes=pResponse->RVelocity; long &nCount1=pResponse->nPPos[id[nWhichI]]; pCRNodes1=pResponse->PPos[id[nWhichI]]; float fLength; vertex vn, vt, v; for(i=0;i<3;i++) { if(nCount1 < RNODES_MAX && pResponse->IsNewCRNode(m_tp[nWhichT].id[i], pCRNodes1, nCount1)) { pCRNodes1[nCount1].id_instrument=id[nWhichI]; //pCRNodes1[nCount1].id_iNode=m_tp[nWhichI].id[i]; //pCRNodes1[nCount1].vector=m_tp[nWhichI].pos[i]; pCRNodes1[nCount1++].id=m_tp[nWhichT].id[i]; } } } //CColliResp::CollisionResponse(I2T, nWhichI, nWhichR, nWhichT); break; } //case T2T: //{ // if(!CR_TT) break; // float fLength; // vertex vn, vt, v, vs; // vertex* pvs; // nWhichN=0; // nWhichS=1; // // long &nCount0=pD[nWhichN]->m_response_b.nRVelocity; // pCRNodes=pD[nWhichN]->m_response_b.RVelocity; // pvs=m_tp[nWhichS].v; // vs=*(pvs); // VectorSum(&vs,pvs+1,&vs); // VectorSum(&vs,pvs+2,&vs); // ScaleVector(&vs,1.0/3.0f,&vs); // // for(i=0;i<3;i++) // { // if(nCount0 < RNODES_MAX && IsNewCRNode(m_tp[nWhichN].id[i], TRUE, pD[nWhichN])) // { // v=m_tp[nWhichN].v[i]; // vn=m_tp[nWhichS].n; // VectorDifference(&v, &vs, &loc); // fLength=DotProduct(&loc, &vn); // if(0.0f<=fLength) continue; // ScaleVector(&vn, fLength, &vn); // VectorDifference(&v, &vn, &vt); // ScaleVector(&vn, 0.1f, &vn); // VectorDifference(&vt, &vn, &loc); //VectorDifference(&loc, &v, &loc); // //ScaleVector(&vt, 0.6f, &loc); // ScaleVector(&loc, 0.1f, &loc); //0.1f // pCRNodes[nCount0].vector=loc; //VectorSum(&(pCRNodes[nCount].vector),&loc,&(pCRNodes[nCount].vector)); // pCRNodes[nCount0++].id=m_tp[nWhichN].id[i]; // } // } // nWhichN=1; // nWhichS=0; // // long &nCount1=pD[nWhichN]->m_response_b.nRVelocity; // pCRNodes=pD[nWhichN]->m_response_b.RVelocity; // pvs=m_tp[nWhichS].v; // vs=*(pvs); // VectorSum(&vs,pvs+1,&vs); // VectorSum(&vs,pvs+2,&vs); // ScaleVector(&vs,1.0/3.0f,&vs); // // for(i=0;i<3;i++) // { // if(nCount1 < RNODES_MAX && IsNewCRNode(m_tp[nWhichN].id[i], TRUE, pD[nWhichN])) // { // v=m_tp[nWhichN].v[i]; // vn=m_tp[nWhichS].n; // VectorDifference(&v, &vs, &loc); // fLength=DotProduct(&loc, &vn); // if(0.0f<=fLength) continue; // ScaleVector(&vn, fLength, &vn); // VectorDifference(&v, &vn, &vt); // ScaleVector(&vn, 0.5f, &vn); // VectorDifference(&vt, &vn, &loc); //VectorDifference(&loc, &v, &loc); // //ScaleVector(&vt, 0.6f, &loc); // ScaleVector(&loc, 0.1f, &loc); //0.1f // pCRNodes[nCount1].vector=loc; //VectorSum(&(pCRNodes[nCount].vector),&loc,&(pCRNodes[nCount].vector)); // pCRNodes[nCount1++].id=m_tp[nWhichN].id[i]; // } // } // break; //} } }
bool HypercomplexFractalRules::Iterate(const Vector3d& IPoint, const Fractal *HCompl, const Vector3d& Direction, DBL *Dist, DBL **IterStack) const { int i; DBL yz, xw; DBL Exit_Value, F_Value, Step; DBL x, y, z, w; Vector3d H_Normal; x = IterStack[X][0] = IPoint[X]; y = IterStack[Y][0] = IPoint[Y]; z = IterStack[Z][0] = IPoint[Z]; w = IterStack[W][0] = (HCompl->SliceDist - HCompl->Slice[X]*x - HCompl->Slice[Y]*y - HCompl->Slice[Z]*z)/HCompl->Slice[T]; Exit_Value = HCompl->Exit_Value; for (i = 1; i <= HCompl->Num_Iterations; ++i) { yz = y * y + z * z; xw = x * x + w * w; if ((F_Value = xw + yz) > Exit_Value) { CalcNormal(H_Normal, i - 1, HCompl, IterStack); Step = dot(H_Normal, Direction); if (Step < -Fractal_Tolerance) { Step = -2.0 * Step; if ((F_Value > HCompl->Precision * Step) && (F_Value < 30 * HCompl->Precision * Step)) { *Dist = F_Value / Step; return (false); } } *Dist = HCompl->Precision; return (false); } IterStack[X][i] = xw - yz + HCompl->Julia_Parm[X]; IterStack[Y][i] = 2.0 * (x * y - z * w) + HCompl->Julia_Parm[Y]; IterStack[Z][i] = 2.0 * (x * z - w * y) + HCompl->Julia_Parm[Z]; IterStack[W][i] = 2.0 * (x * w + y * z) + HCompl->Julia_Parm[T]; w = IterStack[W][i]; x = IterStack[X][i]; z = IterStack[Z][i]; y = IterStack[Y][i]; } *Dist = HCompl->Precision; return (true); }
void ATriangle::Init() { type = OBJ_TRIANGLE; CalcNormal(); CalcCentroid(); }
static void check_collision ( collision_data& coldat ) { float radius; if ( coldat.BoundingSphere.x == coldat.BoundingSphere.y && coldat.BoundingSphere.x == coldat.BoundingSphere.z ) { radius = coldat.BoundingSphere.x; } else { radius = 1.0f; // scale polygon for ( small x = 0; x < cache.count; x++ ) { cache.vertex [ x ].x /= coldat.BoundingSphere.x; cache.vertex [ x ].y /= coldat.BoundingSphere.y; cache.vertex [ x ].z /= coldat.BoundingSphere.z; } CalcNormal ( cache.vertex, &cache.normal ); D3DXVec3Normalize ( &cache.normal, &cache.normal ); } D3DXVECTOR3 r; D3DXVECTOR3 pt = cache.vertex [ 0 ]; D3DXVECTOR3 n = cache.normal; D3DXVECTOR3 s = coldat.src - n * radius; float t = D3DXVec3Dot ( &( s - pt ), &n ); if ( t > coldat.dir_len ) { return; } if ( t < -2 * radius ) { return; } if ( t < 0.0f ) { if ( !intersect_plane ( s, n * radius, pt, r ) ) return; } else { if ( !intersect_plane ( s, coldat.dir, pt, r ) ) return; } if ( !point_in_poly ( r ) ) { D3DXVECTOR3 line_dir; r = closest_on_poly ( r, &line_dir ); // mj change - sticky collision fix 27/08/02 D3DXVECTOR3 ndir; //D3DXVec3Cross ( &ndir, &coldat.ndir, &line_dir ); //D3DXVec3Cross ( &ndir, &line_dir, &ndir ); //D3DXVec3Normalize ( &ndir, &ndir ); ndir = coldat.ndir; t = intersect_sphere ( r, -ndir, coldat.src, radius ); } else { t = intersect_sphere ( r, -coldat.ndir, coldat.src, radius ); } if ( t >= 0.0f && t <= coldat.dir_len ) { if ( !coldat.found || t < coldat.dist ) { coldat.found = true; coldat.dist = t; coldat.nearest_poly = r; } } }
int32 FPoly::Finalize( ABrush* InOwner, int32 NoError ) { // Check for problems. Fix(); if( Vertices.Num()<3 ) { // Since we don't have enough vertices, remove this polygon from the brush check( InOwner ); for( int32 p = 0 ; p < InOwner->Brush->Polys->Element.Num() ; ++p ) { if( InOwner->Brush->Polys->Element[p] == *this ) { InOwner->Brush->Polys->Element.RemoveAt(p); break; } } // UE_LOG(LogPolygon, Warning, TEXT("FPoly::Finalize: Not enough vertices (%i)"), Vertices.Num() ); if( NoError ) return -1; else { // UE_LOG(LogPolygon, Log, TEXT("FPoly::Finalize: Not enough vertices (%i) : polygon removed from brush"), Vertices.Num() ); return -2; } } // If no normal, compute from cross-product and normalize it. if( Normal.IsZero() && Vertices.Num()>=3 ) { if( CalcNormal() ) { // UE_LOG(LogPolygon, Warning, TEXT("FPoly::Finalize: Normalization failed, verts=%i, size=%f"), Vertices.Num(), Normal.Size() ); if( NoError ) { return -1; } else { UE_LOG(LogPolygon, Error, TEXT("FPoly::Finalize: Normalization failed, verts=%d, size=%d"), Vertices.Num(), Normal.Size()); for (int32 VertIdx = 0; VertIdx < Vertices.Num(); ++VertIdx) { UE_LOG(LogPolygon, Error, TEXT("Vertex %d: <%.6f, %.6f, %.6f>"), VertIdx, Vertices[VertIdx].X, Vertices[VertIdx].Y, Vertices[VertIdx].Z); } ensure(false); } } } // If texture U and V coordinates weren't specified, generate them. if( TextureU.IsZero() && TextureV.IsZero() ) { for( int32 i=1; i<Vertices.Num(); i++ ) { TextureU = ((Vertices[0] - Vertices[i]) ^ Normal).GetSafeNormal(); TextureV = (Normal ^ TextureU).GetSafeNormal(); if( TextureU.SizeSquared()!=0 && TextureV.SizeSquared()!=0 ) break; } } return 0; }