Matrix& Matrix::SetInverse(const Matrix& mStart) { const int size = 4; bool bSwap = false; Matrix m(mStart); SetIdentity(); for (int row = 0; row < size; row++) { // // pick the largest row in the rowth column // float max = abs(m.m_m[row][row]); int rowMax = row; for (int rowIndex = row + 1; rowIndex < size; rowIndex++) { if (abs(m.m_m[rowIndex][row]) > max) { max = abs(m.m_m[rowIndex][row]); rowMax = rowIndex; } } // // swap this row with the largest row // if (rowMax != row) { // // swap rows // bSwap = true; for (int col = 0; col < size; col++) { Swap(m.m_m[row][col], m.m_m[rowMax][col]); Swap( m_m[row][col], m_m[rowMax][col]); } } // // scale to get a one in the diagonal // float scale = m.m_m[row][row]; if (scale != 1.0f) { float rscale = 1.0f / scale; int col; m.m_m[row][row] = 1; for (col = row + 1; col < size; col++) { m.m_m[row][col] *= rscale; } if (bSwap) { for (col = 0; col < size; col++) { m_m[row][col] *= rscale; } } else { m_m[row][row] = rscale; for (col = 0; col < row; col++) { m_m[row][col] *= rscale; } } } // // get zeros in the rowth column of each row // by subtracting a multiple of row from row2 // for (int row2 = 0; row2 < size; row2++) { if (row2 != row) { float scale = m.m_m[row2][row]; if (scale != 0) { int col; m.m_m[row2][row] = 0; for (col = row + 1; col < size; col++) { m.m_m[row2][col] -= scale * m.m_m[row][col]; } if (bSwap) { for (col = 0; col < size; col++) { m_m[row2][col] -= scale * m_m[row][col]; } } else { for (col = 0; col <= row; col++) { m_m[row2][col] -= scale * m_m[row][col]; } } } } } } m_type = TransformUnknown; return *this; }
bool PraetoriansTerrainWater::loadPackedMedia(const char* path) { unsigned int signature; unsigned short chunkid; unsigned int chunklength; unsigned int texturescount;///use one in this version unsigned int watercount; unsigned int vertexcount; unsigned int indexcount; Tuple3f* vertices; unsigned short* indices; Tuple4ub* colors; Tuple2f* txcoords; ArchivedFile* file; WaterDatabase* wdatabase; if (!(file = FileSystem::checkOut(path))) return Logger::writeErrorLog(String("Could not load -> ") + path); wdatabase = Gateway::getWaterDatabase(); file->read(&signature, 4); file->read(&chunkid, 2); file->read(&chunklength, 4); file->read(&texturescount, 4); for (unsigned int i = 0; i < texturescount; i++) file->seek((256 * 256 * 4) + 6, SEEKD); file->read(&watercount, 4); for (unsigned int i = 0; i < watercount; i++) { file->read(&chunkid, 2); file->read(&chunklength, 4); file->seek(48, SEEKD); file->read(&vertexcount, 4); vertices = new Tuple3f[vertexcount]; colors = new Tuple4ub[vertexcount]; txcoords = new Tuple2f[vertexcount]; for (unsigned int j = 0; j < vertexcount; j++) { file->read(vertices[j], 12); Swap(vertices[j].x, vertices[j].z); file->read(colors[j], 4); Swap(colors[j].x, colors[j].z); file->read(txcoords[j], 8); } file->read(&indexcount, 4); indices = new unsigned short[indexcount]; file->read(indices, indexcount * 2); String watername = String("H2O_") + int(wdatabase->getWatersCount()); Geometry* geometry; geometry = new Geometry(watername, indexcount, vertexcount); geometry->setIndices(indices, false); geometry->setVertices(vertices, false); geometry->setColors(colors, false); geometry->setTextureElements(txcoords, 2, false); geometry->computeBounds(); Appearance* appearance = new Appearance(); appearance->setBlendAttributes(BlendAttributes(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); appearance->setTexture(0, wdatabase->getWaterTexture()); Model* model = new Model(); model->setAppearance(appearance); model->setGeometry(geometry); TransformGroup* group = new TransformGroup(); group->addChild(model); group->updateBoundsDescriptor(); wdatabase->addWaterModel(group); deleteArray(vertices); deleteArray(indices); deleteArray(colors); deleteArray(txcoords); } FileSystem::checkIn(file); return true; }
bool PraetoriansTerrainWater::exportData(const char* projectName) { WaterDatabase* wdatabase; TransformGroup* tgroup; TransformGroup* tgroupchild; Geometry* geo; const char* inp; unsigned char* colsbuf; Tuple3f* verts; Tuple4ub* colors; Tuple2f *txcoords; unsigned short* indices; unsigned int signature = 2; unsigned short texturechunkid = 22912; unsigned int texturechunklen = 262164; unsigned int texturecount = 1; unsigned short textureid = 22914; unsigned int texturelen = 262150; unsigned short waterid = 22913; unsigned int waterlen = 0; unsigned int watercount; unsigned char bullshit0 = 0; unsigned char bullshit01[4] = {0xF0, 0xAD, 0xBA, 0x0D}; unsigned char bullshit1[4] = {0x00}; unsigned int vertcount; unsigned int idxcount; Tuple4ub refcol; Tuple3f refvert; String path = Gateway::getExportPath(); if (!(inp = MediaPathManager::lookUpMediaPath("water_2_1.col"))) return Logger::writeErrorLog("Could not locate water_2_1.col"); ifstream in(inp, ios_base::binary); if (!in.is_open()) return false; colsbuf = (unsigned char*) Gateway::aquireGeometryMemory(256 * 256 * 4); in.read((char*)colsbuf, 256 * 256 * 4); in.close(); ofstream out((path + "Mapas/" + projectName + ".H2O").getBytes(), ios_base::binary); if (!out.is_open()) return false; out.write((char*)&signature, 4); out.write((char*)&texturechunkid, 2); out.write((char*)&texturechunklen, 4); out.write((char*)&texturecount, 4); out.write((char*)&textureid, 2); out.write((char*)&texturelen, 4); out.write((char*)colsbuf, 256 * 256 * 4); Gateway::releaseGeometryMemory(colsbuf); wdatabase = Gateway::getWaterDatabase(); tgroup = wdatabase->getRootGroup(); watercount = tgroup->getGroupsCount(); out.write((char*)&watercount, 4); for (unsigned int i = 0; i < watercount; i++) { tgroupchild = tgroup->getGroup(i); geo = tgroupchild->getModel(0)->getGeometry(); verts = geo->getVertices(); colors = geo->getColors(); txcoords = geo->getTextureCoords(); indices = geo->getIndices(); vertcount = geo->getVerticesCount(); idxcount = geo->getIndicesCount(); out.write((char*)&waterid, 2); waterlen = 52 + (vertcount*24) + 4 + (idxcount*2) + 6; out.write((char*)&waterlen, 4); out.write((char*)&bullshit0, 1); for (unsigned int j = 0; j < 7; j++) out.write((char*)bullshit01, 4); out.write((char*)bullshit01, 3); for (unsigned int j = 0; j < 4; j++) out.write((char*)bullshit1, 4); out.write((char*)&vertcount, 4); for (unsigned int j = 0; j < vertcount; j++) { refvert = verts[j]; Swap(refvert.x, refvert.z); out.write((char*)&refvert, 12); refcol = colors[j]; Swap(refcol.x, refcol.z); out.write((char*)&refcol, 4); out.write((char*)&txcoords[j], 8); } out.write((char*)&idxcount, 4); out.write((char*)indices, idxcount * 2); } out.close(); return true; }
void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1, GLUvertex *o2, GLUvertex *d2, GLUvertex *v ) /* Given edges (o1,d1) and (o2,d2), compute their point of intersection. * The computed point is guaranteed to lie in the intersection of the * bounding rectangles defined by each edge. */ { GLdouble z1, z2; /* This is certainly not the most efficient way to find the intersection * of two line segments, but it is very numerically stable. * * Strategy: find the two middle vertices in the VertLeq ordering, * and interpolate the intersection s-value from these. Then repeat * using the TransLeq ordering to find the intersection t-value. */ if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); } if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); } if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); } if( ! VertLeq( o2, d1 )) { /* Technically, no intersection -- do our best */ v->s = (o2->s + d1->s) / 2; } else if( VertLeq( d1, d2 )) { /* Interpolate between o2 and d1 */ z1 = EdgeEval( o1, o2, d1 ); z2 = EdgeEval( o2, d1, d2 ); if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } v->s = Interpolate( z1, o2->s, z2, d1->s ); } else { /* Interpolate between o2 and d2 */ z1 = EdgeSign( o1, o2, d1 ); z2 = -EdgeSign( o1, d2, d1 ); if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } v->s = Interpolate( z1, o2->s, z2, d2->s ); } /* Now repeat the process for t */ if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); } if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); } if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); } if( ! TransLeq( o2, d1 )) { /* Technically, no intersection -- do our best */ v->t = (o2->t + d1->t) / 2; } else if( TransLeq( d1, d2 )) { /* Interpolate between o2 and d1 */ z1 = TransEval( o1, o2, d1 ); z2 = TransEval( o2, d1, d2 ); if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } v->t = Interpolate( z1, o2->t, z2, d1->t ); } else { /* Interpolate between o2 and d2 */ z1 = TransSign( o1, o2, d1 ); z2 = -TransSign( o1, d2, d1 ); if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } v->t = Interpolate( z1, o2->t, z2, d2->t ); } }
IOFile& IOFile::operator=(IOFile&& other) { Swap(other); return *this; }
IOFile::IOFile(IOFile&& other) : m_file(nullptr), m_good(true) { Swap(other); }