float *Dataslc::compLength(int &len, float **funx) { float *val = (float *)malloc(sizeof(float)*FSAMPLES); float *fx = (float *)malloc(sizeof(float)*FSAMPLES); int c; u_int *v; len = FSAMPLES; memset(val, 0, sizeof(float)*len); *funx = fx; for (c=0; c<len; c++) fx[c] = getMin() + (c/(len-1.0)) * (getMax()-getMin()); for (c=0; c<getNCells(); c++) { v = getCellVerts(c); triSurfIntegral(getVert(v[0]), getVert(v[1]), getVert(v[2]), getValue(v[0]), getValue(v[1]), getValue(v[2]), fx, val, len, getMin(), getMax(), 1.0); } return(val); }
float *Dataslc::compGradient(int &len, float **funx) { float *val = (float *)malloc(sizeof(float)*FSAMPLES); float *fx = (float *)malloc(sizeof(float)*FSAMPLES); int c; u_int *v; float cellgrad[3], scaling; // u_int cv[3]; len = FSAMPLES; memset(val, 0, sizeof(float)*len); *funx = fx; for (c=0; c<len; c++) fx[c] = getMin() + (c/(len-1.0)) * (getMax()-getMin()); for (c=0; c<getNCells(); c++) { v = getCellVerts(c); getCellGrad3(c, cellgrad); scaling = sqrt(cellgrad[0]*cellgrad[0] + cellgrad[1]*cellgrad[1]) / (cellgrad[2]); // scaling = (cellgrad[0]*cellgrad[0] + cellgrad[1]*cellgrad[1]) / sqr(cellgrad[2]); // cv[0] = v[0]; cv[1]=v[1]; cv[2]=v[2]; triSurfIntegral(getVert(v[0]), getVert(v[1]), getVert(v[2]), getValue(v[0]), getValue(v[1]), getValue(v[2]), fx, val, len, getMin(), getMax(), fabs(scaling)); } return(val); }
// Make object bigger or smaller void Geometry::scale(const Point ¢er, F32 scale) { S32 count = getVertCount(); for(S32 j = 0; j < count; j++) setVert((getVert(j) - center) * scale + center, j); }
void Geometry::offset(const Point &offset) { S32 count = getVertCount(); for(S32 i = 0; i < count; i++) setVert(getVert(i) + offset, i); }
std::vector<float> PlaneGenerator::genNormals(int width, int height) const { std::vector<glm::vec3> averaged(vertices_.size() / 3); glm::vec3 vert[3]; unsigned ind[3]; auto it = ++indices_.begin(); for(int i = 0; i < 3; ++i) { ind[i] = *it++; vert[i] = getVert(ind[i]); } for(; it != indices_.end();) { glm::vec3 normal = glm::cross(vert[0] - vert[1], vert[0] - vert[2]); normal = glm::normalize(normal); for(int i = 0; i < 3; ++i) { averaged[ind[i]] += normal; } vert[0] = vert[1]; vert[1] = vert[2]; ind[0] = ind[1]; ind[1] = ind[2]; if(ind[2] % height == (height - 1) && ind[2] > height && *it < (width * height - 1)) { ++(++(++it)); } ind[2] = *it++; vert[2] = getVert(ind[2]); } std::vector<float> normals; normals.reserve(vertices_.size()); for(auto& avg : averaged) { avg = glm::normalize(avg); normals.push_back(avg.x); normals.push_back(avg.y); normals.push_back(avg.z); } return normals; }
SDL_Texture* TileManager::get(int id0, int id1, int id2, int id3, SDL_Renderer *renderer) { if (id0 == TILE_MAX && id2 == TILE_MAX) { return getVert(id3, id1, renderer); } else if (id1 == TILE_MAX && id3 == TILE_MAX) { return getHori(id0, id2, renderer); } else { return getAll(id0, id1, id2, id3, renderer); } }
// Could probably be more clever about this, but only used when merging polygons in the editor, so speed not critical void Geometry::reverseWinding() { S32 count = getVertCount(); Vector<Point> temp(count); for(S32 i = 0; i < count; i++) temp.push_back(getVert(i)); for(S32 i = 0; i < count; i++) setVert(temp[i], count - i - 1); }
void Geometry::rotateAboutPoint(const Point ¢er, F32 angle) { F32 sinTheta = sin(angle * Float2Pi / 360.0f); F32 cosTheta = cos(angle * Float2Pi / 360.0f); for(S32 j = 0; j < getVertCount(); j++) { Point v = getVert(j) - center; Point n(v.x * cosTheta + v.y * sinTheta, v.y * cosTheta - v.x * sinTheta); setVert(n + center, j); } }
float *Dataslc::compArea(int &len, float **funx) { float *val = (float *)malloc(sizeof(float)*FSAMPLES); float *cum = (float *)malloc(sizeof(float)*FSAMPLES); float *fx = (float *)malloc(sizeof(float)*FSAMPLES); int c; u_int *v; float sum; int b; len = FSAMPLES; memset(val, 0, sizeof(float)*len); memset(cum, 0, sizeof(float)*len); *funx = fx; for (c=0; c<len; c++) fx[c] = getMin() + (c/(len-1.0)) * (getMax()-getMin()); for (c=0; c<getNCells(); c++) { v = getCellVerts(c); triVolIntegral(getVert(v[0]), getVert(v[1]), getVert(v[2]), getValue(v[0]), getValue(v[1]), getValue(v[2]), fx, val, cum, len, getMin(), getMax(), 1.0); } // now we need to sum from the first to last sum = 0.0; for (b=0; b<len; b++) { val[b]+=sum; sum+=cum[b]; } free(cum); return(val); }
void Geometry::flip(F32 center, bool isHoriz) { S32 count = getVertCount(); for(S32 i = 0; i < count; i++) { Point p = getVert(i); if(isHoriz) p.x = center * 2 - p.x; else p.y = center * 2 - p.y; setVert(p, i); } }
static void loadBspGeometry(Bsp *bsp, void *faceData, int32_t faceSize, void *edgeData, int32_t edgeSize, void *ledgeData, int32_t ledgeSize){ bsp->numFaces = faceSize / sizeof(FaceDef); bsp->faces = malloc(sizeof(Face)*bsp->numFaces); FaceDef *faces = malloc(faceSize); memcpy(faces, faceData, faceSize); EdgeDef *edges = malloc(edgeSize); memcpy(edges, edgeData, edgeSize); int32_t *ledges = malloc(ledgeSize); memcpy(ledges, ledgeData, ledgeSize); for(int i=0; i < bsp->numFaces; i++){ // Read all verts from edge data into a vert data structure // that is more suitable for GL rendering Face *face = &bsp->faces[i]; face->numVerts = faces[i].edgeNum; face->verts = malloc(sizeof(Vert)*face->numVerts); TexInfoDef *texInfo = getTexInfo(bsp, faces[i].texinfoId); face->texture = getTexture(bsp, texInfo->texId); face->glId = 0; // If face is a trigger or clip skip loading it's verts // TODO make somekind of stack or vector to store faces so we don't bother // allocating useless memory if(strcmp("trigger", getTexName(face->texture)) == 0 || strcmp("clip", getTexName(face->texture)) == 0){ continue; } for(int edge=0; edge < faces[i].edgeNum; edge++){ int32_t edgeIndex = ledges[edge+faces[i].edgeId]; vec3Float verts[2]; // if edgeIndex is negative flip v0 and v1 if(edgeIndex < 0){ edgeIndex = -edgeIndex; verts[0] = getVert(bsp, edges[edgeIndex].vert1); verts[1] = getVert(bsp, edges[edgeIndex].vert0); } else { verts[0] = getVert(bsp, edges[edgeIndex].vert0); verts[1] = getVert(bsp, edges[edgeIndex].vert1); } face->verts[edge].normal = getPlane(bsp, faces[i].planeId)->normal; // Negate y and flip y & z so it's oriented properly face->verts[edge].position.x = verts[0].x; face->verts[edge].position.y = verts[0].z; face->verts[edge].position.z = -verts[0].y; // compute s and t coordinate for texture mapping face->verts[edge].texCoord.x = (vec3FDot(&verts[0], &texInfo->vecS) + texInfo->distS) / getTexWidth(face->texture); face->verts[edge].texCoord.y = (vec3FDot(&verts[0], &texInfo->vecT) + texInfo->distT) / getTexHeight(face->texture); } // Now that we have loaded all vertex data for this face // We can generate a vbo for it glGenBuffers(1, &face->glId); glBindBuffer(GL_ARRAY_BUFFER, face->glId); glBufferData(GL_ARRAY_BUFFER, sizeof(Vert)*face->numVerts, &face->verts[0], GL_STATIC_DRAW); } free(faces); free(edges); free(ledges); }
string PointGeometry::geomToLevelCode() const { Point pos = getVert(0); return pos.toLevelCode(); }
// Move object to location, specifying (optional) vertex to be positioned at pos void Geometry::moveTo(const Point &pos, S32 vertexIndexToBePositionedAtPos) { offset(pos - getVert(vertexIndexToBePositionedAtPos)); }
void TextureBackground::clear(DrawEnv *pEnv) { #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY) TextureBaseChunk *tex = getTexture(); if(tex == NULL) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); return; } glPushAttrib(GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT); glDisable(GL_LIGHTING); #if 1 // original mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #else // for testing the grid glColor3f(1.0f, 1.0f, 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glDepthMask(GL_FALSE); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, 0, 1); glColor4fv(getColor().getValuesRGBA()); tex->activate(pEnv); if(tex->isTransparent()) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } if(osgAbs(getRadialDistortion()) < TypeTraits<Real32>::getDefaultEps()) { if(getMFTexCoords()->size() < 4) { // set some default texture coordinates. glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 1.0f, 0.0f); glEnd(); } else { glBegin(GL_QUADS); { glTexCoord2f(getTexCoords(0).getValues()[0], getTexCoords(0).getValues()[1]); glVertex3f(0.0f, 0.0f, 0.0f); glTexCoord2f(getTexCoords(1).getValues()[0], getTexCoords(1).getValues()[1]); glVertex3f(1.0f, 0.0f, 0.0f); glTexCoord2f(getTexCoords(2).getValues()[0], getTexCoords(2).getValues()[1]); glVertex3f(1.0f, 1.0f, 0.0f); glTexCoord2f(getTexCoords(3).getValues()[0], getTexCoords(3).getValues()[1]); glVertex3f(0.0f, 1.0f, 0.0f); } glEnd(); } } else // map texture to distortion grid { updateGrid(); Int16 xxmax=getHor()+2,yymax=getVert()+2; UInt32 gridCoords=xxmax*yymax; UInt32 indexArraySize=xxmax*((getVert()+1)*2); if(_vertexCoordArray.size()==gridCoords && _textureCoordArray.size()==gridCoords && _indexArray.size()==indexArraySize) { // clear background, because possibly the distortion grid // could not cover th whole window glClearColor(.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); std::vector<UInt32>::iterator i; UInt32 yMax=getVert()+1; for(UInt32 y=0;y<yMax;y++) { glBegin(GL_TRIANGLE_STRIP); std::vector<UInt32>::iterator begin=_indexArray.begin()+(y*2*xxmax); std::vector<UInt32>::iterator end=begin+2*xxmax; for(std::vector<UInt32>::iterator i=begin;i!=end;i++) { glTexCoord2fv(_textureCoordArray[*i].getValues()); glVertex2fv(_vertexCoordArray[*i].getValues()); } glEnd(); } } } if(tex->isTransparent()) { glDisable(GL_BLEND); } tex->deactivate(pEnv); Int32 bit = getClearStencilBit(); if (bit >= 0) { glClearStencil(bit); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } else { glClear(GL_DEPTH_BUFFER_BIT); } glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); glColor3f(1.0f, 1.0f, 1.0f); #endif }
void TextureBackground::updateGrid(void) { bool gridChanged=( (getHor() != _hor) || (getVert() != _vert) ); if(gridChanged) { //resize grid UInt32 gridCoords=(getHor()+2)*(getVert()+2); _textureCoordArray.resize(gridCoords); _vertexCoordArray .resize(gridCoords); int indexArraySize=(getHor()+2)*((getVert()+1)*2); _indexArray.resize(indexArraySize); _hor = getHor(); _vert = getVert(); } if(gridChanged || _radialDistortion != getRadialDistortion() || _centerOfDistortion != getCenterOfDistortion() ) { _radialDistortion = getRadialDistortion(); _centerOfDistortion = getCenterOfDistortion(); // calculate grid coordinates and triangle strip indices float xStep=1.0/float(getHor()+1); float yStep=1.0/float(getVert()+1); std::vector<Vec2f>::iterator texCoord=_textureCoordArray.begin(); std::vector<Vec2f>::iterator vertexCoord=_vertexCoordArray.begin(); std::vector<UInt32>::iterator index=_indexArray.begin(); UInt32 coord0(0),coord1(0); GLfloat x,y; Int16 xx,yy; Int16 xxmax=getHor()+2,yymax=getVert()+2; for(yy=0,y=0.0f;yy<yymax;yy++,y+=yStep) { if(yy>0) { coord1=yy*xxmax; coord0=coord1-xxmax; *index++=coord1++; *index++=coord0++; } float dy=y-getCenterOfDistortion().y(); float dy2=dy*dy; for(xx=0,x=0.0f;xx<xxmax;xx++,x+=xStep) { *texCoord++=Vec2f(x,y); float dx=(x-getCenterOfDistortion().x()); float dx2=dx*dx; float dist2=dx2+dy2; float deltaX=dx*getRadialDistortion()*dist2; float deltaY=dy*getRadialDistortion()*dist2; *vertexCoord++=Vec2f(x+deltaX,y+deltaY); if(yy>0&&xx>0) { *index++=coord1++; *index++=coord0++; } } } } }
AppMeshLock MsAppMesh::lockMesh(const AppTime & time, const Matrix<4,4,F32> &objectOffset) { msMesh *mesh = mMsNode->getMsMesh(); assert(mesh && "NULL milkshape mesh"); S32 lastMatIdx = -1; // start lists empty mFaces.clear(); mVerts.clear(); mTVerts.clear(); mIndices.clear(); mSmooth.clear(); mVertId.clear(); // start out with faces and crop data allocated mFaces.resize(msMesh_GetTriangleCount(mesh)); S32 vCount = msMesh_GetVertexCount(mesh); // Transform the vertices by the bounds and scale std::vector<Point3D> verts(vCount, Point3D()); for (int i = 0; i < vCount; i++) verts[i] = objectOffset * (getVert(mesh, i) * mMsNode->getScale()); int numTriangles = mFaces.size(); for (int i = 0; i < numTriangles; i++) { msTriangle *msFace = msMesh_GetTriangleAt(mesh, i); Primitive &tsFace = mFaces[i]; // set faces material index S32 matIndex = msMesh_GetMaterialIndex(mesh); tsFace.type = (matIndex >= 0) ? matIndex : Primitive::NoMaterial; tsFace.firstElement = mIndices.size(); tsFace.numElements = 3; tsFace.type |= Primitive::Triangles | Primitive::Indexed; // set vertex indices word vertIndices[3]; msTriangle_GetVertexIndices(msFace, vertIndices); Point3D vert0 = verts[vertIndices[0]]; Point3D vert1 = verts[vertIndices[1]]; Point3D vert2 = verts[vertIndices[2]]; Point3D norm0 = getNormal(mesh, i, 0); Point3D norm1 = getNormal(mesh, i, 1); Point3D norm2 = getNormal(mesh, i, 2); // set texture vertex indices Point2D tvert0 = getTVert(mesh, i, 0); Point2D tvert1 = getTVert(mesh, i, 1); Point2D tvert2 = getTVert(mesh, i, 2); // now add indices (switch order to be CW) mIndices.push_back(addVertex(vert0,norm0,tvert0,vertIndices[0])); mIndices.push_back(addVertex(vert2,norm2,tvert2,vertIndices[2])); mIndices.push_back(addVertex(vert1,norm1,tvert1,vertIndices[1])); // if the material is double-sided, add the backface as well if (!(tsFace.type & Primitive::NoMaterial)) { bool doubleSided = false; MilkshapeMaterial *msMat = mMsNode->getMaterial(); msMat->getUserPropBool("doubleSided", doubleSided); if (doubleSided) { Primitive backface = tsFace; backface.firstElement = mIndices.size(); mFaces.push_back(backface); // add verts with order reversed to get the backface mIndices.push_back(addVertex(vert0,-norm0,tvert0,vertIndices[0])); mIndices.push_back(addVertex(vert1,-norm1,tvert1,vertIndices[1])); mIndices.push_back(addVertex(vert2,-norm2,tvert2,vertIndices[2])); } } } return Parent::lockMesh(time,objectOffset); }