LptaAssimpMesh::LptaAssimpMesh( VERTEX_TYPE vertexType, const std::string &filename, const LptaRenderDevice &device) { MANAGERS managers = { *device.GetMaterialManager(), *device.GetTextureManager(), *device.GetSkinManager() }; if (SUCCESSFUL assetImporter.ReadFile(filename, IMPORT_FLAGS)) { const aiScene *scene = assetImporter.GetOrphanedScene(); try { if (!scene || !IsValidScene(*scene)) { throw LptaMeshLoadFailure("Not a valid mesh file"); } vertices = CopyMesh(vertexType, indices, skinId, scene, managers); } catch (const LptaMeshLoadFailure &loadFailure) { if (scene) { aiReleaseImport(scene); } throw loadFailure; } aiReleaseImport(scene); } else { // log error throw LptaMeshLoadFailure(assetImporter.GetErrorString()); } }
/* ================ DrawSurfaceForMesh ================ */ mapDrawSurface_t *DrawSurfaceForMesh( mesh_t *m ) { mapDrawSurface_t *ds; int i, j; mesh_t *copy; // to make valid normals for patches with degenerate edges, // we need to make a copy of the mesh and put the aproximating // points onto the curve copy = CopyMesh( m ); PutMeshOnCurve( *copy ); MakeMeshNormals( *copy ); for ( j = 0 ; j < m->width ; j++ ) { for ( i = 0 ; i < m->height ; i++ ) { VectorCopy( copy->verts[i*m->width+j].normal, m->verts[i*m->width+j].normal ); } } FreeMesh( copy ); ds = AllocDrawSurf(); ds->mapBrush = NULL; ds->side = NULL; ds->patch = qtrue; ds->patchWidth = m->width; ds->patchHeight = m->height; ds->numVerts = ds->patchWidth * ds->patchHeight; ds->verts = malloc( ds->numVerts * sizeof( *ds->verts ) ); memcpy( ds->verts, m->verts, ds->numVerts * sizeof( *ds->verts ) ); ds->lightmapNum = -1; ds->fogNum = -1; return ds; }
SpawnPoint::SpawnPoint(unsigned int index, unsigned int teamNum, Player* o, renderableType i, Vec2D loc, Vec2D dir, bool collides, bool draw) : Base(index, o, loc, dir, collides, draw) { teamNumber = teamNum; mesh = CopyMesh(i, getGameType()->teams[teamNumber].color); //each object's mesh will have an individual color, so each has its own copy if(collidable) { bb = new BoundingBox; bb->Setup(loc.x - mesh->radius, loc.y + mesh->radius, mesh->radius * 2, this); } }
EMPBomb::EMPBomb(unsigned int index, Player* player, Vec2D location, Vec2D direction, float life, bool collides, bool draw) : Base(index, player, location, direction, collides, draw) { mesh = CopyMesh(empbomb, (player? getGameType()->teams[player->team].color:Color())); //each object's mesh will have an individual color, so each has its own copy if(collidable) { bb = new BoundingBox; bb->Setup(loc.x - mesh->radius, loc.y + mesh->radius, mesh->radius * 2, this); } lifetime = life; }
void CMoon::Copy( const CMoon& Src_ ) { // Single Mesh CopyMesh( Src_ ); // Blending m_OriginalColor = Src_.m_OriginalColor; // This m_bActive = Src_.m_bActive; m_vTranslation = Src_.m_vTranslation; m_fRisingRate = Src_.m_fRisingRate; m_fFillRate = Src_.m_fFillRate; m_fPitch = Src_.m_fPitch; }
/* ================= SubdivideMeshQuads ================= */ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *widthtable, int *heighttable ) { int i, j, k, w, h, maxsubdivisions, subdivisions; vec3_t dir; float length, maxLength, amount; mesh_t out; bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; out.width = in->width; out.height = in->height; for ( i = 0 ; i < in->width ; i++ ) { for ( j = 0 ; j < in->height ; j++ ) { expand[j][i] = in->verts[j*in->width+i]; } } if (maxsize > MAX_EXPANDED_AXIS) Error("SubdivideMeshQuads: maxsize > MAX_EXPANDED_AXIS"); // horizontal subdivisions maxsubdivisions = (maxsize - in->width) / (in->width - 1); for ( w = 0, j = 0 ; w < in->width - 1; w++, j += subdivisions + 1) { maxLength = 0; for ( i = 0 ; i < out.height ; i++ ) { VectorSubtract(expand[i][j+1].xyz, expand[i][j].xyz, dir); length = VectorLength( dir ); if (length > maxLength) { maxLength = length; } } subdivisions = (int) (maxLength / minLength); if (subdivisions > maxsubdivisions) subdivisions = maxsubdivisions; widthtable[w] = subdivisions + 1; if (subdivisions <= 0) continue; out.width += subdivisions; for ( i = 0 ; i < out.height ; i++ ) { for ( k = out.width - 1 ; k > j + subdivisions; k-- ) { expand[i][k] = expand[i][k-subdivisions]; } for (k = 1; k <= subdivisions; k++) { amount = (float) k / (subdivisions + 1); LerpDrawVertAmount(&expand[i][j], &expand[i][j+subdivisions+1], amount, &expand[i][j+k]); } } } maxsubdivisions = (maxsize - in->height) / (in->height - 1); for ( h = 0, j = 0 ; h < in->height - 1; h++, j += subdivisions + 1) { maxLength = 0; for ( i = 0 ; i < out.width ; i++ ) { VectorSubtract(expand[j+1][i].xyz, expand[j][i].xyz, dir); length = VectorLength( dir ); if (length > maxLength) { maxLength = length; } } subdivisions = (int) (maxLength / minLength); if (subdivisions > maxsubdivisions) subdivisions = maxsubdivisions; heighttable[h] = subdivisions + 1; if (subdivisions <= 0) continue; out.height += subdivisions; for ( i = 0 ; i < out.width ; i++ ) { for ( k = out.height - 1 ; k > j + subdivisions; k-- ) { expand[k][i] = expand[k-subdivisions][i]; } for (k = 1; k <= subdivisions; k++) { amount = (float) k / (subdivisions + 1); LerpDrawVertAmount(&expand[j][i], &expand[j+subdivisions+1][i], amount, &expand[j+k][i]); } } } // collapse the verts out.verts = &expand[0][0]; for ( i = 1 ; i < out.height ; i++ ) { memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(bspDrawVert_t) ); } return CopyMesh(&out); }
/* ================ RemoveLinearMeshColumsRows ================ */ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) { int i, j, k; float len, maxLength; vec3_t proj, dir; mesh_t out; /* ydnar: static for os x */ MAC_STATIC bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; out.width = in->width; out.height = in->height; for ( i = 0 ; i < in->width ; i++ ) { for ( j = 0 ; j < in->height ; j++ ) { expand[j][i] = in->verts[j*in->width+i]; } } for ( j = 1 ; j < out.width - 1; j++ ) { maxLength = 0; for ( i = 0 ; i < out.height ; i++ ) { ProjectPointOntoVector(expand[i][j].xyz, expand[i][j-1].xyz, expand[i][j+1].xyz, proj); VectorSubtract(expand[i][j].xyz, proj, dir); len = VectorLength(dir); if (len > maxLength) { maxLength = len; } } if (maxLength < 0.1) { out.width--; for ( i = 0 ; i < out.height ; i++ ) { for (k = j; k < out.width; k++) { expand[i][k] = expand[i][k+1]; } } j--; } } for ( j = 1 ; j < out.height - 1; j++ ) { maxLength = 0; for ( i = 0 ; i < out.width ; i++ ) { ProjectPointOntoVector(expand[j][i].xyz, expand[j-1][i].xyz, expand[j+1][i].xyz, proj); VectorSubtract(expand[j][i].xyz, proj, dir); len = VectorLength(dir); if (len > maxLength) { maxLength = len; } } if (maxLength < 0.1) { out.height--; for ( i = 0 ; i < out.width ; i++ ) { for (k = j; k < out.height; k++) { expand[k][i] = expand[k+1][i]; } } j--; } } // collapse the verts out.verts = &expand[0][0]; for ( i = 1 ; i < out.height ; i++ ) { memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(bspDrawVert_t) ); } return CopyMesh(&out); }
mesh_t *SubdivideMesh2( mesh_t in, int iterations ) { int i, j, k; bspDrawVert_t prev, next, mid; mesh_t out; /* ydnar: static for os x */ MAC_STATIC bspDrawVert_t expand[ MAX_EXPANDED_AXIS ][ MAX_EXPANDED_AXIS ]; /* initial setup */ out.width = in.width; out.height = in.height; for( i = 0; i < in.width; i++ ) { for( j = 0; j < in.height; j++ ) expand[ j ][ i ] = in.verts[ j * in.width + i ]; } /* keep chopping */ for( iterations; iterations > 0; iterations-- ) { /* horizontal subdivisions */ for( j = 0; j + 2 < out.width; j += 4 ) { /* check size limit */ if( out.width + 2 >= MAX_EXPANDED_AXIS ) break; /* insert two columns and replace the peak */ out.width += 2; for( i = 0; i < out.height; i++ ) { LerpDrawVert( &expand[ i ][ j ], &expand[ i ][ j + 1 ], &prev ); LerpDrawVert( &expand[ i ][ j + 1 ], &expand[ i ][ j + 2 ], &next ); LerpDrawVert( &prev, &next, &mid ); for ( k = out.width - 1 ; k > j + 3; k-- ) expand [ i ][ k ] = expand[ i ][ k - 2 ]; expand[ i ][ j + 1 ] = prev; expand[ i ][ j + 2 ] = mid; expand[ i ][ j + 3 ] = next; } } /* vertical subdivisions */ for ( j = 0; j + 2 < out.height; j += 4 ) { /* check size limit */ if( out.height + 2 >= MAX_EXPANDED_AXIS ) break; /* insert two columns and replace the peak */ out.height += 2; for( i = 0; i < out.width; i++ ) { LerpDrawVert( &expand[ j ][ i ], &expand[ j + 1 ][ i ], &prev ); LerpDrawVert( &expand[ j + 1 ][ i ], &expand[ j + 2 ][ i ], &next ); LerpDrawVert( &prev, &next, &mid ); for( k = out.height - 1; k > j + 3; k-- ) expand[ k ][ i ] = expand[ k - 2 ][ i ]; expand[ j + 1 ][ i ] = prev; expand[ j + 2 ][ i ] = mid; expand[ j + 3 ][ i ] = next; } } } /* collapse the verts */ out.verts = &expand[ 0 ][ 0 ]; for( i = 1; i < out.height; i++ ) memmove( &out.verts[ i * out.width ], expand[ i ], out.width * sizeof( bspDrawVert_t ) ); /* return to sender */ return CopyMesh( &out ); }
/* ================= SubdivideMesh ================= */ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ) { int i, j, k, l; bspDrawVert_t prev, next, mid; vec3_t prevxyz, nextxyz, midxyz; vec3_t delta; float len; mesh_t out; /* ydnar: static for os x */ MAC_STATIC bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; out.width = in.width; out.height = in.height; for ( i = 0 ; i < in.width ; i++ ) { for ( j = 0 ; j < in.height ; j++ ) { expand[j][i] = in.verts[j*in.width+i]; } } // horizontal subdivisions for ( j = 0 ; j + 2 < out.width ; j += 2 ) { // check subdivided midpoints against control points for ( i = 0 ; i < out.height ; i++ ) { for ( l = 0 ; l < 3 ; l++ ) { prevxyz[l] = expand[i][j+1].xyz[l] - expand[i][j].xyz[l]; nextxyz[l] = expand[i][j+2].xyz[l] - expand[i][j+1].xyz[l]; midxyz[l] = (expand[i][j].xyz[l] + expand[i][j+1].xyz[l] * 2 + expand[i][j+2].xyz[l] ) * 0.25; } // if the span length is too long, force a subdivision if ( VectorLength( prevxyz ) > minLength || VectorLength( nextxyz ) > minLength ) { break; } // see if this midpoint is off far enough to subdivide VectorSubtract( expand[i][j+1].xyz, midxyz, delta ); len = VectorLength( delta ); if ( len > maxError ) { break; } } if ( out.width + 2 >= MAX_EXPANDED_AXIS ) { break; // can't subdivide any more } if ( i == out.height ) { continue; // didn't need subdivision } // insert two columns and replace the peak out.width += 2; for ( i = 0 ; i < out.height ; i++ ) { LerpDrawVert( &expand[i][j], &expand[i][j+1], &prev ); LerpDrawVert( &expand[i][j+1], &expand[i][j+2], &next ); LerpDrawVert( &prev, &next, &mid ); for ( k = out.width - 1 ; k > j + 3 ; k-- ) { expand[i][k] = expand[i][k-2]; } expand[i][j + 1] = prev; expand[i][j + 2] = mid; expand[i][j + 3] = next; } // back up and recheck this set again, it may need more subdivision j -= 2; } // vertical subdivisions for ( j = 0 ; j + 2 < out.height ; j += 2 ) { // check subdivided midpoints against control points for ( i = 0 ; i < out.width ; i++ ) { for ( l = 0 ; l < 3 ; l++ ) { prevxyz[l] = expand[j+1][i].xyz[l] - expand[j][i].xyz[l]; nextxyz[l] = expand[j+2][i].xyz[l] - expand[j+1][i].xyz[l]; midxyz[l] = (expand[j][i].xyz[l] + expand[j+1][i].xyz[l] * 2 + expand[j+2][i].xyz[l] ) * 0.25; } // if the span length is too long, force a subdivision if ( VectorLength( prevxyz ) > minLength || VectorLength( nextxyz ) > minLength ) { break; } // see if this midpoint is off far enough to subdivide VectorSubtract( expand[j+1][i].xyz, midxyz, delta ); len = VectorLength( delta ); if ( len > maxError ) { break; } } if ( out.height + 2 >= MAX_EXPANDED_AXIS ) { break; // can't subdivide any more } if ( i == out.width ) { continue; // didn't need subdivision } // insert two columns and replace the peak out.height += 2; for ( i = 0 ; i < out.width ; i++ ) { LerpDrawVert( &expand[j][i], &expand[j+1][i], &prev ); LerpDrawVert( &expand[j+1][i], &expand[j+2][i], &next ); LerpDrawVert( &prev, &next, &mid ); for ( k = out.height - 1 ; k > j + 3 ; k-- ) { expand[k][i] = expand[k-2][i]; } expand[j+1][i] = prev; expand[j+2][i] = mid; expand[j+3][i] = next; } // back up and recheck this set again, it may need more subdivision j -= 2; } // collapse the verts out.verts = &expand[0][0]; for ( i = 1 ; i < out.height ; i++ ) { memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(bspDrawVert_t) ); } return CopyMesh(&out); }
Ship::Ship(unsigned int index, Player* o, renderableType i, Vec2D location, Vec2D direction, float maxspeed, float sensor, int hp, int weight, pfunc pF, pfunc2 pF2, bool collides, bool draw) : Base(index, o, location, direction, collides, draw) { mesh = CopyMesh(i, (o? getGameType()->teams[o->team].color:Color())); //each object's mesh will have an individual color, so each has its own copy if(collidable) { bb = new BoundingBox; bb->Setup(loc.x - mesh->radius, loc.y + mesh->radius, mesh->radius * 2, this); } SpecialAbility = pF; EndSpecialAbility = pF2; abilityTimer = 0.0f; abilityCooldownTimer = 0.0f; maxSpeed = maxspeed; mass = weight; theta = 3.14159f/(mass < 35? 35:mass); //limit on how fast you can turn hitpoints = maxHitpoints = hp; if(mass <= 0) mass = 1; else if(mass > 100) mass = 100; sensorStrength = sensor; thrusting = false; //shooting = thrusting = slowing = turningRight = turningLeft = stop = breakLock = haxors = false; weapon = NULL; targetObj = NULL; acc.zero(); vel.zero(); Mesh* m = (Mesh*)mesh; //convert mesh from Renderable to Mesh pointer Game* g = getGame(); bool handledHere = false; Base* p = NULL; for(unsigned int i = 0; i < m->mountNum; ++i) { if(m->mountNames[i] == "missile") { p = new Launcher(getGame()->getNextIndex(), owner, none, this, m->mountLocs[i], Vec2D(), 1.0f, shootMissile); handledHere = true; } else if(m->mountNames[i] == "projectile") { p = new Launcher(getGame()->getNextIndex(), owner, none, this, m->mountLocs[i], Vec2D(), 1.0f, shootProjectile); handledHere = true; } else if(m->mountNames[i] == "drone") { p = new Launcher(getGame()->getNextIndex(), owner, none, this, m->mountLocs[i], Vec2D(), 1.0f, shootDrone); handledHere = true; } if(handledHere) { g->insertObject(p); m->actualMounts[i] = p; this->weapon = ((Weapon*)p); handledHere = false; } } }