void CEndGameBox::Draw() { if (disabled) { return; } float mx=MouseX(mouse->lastx); float my=MouseY(mouse->lasty); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); // Large Box glColor4f(0.2f,0.2f,0.2f,guiAlpha); DrawBox(box); glColor4f(0.2f,0.2f,0.7f,guiAlpha); if(dispMode==0){ DrawBox(box+playerBox); } else if(dispMode==1){ DrawBox(box+sumBox); } else { DrawBox(box+difBox); } if(InBox(mx,my,box+exitBox)){ glColor4f(0.7f,0.2f,0.2f,guiAlpha); DrawBox(box+exitBox); } if(InBox(mx,my,box+playerBox)){ glColor4f(0.7f,0.2f,0.2f,guiAlpha); DrawBox(box+playerBox); } if(InBox(mx,my,box+sumBox)){ glColor4f(0.7f,0.2f,0.2f,guiAlpha); DrawBox(box+sumBox); } if(InBox(mx,my,box+difBox)){ glColor4f(0.7f,0.2f,0.2f,guiAlpha); DrawBox(box+difBox); } glEnable(GL_TEXTURE_2D); glColor4f(1,1,1,0.8f); font->glPrintAt(box.x1+exitBox.x1+0.025f,box.y1+exitBox.y1+0.005f,1,"Exit"); font->glPrintAt(box.x1+playerBox.x1+0.015f,box.y1+playerBox.y1+0.005f,0.7f,"Player stats"); font->glPrintAt(box.x1+sumBox.x1+0.015f,box.y1+sumBox.y1+0.005f,0.7f,"Team stats"); font->glPrintAt(box.x1+difBox.x1+0.015f,box.y1+difBox.y1+0.005f,0.7f,"Team delta stats"); if(gs->Team(gu->myTeam)->isDead){ font->glPrintAt(box.x1+0.25f,box.y1+0.65f,1,"You lost the game"); } else { font->glPrintAt(box.x1+0.25f,box.y1+0.65f,1,"You won the game"); } if(dispMode==0){ float xpos=0.01f; string headers[]={"Name","MC/m","MP/m","KP/m","Cmds/m","ACS"}; for(int a=0;a<6;++a){ font->glPrintAt(box.x1+xpos,box.y1+0.55f,0.8f,headers[a].c_str()); xpos+=0.1f; } float ypos=0.5f; for(int a=0;a<gs->activePlayers;++a){ if(gs->players[a]->currentStats->mousePixels==0) continue; char values[6][100]; sprintf(values[0],"%s", gs->players[a]->playerName.c_str()); sprintf(values[1],"%i",(int)(gs->players[a]->currentStats->mouseClicks*60/game->totalGameTime)); sprintf(values[2],"%i",(int)(gs->players[a]->currentStats->mousePixels*60/game->totalGameTime)); sprintf(values[3],"%i",(int)(gs->players[a]->currentStats->keyPresses*60/game->totalGameTime)); sprintf(values[4],"%i",(int)(gs->players[a]->currentStats->numCommands*60/game->totalGameTime)); sprintf(values[5],"%i",(int) ( gs->players[a]->currentStats->numCommands != 0 ) ? ( gs->players[a]->currentStats->unitCommands/gs->players[a]->currentStats->numCommands) : ( 0 )); float xpos=0.01f; for(int a=0;a<6;++a){ font->glPrintAt(box.x1+xpos,box.y1+ypos,0.8f,values[a]); xpos+=0.1f; } ypos-=0.02f; } } else { if(stats.empty()) FillTeamStats(); glBindTexture(GL_TEXTURE_2D, graphTex); CVertexArray* va=GetVertexArray(); va->Initialize(); va->AddVertexT(float3(box.x1+0.15f, box.y1+0.08f, 0),0,0); va->AddVertexT(float3(box.x1+0.69f, box.y1+0.08f, 0),4,0); va->AddVertexT(float3(box.x1+0.69f, box.y1+0.62f, 0),4,4); va->AddVertexT(float3(box.x1+0.15f, box.y1+0.62f, 0),0,4); va->DrawArrayT(GL_QUADS); if(mx>box.x1+0.01f && mx<box.x1+0.12f && my<box.y1+0.57f && my>box.y1+0.571f-stats.size()*0.02f){ int sel=(int)floor(-(my-box.y1-0.57f)*50); glColor4f(0.7f,0.2f,0.2f,guiAlpha); glDisable(GL_TEXTURE_2D); CVertexArray* va=GetVertexArray(); va->Initialize(); va->AddVertex0(float3(box.x1+0.01f, box.y1+0.55f-sel*0.02f , 0)); va->AddVertex0(float3(box.x1+0.01f, box.y1+0.55f-sel*0.02f+0.02f , 0)); va->AddVertex0(float3(box.x1+0.12f, box.y1+0.55f-sel*0.02f+0.02f , 0)); va->AddVertex0(float3(box.x1+0.12f, box.y1+0.55f-sel*0.02f , 0)); va->DrawArray0(GL_QUADS); glEnable(GL_TEXTURE_2D); glColor4f(1,1,1,0.8f); } float ypos=0.55f; for(int a=0;a<stats.size();++a){ font->glPrintAt(box.x1+0.01f,box.y1+ypos,0.8f,stats[a].name.c_str()); ypos-=0.02f; } float maxy=1; if(dispMode==1) maxy=std::max(stats[stat1].max,stat2!=-1?stats[stat2].max:0); else maxy=std::max(stats[stat1].maxdif,stat2!=-1?stats[stat2].maxdif:0)/CTeam::statsPeriod; int numPoints=stats[0].values[0].size(); float scalex=0.54f/max(1.0f,numPoints-1.0f); float scaley=0.54f/maxy; for (int a = 0; a < 5; ++a) { font->glPrintAt(box.x1 + 0.12f, box.y1 + 0.07f + (a * 0.135f), 0.8f, "%s", FloatToSmallString(maxy * 0.25f * a).c_str()); font->glPrintAt(box.x1 + 0.135f + (a * 0.135f), box.y1 + 0.057f, 0.8f, "%i:%2i", int(a * 0.25f * numPoints * CTeam::statsPeriod / 60), int(a * 0.25f * (numPoints - 1) * CTeam::statsPeriod) % 60); } font->glPrintAt(box.x1+0.55f,box.y1+0.65f,0.8f,"%s",stats[stat1].name.c_str()); font->glPrintAt(box.x1+0.55f,box.y1+0.63f,0.8f,"%s",stat2!=-1?stats[stat2].name.c_str():""); glDisable(GL_TEXTURE_2D); glBegin(GL_LINES); glVertex3f(box.x1+0.50f,box.y1+0.66f,0); glVertex3f(box.x1+0.55f,box.y1+0.66f,0); glEnd(); glLineStipple(3,0x5555); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex3f(box.x1+0.50f,box.y1+0.64f,0); glVertex3f(box.x1+0.55f,box.y1+0.64f,0); glEnd(); glDisable(GL_LINE_STIPPLE); for(int team=0; team<gs->activeTeams; team++){ if (gs->Team(team)->gaia) continue; glColor4ubv(gs->Team(team)->color); glBegin(GL_LINE_STRIP); for(int a=0;a<numPoints;++a){ float value=0; if(dispMode==1) value=stats[stat1].values[team][a]; else if(a>0) value=(stats[stat1].values[team][a]-stats[stat1].values[team][a-1])/CTeam::statsPeriod; glVertex3f(box.x1+0.15f+a*scalex,box.y1+0.08f+value*scaley,0); } glEnd(); if (stat2!=-1) { glLineStipple(3,0x5555); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINE_STRIP); for(int a=0;a<numPoints;++a){ float value=0; if(dispMode==1) value=stats[stat2].values[team][a]; else if(a>0) value=(stats[stat2].values[team][a]-stats[stat2].values[team][a-1])/CTeam::statsPeriod; glVertex3f(box.x1+0.15f+a*scalex,box.y1+0.08f+value*scaley,0); } glEnd(); glDisable(GL_LINE_STIPPLE); } } } }
int main(int argc, char *argv[]) try { physics_driftmax = 0.0025f; GLWin glwin("point cloud push interaction"); RSCam dcam; dcam.Init((argc == 2) ? argv[1] : NULL); Image<unsigned short> dimage(dcam.dcamera()); glwin.ViewAngle = dcam.fov().y; float viewdist = 2.0f; float yaw = 120; int mousexold = 0; Mesh mesh; bool pause = false; bool debuglines=false; int center = 0; bool chains = true; bool usehull = false; std::vector<RigidBody*> rigidbodies; std::vector < std::pair<RigidBody*, RigidBody*>> links; for (float x = -0.2f; x < 0.2f; x+= 0.07f) for(float z: {0.350f}) for (float y = -0.2f; y <= 0.2f; y += 0.07f) { rigidbodies.push_back(new RigidBody({ AsShape(WingMeshDual(WingMeshCube(0.025f),0.028f)) }, { x,y,z })); //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.025f) ) }, { x,y,z })); links.push_back({(y > -0.2f)?rigidbodies[rigidbodies.size() - 2]:NULL , rigidbodies.back()}); } //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.05f)) }, { 0,0,0.50f })); auto seesaw = new RigidBody({ AsShape(WingMeshBox({ 0.20f, 0.015f, 0.05f })) }, { 0,0,0.45f }); rigidbodies.push_back(seesaw); glwin.keyboardfunc = [&](unsigned char key, int x, int y)->void { switch (std::tolower(key)) { case 'q': case 27: exit(0); break; // 27 is ESC case ' ': pause = !pause; break; case 'c': chains = !chains; break; case 'd': debuglines = !debuglines; break; case 'h': usehull = !usehull; break; case 'r': for (auto &rb : rigidbodies) { rb->angular_momentum = rb->linear_momentum = float3(0.0f);rb->pose() = { rb->position_start,rb->orientation_start }; } break; default: std::cout << "unassigned key (" << (int)key << "): '" << key << "'\n"; break; } }; if (dcam.dev->supports_option(rs::option::r200_lr_auto_exposure_enabled)) dcam.dev->set_option(rs::option::r200_lr_auto_exposure_enabled, 1); while (glwin.WindowUp()) { if (glwin.MouseState) { yaw += glwin.mousepos.x - mousexold; } mousexold = glwin.mousepos.x; viewdist *= powf(1.1f, (float)glwin.mousewheel); if (!pause) dimage = dcam.GetDepth(); glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(0, 0, glwin.res.x, glwin.res.y); glClearColor(0.1f, 0.1f, 0.15f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(glwin.ViewAngle, (double)glwin.aspect_ratio(), 0.01f, 50.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); gluLookAt(0, 0, viewdist, 0, 0, 0, 0, -1, 0); glEnable(GL_DEPTH_TEST); glTranslatef(0, 0, 0.35f); glRotatef(yaw, 0, 1, 0); glTranslatef(0, 0, -0.35f); std::vector<float3> pts; std::vector<float3> outliers; std::vector<float3> vpts; glDisable(GL_BLEND); float2 wrange = { 0.20f,0.60f }; auto dp_image_c = Transform(dimage, [](unsigned short s) {return byte3((unsigned char)clamp(255 - s / 4, 0, 255)); }); drawimage(dp_image_c, { 0.78f,0.22f }, { 0.2f,-0.2f }, 3); float depth_scale = (dcam.dev) ? dcam.dev->get_depth_scale() : 0.001f; // to put into meters // if file assume file is mm for (auto p : rect_iteration(dimage.dim())) // p is int2 from 0,0 to w,h of dcam { float d = dimage.pixel(p) * depth_scale; // d is in meters, whereas depth[i] is in camera units mm for R200, .125mm for SR300 ivycam if (p.x<5 || p.x> dimage.dim().x - 5 || p.y<5 || p.y>dimage.dim().y - 5) continue; // crop, seems to be lots of noise at the edges if (d > 1.0f) // just too far continue; float3 v = dimage.cam.deprojectz(asfloat2(p), d); if (d>wrange.x && d < wrange.y) pts.push_back(v); else outliers.push_back(v); } vpts = ObtainVoxelPointCloud(pts, 0.0082f, 8); std::vector<std::pair<float3, float3>> lines; std::vector<std::pair<float3, float3>> glines; if (1)// && pts.size()) { std::vector<LimitLinear> linears; std::vector<LimitAngular> angulars; physics_gravity = { 0, (float) chains,0 }; // ugg y is down if(!usehull) for(auto rb:rigidbodies) { if (!rb->shapes[0].planes.size()) rb->shapes[0].planes = Planes(rb->shapes[0].verts, rb->shapes[0].tris); auto planes = Transform(rb->shapes[0].planes, [&](float4 p) { return rb->pose().TransformPlane(p);}); rb->gravscale = (float)chains; float separation = FLT_MAX; float3 pushpoint = float3(0, 0, 0); // float4 pushplane; for (auto p : vpts) { auto plane = mostabove(planes, p); float sep; if ((sep = dot(plane, float4(p, 1))) < separation) { pushpoint = p; pushplane = plane; separation = sep; } } if (separation > 0.1f) continue; float3 closestpoint = ProjectOntoPlane(pushplane, pushpoint); pushplane = float4({ -pushplane.xyz(), -dot(-pushplane.xyz(),pushpoint) }); linears.push_back(ConstrainAlongDirection(NULL, pushpoint, rb, rb->pose().inverse()*closestpoint, pushplane.xyz(), 0, 100.0f)); // FLT_MAX)); lines.push_back({ closestpoint,pushpoint }); auto cp=Separated(rb->shapes[0].verts, rb->position, rb->orientation, { pushpoint }, { 0,0,0 }, { 0,0,0,1 }, 1); glines.push_back({ cp.p0w, cp.p1w }); } Append(linears, ConstrainPositionNailed(NULL, seesaw->position_start, seesaw, { 0, 0, 0 })); Append(angulars, ConstrainAngularRange(NULL, seesaw, { 0, 0, 0, 1 }, { 0, 0,-20 }, { 0, 0,20 })); if (chains) for (auto link : links) Append(linears, ConstrainPositionNailed(link.first,link.first? float3(0, 0.035f, 0) : link.second->position_start-float3(0, -0.035f, 0) , link.second, { 0,-0.035f,0 })); if(!pause) if(usehull && vpts.size()>5) PhysicsUpdate(rigidbodies, linears, angulars, { &vpts }); else PhysicsUpdate(rigidbodies, linears, angulars, std::vector<std::vector<float3>*>()); } glColor3f(1, 1, 1); glwirefrustumz(dcam.deprojectextents(), { 0.1f,1.0f }); // draw the camera frustum volume glPushAttrib(GL_ALL_ATTRIB_BITS); glPointSize(1); glBegin(GL_POINTS); glColor3f(0, 1, 0.5f); for (auto p : pts) glVertex3fv(p); glColor3f(1, 0.15f, 0.15f); for (auto p : outliers) glVertex3fv(p); glEnd(); glPointSize(3); glBegin(GL_POINTS); glColor3f(1, 1, 1); for (auto p : vpts) // was: spts glVertex3fv(p); glEnd(); glPopAttrib(); if (debuglines) { glBegin(GL_LINES); glColor3f(0, 1, 1); if (0)for (auto line : lines) glVertex3fv(line.first), glVertex3fv(line.second); glColor3f(1, 1, 0); for (auto line : glines) glVertex3fv(line.first), glVertex3fv(line.second); glEnd(); } if (usehull && vpts.size() > 5) { auto tris = calchull(vpts, 0); glBegin(GL_LINES); glColor3f(1, 1, 1); for (auto t : tris) for( int i : {0,1,1,2,2,0}) glVertex3fv(vpts[t[i]]); glEnd(); } if (chains) { glBegin(GL_LINES); glColor3f(1, 0, 1); for (auto link : links) { if(link.first) glVertex3fv(link.first->pose()* float3(0, 0, 0)), glVertex3fv(link.first->pose()* float3(0, 0.035f, 0)); glVertex3fv(link.second->pose()* float3(0, 0, 0)) , glVertex3fv(link.second->pose()* float3(0, -0.035f, 0)); } glEnd(); } glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glColor3f(0.5f, 0.5f, 0.5f); for (auto &rb : rigidbodies) rbdraw(rb); glPopAttrib(); // Restore state // Restore state glPopMatrix(); //should be currently in modelview mode glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); glMatrixMode(GL_MODELVIEW); glwin.PrintString({ 0,0 }, "esc to quit."); glwin.PrintString({ 0,1 }, "[h] collision %s ",(usehull)?"hull":"points"); glwin.SwapBuffers(); } return 0; } catch (const char *c) { MessageBox(GetActiveWindow(), c, "FAIL", 0); } catch (std::exception e) { MessageBox(GetActiveWindow(), e.what(), "FAIL", 0); }
void CTorpedoProjectile::Draw() { if (model) { // do not draw if a 3D model has been defined for us return; } inArray = true; unsigned char col[4]; col[0] = 60; col[1] = 60; col[2] = 100; col[3] = 255; float3 r = dir.cross(UpVector); if (r.Length() < 0.001f) { r = float3(1.0f, 0.0f, 0.0f); } r.Normalize(); const float3 u = dir.cross(r); const float h = 12; const float w = 2; va->EnlargeArrays(32, 0, VA_SIZE_TC); va->AddVertexQTC(drawPos + (r * w), texx, texy, col); va->AddVertexQTC(drawPos + (u * w), texx, texy, col); va->AddVertexQTC(drawPos + (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (u * w), texx, texy, col); va->AddVertexQTC(drawPos - (r * w), texx, texy, col); va->AddVertexQTC(drawPos - (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (r * w), texx, texy, col); va->AddVertexQTC(drawPos - (u * w), texx, texy, col); va->AddVertexQTC(drawPos - (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (u * w), texx, texy, col); va->AddVertexQTC(drawPos + (r * w), texx, texy, col); va->AddVertexQTC(drawPos + (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos + (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos - (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos - (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos - (u * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (r * w) + (dir * h), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); va->AddVertexQTC(drawPos + (dir * h * 1.2f), texx, texy, col); }
void Mesh::ComputeTangents() { int triangleCount = (int)indices.size(); int vertexCount = (int)pos.size(); if (triangleCount == 0 || vertexCount == 0 || nor.size() == 0) { return; } if (!SizeCheck(tex.size(), vertexCount, "tex", "pos") || !SizeCheck(nor.size(), vertexCount, "nor", "pos")) { return; } std::vector<float3> tan1; tan1.resize(vertexCount); tan.clear(); tan.resize(vertexCount); for (long a = 0; a + 2 < triangleCount; a += 3) { long i1 = indices[a + 0]; long i2 = indices[a + 1]; long i3 = indices[a + 2]; if (!BoundsCheck(i1, vertexCount) || !BoundsCheck(i2, vertexCount) || !BoundsCheck(i3, vertexCount)) { return; } float3 v1 = pos[i1]; float3 v2 = pos[i2]; float3 v3 = pos[i3]; float2 w1 = tex[i1]; float2 w2 = tex[i2]; float2 w3 = tex[i3]; // position differences float x1 = v2.x - v1.x; float x2 = v3.x - v1.x; float y1 = v2.y - v1.y; float y2 = v3.y - v1.y; float z1 = v2.z - v1.z; float z2 = v3.z - v1.z; // texcoord differences float s1 = w2.x - w1.x; float s2 = w3.x - w1.x; float t1 = w2.y - w1.y; float t2 = w3.y - w1.y; // ratio float r = 1.0f / (s1 * t2 - s2 * t1); // vector in the s direction ( tangent ) float3 sdir = float3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); //accumulate tangents for each triangle tan1[i1] += sdir; tan1[i2] += sdir; tan1[i3] += sdir; } // loop through and ortho normalize the tangents for (long a = 0; a < vertexCount; ++a) { float3 n = nor[a]; float3 t = tan1[a]; OrthoNormalize(&n,&t); tan[a].x = t.x; tan[a].y = t.y; tan[a].z = t.z; } }
void CShadowHandler::CalcMinMaxView(void) { left.clear(); //Add restraints for camera sides GetFrustumSide(cam2->bottom,false); GetFrustumSide(cam2->top,true); GetFrustumSide(cam2->rightside,false); GetFrustumSide(cam2->leftside,false); std::vector<fline>::iterator fli,fli2; for(fli=left.begin();fli!=left.end();fli++){ for(fli2=left.begin();fli2!=left.end();fli2++){ if(fli==fli2) continue; float colz=0; if(fli->dir-fli2->dir==0) continue; colz=-(fli->base-fli2->base)/(fli->dir-fli2->dir); if(fli2->left*(fli->dir-fli2->dir)>0){ if(colz>fli->minz && colz<gs->mapy*SQUARE_SIZE+20000) fli->minz=colz; } else { if(colz<fli->maxz && colz>-20000) fli->maxz=colz; } } } x1=-100; x2=100; y1=-100; y2=100; //if someone could figure out how the frustum and nonlinear shadow transform really works (and not use the SJan trial and error method) //so that we can skip this sort of fudge factors it would be good float borderSize=270; float maxSize=gu->viewRange*0.75f; if(shadowMapSize==1024){ borderSize*=1.5f; maxSize*=1.2f; } if(!left.empty()){ std::vector<fline>::iterator fli; for(fli=left.begin();fli!=left.end();fli++){ if(fli->minz<fli->maxz){ float3 p[5]; p[0]=float3(fli->base+fli->dir*fli->minz,0,fli->minz); p[1]=float3(fli->base+fli->dir*fli->maxz,0,fli->maxz); p[2]=float3(fli->base+fli->dir*fli->minz,readmap->maxheight+200,fli->minz); p[3]=float3(fli->base+fli->dir*fli->maxz,readmap->maxheight+200,fli->maxz); p[4]=float3(camera->pos.x,0,camera->pos.z); for(int a=0;a<5;++a){ float xd=(p[a]-centerPos).dot(cross1); float yd=(p[a]-centerPos).dot(cross2); if(xd+borderSize>x2) x2=xd+borderSize; if(xd-borderSize<x1) x1=xd-borderSize; if(yd+borderSize>y2) y2=yd+borderSize; if(yd-borderSize<y1) y1=yd-borderSize; } } } if(x1<-maxSize) x1=-maxSize; if(x2>maxSize) x2=maxSize; if(y1<-maxSize) y1=-maxSize; if(y2>maxSize) y2=maxSize; } else { x1=-maxSize; x2=maxSize; y1=-maxSize; y2=maxSize; } }
void CBasicMapDamage::Explosion(const float3& pos, float strength,float radius) { if(pos.x<0 || pos.z<0 || pos.x>gs->mapx*SQUARE_SIZE || pos.z>gs->mapy*SQUARE_SIZE){ // info->AddLine("Map damage explosion outside map %.0f %.0f",pos.x,pos.z); return; } if(strength<10 || radius<8) return; radius*=1.5; Explo* e=new Explo; e->pos=pos; e->strength=strength; e->ttl=10; e->x1=max((int)(pos.x-radius)/SQUARE_SIZE,2); e->x2=min((int)(pos.x+radius)/SQUARE_SIZE,gs->mapx-3); e->y1=max((int)(pos.z-radius)/SQUARE_SIZE,2); e->y2=min((int)(pos.z+radius)/SQUARE_SIZE,gs->mapy-3); float baseStrength=-pow(strength,0.6f)*3/mapHardness; float invRadius=1.0/radius; for(int y=e->y1;y<=e->y2;++y){ for(int x=e->x1;x<=e->x2;++x){ if(readmap->groundBlockingObjectMap[y*gs->mapx+x] && readmap->groundBlockingObjectMap[y*gs->mapx+x]->blockHeightChanges){ //dont change squares with building on them here e->squares.push_back(0); continue; } float dist=pos.distance2D(float3(x*SQUARE_SIZE,0,y*SQUARE_SIZE)); //calculate the distance float relDist=dist*invRadius; //normalize distance float dif=baseStrength*craterTable[int(relDist*200)]*invHardness[readmap->typemap[(y/2)*gs->hmapx+x/2]]; float prevDif=readmap->heightmap[y*(gs->mapx+1)+x]-readmap->orgheightmap[y*(gs->mapx+1)+x]; // prevDif+=dif*5; if(prevDif*dif>0) dif/=fabs(prevDif)*0.1+1; e->squares.push_back(dif); if(dif<-0.3 && strength>200) treeDrawer->RemoveGrass(x,y); } } std::vector<CUnit*> units=qf->GetUnitsExact(pos,radius); for(std::vector<CUnit*>::iterator ui=units.begin();ui!=units.end();++ui){ //calculate how much to offset the buildings in the explosion radius with (while still keeping the ground under them flat if((*ui)->blockHeightChanges && (*ui)->isMarkedOnBlockingMap){ CUnit* unit=*ui; float3& upos=(*ui)->pos; float totalDif=0; for(int z=unit->mapPos.y; z<unit->mapPos.y+unit->ysize; z++){ for(int x=unit->mapPos.x; x<unit->mapPos.x+unit->xsize; x++){ float dist=pos.distance2D(float3(x*SQUARE_SIZE,0,z*SQUARE_SIZE)); //calculate the distance float relDist=dist*invRadius; //normalize distance float dif=baseStrength*craterTable[int(relDist*200)]*invHardness[readmap->typemap[(z/2)*gs->hmapx+x/2]]; float prevDif=readmap->heightmap[z*(gs->mapx+1)+x]-readmap->orgheightmap[z*(gs->mapx+1)+x]; if(prevDif*dif>0) dif/=fabs(prevDif)*0.1+1; totalDif+=dif; } } totalDif/=unit->xsize*unit->ysize; if(totalDif!=0){ ExploBuilding eb; eb.id=(*ui)->id; eb.dif=totalDif; eb.tx1=unit->mapPos.x; eb.tx2=unit->mapPos.x+unit->xsize; eb.tz1=unit->mapPos.y; eb.tz2=unit->mapPos.y+unit->ysize; e->buildings.push_back(eb); } } } explosions.push_back(e); readmap->Explosion(pos.x,pos.z,strength); }
void CFactory::SlowUpdate(void) { helper->BuggerOff(pos - float3(0.01f, 0, 0.02f), radius); CBuilding::SlowUpdate(); }
void CStartPosSelecter::DrawStartBox() const { glPushMatrix(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); camera->Update(); glColor4f(0.2f,0.8f,0.2f,0.5f); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); const std::vector<AllyTeam>& allyStartData = CGameSetup::GetAllyStartingData(); const AllyTeam& myStartData = allyStartData[gu->myAllyTeam]; const float by = myStartData.startRectTop * mapDims.mapy * SQUARE_SIZE; const float bx = myStartData.startRectLeft * mapDims.mapx * SQUARE_SIZE; const float dy = (myStartData.startRectBottom - myStartData.startRectTop) * mapDims.mapy * SQUARE_SIZE / 10; const float dx = (myStartData.startRectRight - myStartData.startRectLeft) * mapDims.mapx * SQUARE_SIZE / 10; // draw starting-rectangle restrictions glBegin(GL_QUADS); for (int a = 0; a < 10; ++a) { float3 pos1(bx + (a ) * dx, 0.0f, by); float3 pos2(bx + (a + 1) * dx, 0.0f, by); pos1.y = CGround::GetHeightAboveWater(pos1.x, pos1.z, false); pos2.y = CGround::GetHeightAboveWater(pos2.x, pos2.z, false); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2 + UpVector * 100.0f); glVertexf3(pos1 + UpVector * 100.0f); pos1 = float3(bx + (a ) * dx, 0.0f, by + dy * 10.0f); pos2 = float3(bx + (a + 1) * dx, 0.0f, by + dy * 10.0f); pos1.y = CGround::GetHeightAboveWater(pos1.x, pos1.z, false); pos2.y = CGround::GetHeightAboveWater(pos2.x, pos2.z, false); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2 + UpVector * 100.0f); glVertexf3(pos1 + UpVector * 100.0f); pos1 = float3(bx, 0.0f, by + dy * (a )); pos2 = float3(bx, 0.0f, by + dy * (a + 1)); pos1.y = CGround::GetHeightAboveWater(pos1.x, pos1.z, false); pos2.y = CGround::GetHeightAboveWater(pos2.x, pos2.z, false); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2 + UpVector * 100.0f); glVertexf3(pos1 + UpVector * 100.0f); pos1 = float3(bx + dx * 10.0f, 0.0f, by + dy * (a )); pos2 = float3(bx + dx * 10.0f, 0.0f, by + dy * (a + 1)); pos1.y = CGround::GetHeightAboveWater(pos1.x, pos1.z, false); pos2.y = CGround::GetHeightAboveWater(pos2.x, pos2.z, false); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2 + UpVector * 100.0f); glVertexf3(pos1 + UpVector * 100.0f); } glEnd(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glDisable(GL_DEPTH_TEST); glColor4f(1.0f,1.0f,1.0f,1.0f); }
void AudioChannel::PlaySample(size_t id, float volume) { FindSourceAndPlay(id, float3(0.0f, 0.0f, -1.0f), ZeroVector, volume, true); }
void SSEffect::render(GLuint posVBO, GLuint colVBO, unsigned int num, RTPSSettings* settings, const Light* light,const Material* material, float scale, GLuint sceneTex, GLuint sceneDepthTex, GLuint framebuffer) { if(num==0) return; glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); currentDepthBuffer="depth"; bool blending = settings->GetSettingAs<bool>("blending","1"); //QT send 2 for check boxes when enable(due to the possiblity of adding a tristate option. //Apparently the default string-to-bool conversion is true for 1 and false otherwise //I need it to be false for 0 and true otherwise. //bool thickness = !settings->GetSettingAs<int>("thickness","1"); bool thickness = settings->GetSettingAs<bool>("thickness","1"); //perserve original buffer GLint buffer; glGetIntegerv(GL_DRAW_BUFFER,&buffer); glClearColor(0.0f,0.0f,0.0f,0.0f); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,m_fbos[0]); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); //Should probably conditionally create the thickness buffer as well. //Render Thickness buffer. if(thickness) { m_timers["render_thickness"]->start(); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); //give the fluid some thickness everywhere glClearColor(0.1f,0.1f,0.1f,1.0f); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["thickness1"],0); //glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glClear(GL_COLOR_BUFFER_BIT); renderPointsAsSpheres( m_shaderLibrary->shaders["sphereThicknessShader"].getProgram(),posVBO, colVBO, num,settings, light,material,scale); //renderPointsAsSpheres( m_shaderLibrary->shaders["sphereShader"].getProgram(),posVBO, colVBO, num,settings, light,material,scale); glFinish(); m_timers["render_thickness"]->stop(); m_timers["blur_thickness"]->start(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["thickness2"],0); GLuint program= m_shaderLibrary->shaders["fixedWidthGaussianShader"].getProgram(); glEnable(GL_TEXTURE_2D); float xdir[] = {1.0f/height,0.0f}; float ydir[] = {0.0f,1.0f/width}; glUseProgram(program); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["thickness1"]); glUniform1i( glGetUniformLocation(program, "imgTex"),0); glUniform2fv( glGetUniformLocation(program, "dTex"),1,xdir); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); RenderUtils::fullscreenQuad(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["thickness1"],0); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["thickness2"]); glUniform2fv( glGetUniformLocation(program, "dTex"),1,ydir); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); RenderUtils::fullscreenQuad(); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDisable(GL_TEXTURE_2D); glFinish(); m_timers["blur_thickness"]->stop(); } //glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,framebuffer); m_timers["render_spheres"]->start(); //Render Color and depth buffer of spheres. glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["Color"],0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["depth"],0); glEnable(GL_TEXTURE_2D); GLuint sphereProgram = m_shaderLibrary->shaders["sphereShader"].getProgram(); glBindTexture(GL_TEXTURE_2D,sceneDepthTex); glUseProgram(sphereProgram); glUniform1i(glGetUniformLocation(sphereProgram,"sceneDepth"),0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderPointsAsSpheres(sphereProgram,posVBO, colVBO, num,settings, light,material,scale); glFinish(); m_timers["render_spheres"]->stop(); //Smooth the depth texture to emulate a surface. m_timers["smooth_depth"]->start(); //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["Color"],0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["depth2"],0); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["depth"]); currentDepthBuffer="depth2"; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); smoothDepth(settings); glFinish(); m_timers["smooth_depth"]->stop(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,m_glFramebufferTexs[currentDepthBuffer],0); //Switch to the buffer that was written to in the smoothing step if(currentDepthBuffer=="depth2") currentDepthBuffer="depth"; else currentDepthBuffer="depth2"; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs[currentDepthBuffer]); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); //if (blending) //{ //glDepthMask(GL_FALSE); // glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //} glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["normalColor"],0); m_timers["calculate_normals"]->start(); //Now we use the depth to normal shader which converts screenspace depth into //world coordinates and then computes lighting. glClear(GL_COLOR_BUFFER_BIT); GLuint normalProgram = m_shaderLibrary->shaders["depth2NormalShader"].getProgram(); glUseProgram(normalProgram); glUniform1i( glGetUniformLocation(normalProgram, "depthTex"),0); glUniform1f( glGetUniformLocation(normalProgram, "del_x"),1.0/((float)width)); glUniform1f( glGetUniformLocation(normalProgram, "del_y"),1.0/((float)height)); RenderUtils::fullscreenQuad(); glFinish(); m_timers["calculate_normals"]->stop(); m_timers["render_composite"]->start(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,m_glFramebufferTexs["Color"],0); GLuint compositeProgram = m_shaderLibrary->shaders["compositeFluidShader"].getProgram(); glUseProgram(compositeProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs[currentDepthBuffer]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["normalColor"]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["thickness1"]); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D,sceneTex); glUniform1i( glGetUniformLocation(compositeProgram, "depthTex"),0); glUniform1i( glGetUniformLocation(compositeProgram, "normalTex"),1); glUniform1i( glGetUniformLocation(compositeProgram, "thicknessTex"),2); glUniform1i( glGetUniformLocation(compositeProgram, "sceneTex"),3); glUniform1f( glGetUniformLocation(compositeProgram, "gamma"),settings->GetSettingAs<float>("thickness_gamma","0.1")); //dout<<"Here"<<endl; if(material) { glUniform3fv(glGetUniformLocation(compositeProgram,"material.diffuse"),1,&material->diffuse.x); glUniform3fv(glGetUniformLocation(compositeProgram,"material.specular"),1,&material->specular.x); glUniform3fv(glGetUniformLocation(compositeProgram,"material.ambient"),1,&material->ambient.x); glUniform1fv(glGetUniformLocation(compositeProgram,"material.shininess"),1,&material->shininess); glUniform1fv(glGetUniformLocation(compositeProgram,"material.opacity"),1,&material->opacity); } else { Material defaultMat; defaultMat.ambient=float3(0.05f,0.075f,0.25f); defaultMat.diffuse=float3(0.05f,0.075f,0.25f); defaultMat.specular=float3(1.0f,1.f,1.0f); defaultMat.opacity=0.5; defaultMat.shininess=100; glUniform3fv(glGetUniformLocation(compositeProgram,"material.diffuse"),1,&defaultMat.diffuse.x); glUniform3fv(glGetUniformLocation(compositeProgram,"material.specular"),1,&defaultMat.specular.x); glUniform3fv(glGetUniformLocation(compositeProgram,"material.ambient"),1,&defaultMat.ambient.x); glUniform1fv(glGetUniformLocation(compositeProgram,"material.shininess"),1,&defaultMat.shininess); glUniform1fv(glGetUniformLocation(compositeProgram,"material.opacity"),1,&defaultMat.opacity); } if(light) { glUniform3fv(glGetUniformLocation(compositeProgram,"light.diffuse"),1,&light->diffuse.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.specular"),1,&light->specular.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.ambient"),1,&light->ambient.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.position"),1,&light->pos.x); } else { Light defaultLight; defaultLight.ambient = float3(0.2f,0.2f,0.2f); defaultLight.diffuse = float3(1.0f,1.0f,1.0f); defaultLight.specular = float3(1.0f,1.0f,1.0f); defaultLight.pos = float3(5.0f,10.0f,-5.0f); glUniform3fv(glGetUniformLocation(compositeProgram,"light.diffuse"),1,&defaultLight.diffuse.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.specular"),1,&defaultLight.specular.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.ambient"),1,&defaultLight.ambient.x); glUniform3fv(glGetUniformLocation(compositeProgram,"light.position"),1,&defaultLight.pos.x); } RenderUtils::fullscreenQuad(); glFinish(); m_timers["render_composite"]->stop(); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,0); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D,0); //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,framebuffer); m_timers["copy_to_fbo"]->start(); glDrawBuffer(buffer); glActiveTexture(GL_TEXTURE0); GLuint copyProgram = m_shaderLibrary->shaders["copyShader"].getProgram(); glUniform1i( glGetUniformLocation(copyProgram, "colorTex"),0); if(settings->GetSettingAs<bool>("render_composite","1")) { glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["Color"]); } else if(settings->GetSettingAs<bool>("render_normal","0")) { glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["normalColor"]); copyProgram = m_shaderLibrary->shaders["copyInverseShader"].getProgram(); glUniform1i( glGetUniformLocation(copyProgram, "colorTex"),0); } else if(settings->GetSettingAs<bool>("render_depth","0")) { if(currentDepthBuffer=="depth2") glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["depth"]); else glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["depth2"]); copyProgram = m_shaderLibrary->shaders["copyDepthColorShader"].getProgram(); glUniform1i( glGetUniformLocation(copyProgram, "scalarTex"),0); } else if(settings->GetSettingAs<bool>("render_depth_smoothed","0")) { glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs[currentDepthBuffer]); copyProgram = m_shaderLibrary->shaders["copyDepthColorShader"].getProgram(); glUniform1i( glGetUniformLocation(copyProgram, "scalarTex"),0); } else if(settings->GetSettingAs<bool>("render_thickness","0")) { glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["thickness1"]); copyProgram = m_shaderLibrary->shaders["copyScalarShader"].getProgram(); glUniform1i( glGetUniformLocation(copyProgram, "scalarTex"),0); } else { glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs["Color"]); } //need to copy the contents to the back buffer. It's important that we copy the //depth as well. Otherwise anything drawn afterwards may incorrecly occlude the fluid. glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D,m_glFramebufferTexs[currentDepthBuffer]); glUseProgram(copyProgram); glUniform1i( glGetUniformLocation(copyProgram, "depthTex"),1); RenderUtils::fullscreenQuad(); glFinish(); m_timers["copy_to_fbo"]->stop(); glUseProgram(0); glBindTexture(GL_TEXTURE_2D,0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,0); //if (blending) //{ //glDisable(GL_BLEND); //} glPopAttrib(); glPopClientAttrib(); if (m_writeFramebuffers) { glFinish(); writeFramebufferTextures(); m_writeFramebuffers = false; } }
void CFactory::Update() { if (beingBuilt) { // factory under construction CUnit::Update(); return; } if (quedBuild && !opening && !stunned) { script->Activate(); groundBlockingObjectMap->OpenBlockingYard(this, curYardMap); opening = true; } if (quedBuild && inBuildStance && !stunned) { // start building a unit const float3 buildPos = CalcBuildPos(); const CSolidObject* solidObj = groundBlockingObjectMap->GroundBlocked(buildPos); if (solidObj == NULL || (dynamic_cast<const CUnit*>(solidObj) == this)) { quedBuild = false; CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team, true, buildFacing, this); b->lineage = this->lineage; if (!unitDef->canBeAssisted) { b->soloBuilder = this; b->AddDeathDependence(this); } AddDeathDependence(b); curBuild = b; script->StartBuilding(); int soundIdx = unitDef->sounds.build.getRandomIdx(); if (soundIdx >= 0) { Channels::UnitReply.PlaySample( unitDef->sounds.build.getID(soundIdx), pos, unitDef->sounds.build.getVolume(0)); } } else { helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8); } } if (curBuild && !beingBuilt) { if (!stunned) { // factory not under construction and // nanolathing unit: continue building lastBuild = gs->frameNum; // buildPiece is the rotating platform const int buildPiece = GetBuildPiece(); const CMatrix44f& mat = script->GetPieceMatrix(buildPiece); const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z // rotate unit nanoframe with platform curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535; const float3 buildPos = CalcBuildPos(buildPiece); curBuild->pos = buildPos; if (curBuild->floatOnWater) { float waterline = ground->GetHeight(buildPos.x, buildPos.z) - curBuild->unitDef->waterline; if (waterline > curBuild->pos.y) curBuild->pos.y = waterline; } curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y); const CCommandQueue& queue = commandAI->commandQue; if(!queue.empty() && (queue.front().id == CMD_WAIT)) { curBuild->AddBuildPower(0, this); } else { if (curBuild->AddBuildPower(buildSpeed, this)) { CreateNanoParticle(); } } } if (!curBuild->beingBuilt && (!unitDef->fullHealthFactory || (curBuild->health >= curBuild->maxHealth))) { if (group && curBuild->group == 0) { curBuild->SetGroup(group); } bool userOrders = true; if (curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) { userOrders = false; AssignBuildeeOrders(curBuild); waitCommandsAI.AddLocalUnit(curBuild, this); } eventHandler.UnitFromFactory(curBuild, this, userOrders); StopBuild(); } } if (((lastBuild + 200) < gs->frameNum) && !stunned && !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this, curYardMap); opening = false; script->Deactivate(); } CBuilding::Update(); }
#include "Map/Ground.h" #include "myMath.h" #include "Rendering/GL/VertexArray.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/Unsynced/BubbleProjectile.h" #include "Sim/Projectiles/Unsynced/SmokeTrailProjectile.h" #include "Sim/Units/Unit.h" #include "Sim/Weapons/WeaponDef.h" #include "TorpedoProjectile.h" #include "GlobalUnsynced.h" #ifdef TRACE_SYNC #include "Sync/SyncTracer.h" #endif CR_BIND_DERIVED(CTorpedoProjectile, CTorpedoProjectile, (float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,NULL,NULL)); CR_REG_METADATA(CTorpedoProjectile,( CR_MEMBER(tracking), CR_MEMBER(dir), CR_MEMBER(maxSpeed), CR_MEMBER(curSpeed), CR_MEMBER(areaOfEffect), CR_MEMBER(target), CR_MEMBER(nextBubble), CR_MEMBER(texx), CR_MEMBER(texy), CR_RESERVED(16) )); CTorpedoProjectile::CTorpedoProjectile(const float3& pos, const float3& speed, CUnit* owner,
void EntitiesEditor::drawContents(Renderer2D &out) const { m_view.updateVisibility(); SceneRenderer renderer(clippedRect(), m_view.pos()); { vector<int> visible_ids; visible_ids.reserve(1024); m_tile_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); for(int i = 0; i < (int)visible_ids.size(); i++) { auto &object = m_tile_map[visible_ids[i]]; int3 pos(object.bbox.min); object.ptr->addToRender(renderer, pos, Color::white); } visible_ids.clear(); m_entity_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); vector<char> selection_map(m_entity_map.size(), 0); vector<float3> old_positions(m_selected_ids.size()); for(int n = 0; n < (int)m_selected_ids.size(); n++) { selection_map[m_selected_ids[n]] = 1; visible_ids.push_back(m_selected_ids[n]); if(m_is_moving) { auto &object = m_entity_map[m_selected_ids[n]]; old_positions[n] = object.ptr->pos(); object.ptr->setPos(old_positions[n] + float3(m_move_offset)); m_entity_map.update(m_selected_ids[n]); } } sort(visible_ids.begin(), visible_ids.end()); visible_ids.resize(std::unique(visible_ids.begin(), visible_ids.end()) - visible_ids.begin()); for(int n = 0; n < (int)visible_ids.size(); n++) { auto &object = m_entity_map[visible_ids[n]]; float3 old_pos = object.ptr->pos(); bool is_selected = selection_map[visible_ids[n]]; FBox bbox = object.ptr->boundingBox(); if(object.ptr->typeId() == EntityId::trigger) { renderer.addBox(bbox, Color(Color::green, 64), true); renderer.addBox(FBox(bbox.min + float3(0.1, 0.1, 0.1), bbox.max - float3(0.1, 0.1, 0.1)), Color::green); } else { object.ptr->addToRender(renderer); } bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox, visible_ids[n]) != -1; if(is_colliding) renderer.addBox(bbox, Color::red); if(is_selected) { if(!is_colliding) renderer.addBox(bbox, Color::white); FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } } if(m_is_moving) for(int n = 0; n < (int)m_selected_ids.size(); n++) { auto &object = m_entity_map[m_selected_ids[n]]; object.ptr->setPos(old_positions[n]); m_entity_map.update(m_selected_ids[n]); } } if(m_proto && m_mode == Mode::placing) { m_proto->setPos(m_cursor_pos); m_proto->addToRender(renderer); FBox bbox = m_proto->boundingBox(); bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox) != -1; renderer.addBox(bbox, is_colliding? Color::red : Color::white); if(bbox.max.y == bbox.min.y) bbox.max.y += 1.0f; FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } renderer.render(); if(m_mode == Mode::selecting && m_is_selecting) out.addRect(m_selection - m_view.pos(), Color::white); out.setScissorRect(clippedRect()); out.setViewPos(-clippedRect().min + m_view.pos()); m_view.drawGrid(out); out.setViewPos(-clippedRect().min); auto font = res::getFont(WindowStyle::fonts[1]); font->draw(out, int2(0, clippedRect().height() - 25), {Color::white, Color::black}, format("Cursor: (%.0f, %.0f, %.0f) Grid: %d Mode: %s\n", m_cursor_pos.x, m_cursor_pos.y, m_cursor_pos.z, m_view.gridHeight(), EntitiesEditorMode::toString(m_mode))); }
bool EntitiesEditor::onMouseDrag(const InputState &state, int2 start, int2 current, int key, int is_final) { bool shift_pressed = state.isKeyPressed(InputKey::lshift); if(key == 0 && !state.isKeyPressed(InputKey::lctrl)) { computeCursor(start, current, shift_pressed); m_is_selecting = !is_final; if(m_mode == Mode::selecting && is_final && is_final != -1) { findVisible(m_selected_ids, m_selection); computeCursor(current, current, shift_pressed); } else if(m_mode == Mode::placing) { if(m_proto->typeId() == EntityId::trigger) { Trigger *trigger = static_cast<Trigger*>(m_proto.get()); if(m_trigger_mode == 0) { m_trigger_box = m_view.computeCursor(start, current, int3(1, 1, 1), m_cursor_pos.y, 0); if(state.isMouseButtonDown(InputButton::right)) { m_trigger_mode = 1; m_trigger_offset = current; } } IBox new_box = m_trigger_box; if(m_trigger_mode == 1) { int offset = screenToWorld(int2(0, m_trigger_offset.y - current.y)).y; if(offset < 0) new_box.min.y += offset; else new_box.max.y += offset; } trigger->setBox((FBox)new_box); m_cursor_pos = trigger->pos(); if(is_final > 0) { m_entity_map.add(PEntity(m_proto->clone())); } if(is_final) { m_trigger_mode = 0; trigger->setBox(FBox(0, 0, 0, 1, 1, 1) + trigger->pos()); } } else if(is_final > 0) m_entity_map.add(PEntity(m_proto->clone())); } return true; } else if(key == 1 && m_mode == Mode::selecting) { if(!m_is_moving) { m_is_moving_vertically = state.isKeyPressed(InputKey::lshift); m_is_moving = true; } if(m_is_moving_vertically) m_move_offset = int3(0, screenToWorld(int2(0, start.y - current.y)).y, 0); else m_move_offset = asXZY(screenToWorld(current - start), 0); if(is_final) m_is_moving = false; if(is_final > 0) { for(int n = 0; n < (int)m_selected_ids.size(); n++) { auto &object = m_entity_map[m_selected_ids[n]]; object.ptr->setPos(object.ptr->pos() + float3(m_move_offset)); m_entity_map.update(m_selected_ids[n]); } } return true; } return false; }
CONST_WIN32 float3 float3x4::Diagonal() const { return float3(v[0][0], v[1][1], v[2][2]); }
void GetTrianglesFromMesh(Ogre::Mesh* mesh, std::vector<float3>& dest) { dest.clear(); try { for(uint i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertices = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); size_t vertexSize = vbuf->getVertexSize(); float* pReal = 0; Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; u32* pLong = static_cast<u32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); u16* pShort = reinterpret_cast<u16*>(pLong); bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); if (use32bitindexes) { for(size_t k = 0; k < numTris * 3; k += 3) { uint i1 = pLong[k]; uint i2 = pLong[k+1]; uint i3 = pLong[k+2]; posElem->baseVertexPointerToElement(vertices + i1 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i2 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i3 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); } } else { for(size_t k = 0; k < numTris * 3; k += 3) { uint i1 = pShort[k]; uint i2 = pShort[k+1]; uint i3 = pShort[k+2]; posElem->baseVertexPointerToElement(vertices + i1 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i2 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i3 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); } } vbuf->unlock(); ibuf->unlock(); } } catch(Ogre::Exception &e) { ///\todo Fix Ogre to not allow meshes like this to be successfully created. LogError("GetTrianglesFromMesh failed for mesh! Ogre threw an exception: " + QString(e.what())); dest.clear(); } }
void CBasicMapDamage::RecalcArea(int x1, int x2, int y1, int y2) { for(int y=y1;y<y2;y++){ for(int x=x1;x<x2;x++){ float height=readmap->heightmap[(y)*(gs->mapx+1)+x]; height+=readmap->heightmap[(y)*(gs->mapx+1)+x+1]; height+=readmap->heightmap[(y+1)*(gs->mapx+1)+x]; height+=readmap->heightmap[(y+1)*(gs->mapx+1)+x+1]; readmap->centerheightmap[y*gs->mapx+x]=height*0.25; } } int hy2=min(gs->hmapy-1,y2/2); int hx2=min(gs->hmapx-1,x2/2); for(int y=y1/2;y<=hy2;y++){ for(int x=x1/2;x<=hx2;x++){ readmap->halfHeightmap[y*gs->hmapx+x]=readmap->heightmap[(y*2+1)*(gs->mapx+1)+(x*2+1)]; } } float3 n1,n2,n3,n4; int decy=max(0,y1-1); int incy=min(gs->mapy-1,y2+1); int decx=max(0,x1-1); int incx=min(gs->mapx-1,x2+1); for(int y=decy;y<=incy;y++){ for(int x=decx;x<=incx;x++){ float3 e1(-SQUARE_SIZE,readmap->heightmap[y*(gs->mapx+1)+x]-readmap->heightmap[y*(gs->mapx+1)+x+1],0); float3 e2( 0,readmap->heightmap[y*(gs->mapx+1)+x]-readmap->heightmap[(y+1)*(gs->mapx+1)+x],-SQUARE_SIZE); float3 n=e2.cross(e1); n.Normalize(); readmap->facenormals[(y*gs->mapx+x)*2]=n; e1=float3( SQUARE_SIZE,readmap->heightmap[(y+1)*(gs->mapx+1)+x+1]-readmap->heightmap[(y+1)*(gs->mapx+1)+x],0); e2=float3( 0,readmap->heightmap[(y+1)*(gs->mapx+1)+x+1]-readmap->heightmap[(y)*(gs->mapx+1)+x+1],SQUARE_SIZE); n=e2.cross(e1); n.Normalize(); readmap->facenormals[(y*gs->mapx+x)*2+1]=n; } } for(int y=max(2,(y1&0xfffffe));y<=min(gs->mapy-3,y2);y+=2){ for(int x=max(2,(x1&0xfffffe));x<=min(gs->mapx-3,x2);x+=2){ float3 e1(-SQUARE_SIZE*4,readmap->heightmap[(y-1)*(gs->mapx+1)+x-1]-readmap->heightmap[(y-1)*(gs->mapx+1)+x+3],0); float3 e2( 0,readmap->heightmap[(y-1)*(gs->mapx+1)+x-1]-readmap->heightmap[(y+3)*(gs->mapx+1)+x-1],-SQUARE_SIZE*4); float3 n=e2.cross(e1); n.Normalize(); e1=float3( SQUARE_SIZE*4,readmap->heightmap[(y+3)*(gs->mapx+1)+x+3]-readmap->heightmap[(y+3)*(gs->mapx+1)+x-1],0); e2=float3( 0,readmap->heightmap[(y+3)*(gs->mapx+1)+x+3]-readmap->heightmap[(y-1)*(gs->mapx+1)+x+3],SQUARE_SIZE*4); float3 n2=e2.cross(e1); n2.Normalize(); readmap->slopemap[(y/2)*gs->hmapx+(x/2)]=1-(n.y+n2.y)*0.5; } } pathManager->TerrainChange(x1,y1,x2,y2); featureHandler->TerrainChanged(x1,y1,x2,y2); readmap->HeightmapUpdated(x1,x2,y1,y2); decy=max(0,(y1*SQUARE_SIZE-QUAD_SIZE/2)/QUAD_SIZE); incy=min(qf->numQuadsZ-1,(y2*SQUARE_SIZE+QUAD_SIZE/2)/QUAD_SIZE); decx=max(0,(x1*SQUARE_SIZE-QUAD_SIZE/2)/QUAD_SIZE); incx=min(qf->numQuadsX-1,(x2*SQUARE_SIZE+QUAD_SIZE/2)/QUAD_SIZE); for(int y=decy;y<=incy;y++){ for(int x=decx;x<=incx;x++){ if(inRelosQue[y*qf->numQuadsX+x]) continue; RelosSquare rs; rs.x=x; rs.y=y; rs.neededUpdate=gs->frameNum; rs.numUnits=qf->baseQuads[y*qf->numQuadsX+x].units.size(); relosSize+=rs.numUnits; inRelosQue[y*qf->numQuadsX+x]=true; relosQue.push_back(rs); } } }
void PVScene::draw(int x, int y, int w, int h) { static float time = 0.0f; time += 0.01f; viewMatrix = lookAtLH(float3(cosf(time) * 5, 2, sinf(time) * 5), float3(0, 0, 0), float3(0, 1, 0)); float4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(vertexArray); shader->bind(); GLuint viewProjectionLocation = shader->getUniformLocation("viewProjection"); glUniformMatrix4fv(viewProjectionLocation, 1, true, &viewProjectionMatrix.m[0][0]); GLuint lightColorLocation = shader->getUniformLocation("lightColor"); GLuint lightPositionLocation = shader->getUniformLocation("lightPosition"); GLuint numLightsLocation = shader->getUniformLocation("numLights"); float lightPositions[3 * 4]; float lightColors[3 * 4]; int numLights = lights.size(); if (numLights > 4) numLights = 4; for (int i = 0; i < numLights; i++) { PVLight *light = lights[i]; float3 lightPosition = light->getPosition(); float3 lightColor = light->getColor(); lightPositions[i * 3 + 0] = lightPosition.x; lightPositions[i * 3 + 1] = lightPosition.y; lightPositions[i * 3 + 2] = lightPosition.z; lightColors[i * 3 + 0] = lightColor.x; lightColors[i * 3 + 1] = lightColor.y; lightColors[i * 3 + 2] = lightColor.z; } glUniform3fv(lightPositionLocation, numLights, lightPositions); glUniform3fv(lightColorLocation, numLights, lightColors); glUniform1i(numLightsLocation, numLights); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CW); glViewport(x, y, w, h); for (PVMesh *mesh : meshes) mesh->draw(shader); glDisable(GL_CULL_FACE); glActiveTexture(GL_TEXTURE0); glDisable(GL_DEPTH_TEST); glUseProgram(0); glBindVertexArray(0); GLCHECK(); }
void CFactory::Update() { if (beingBuilt) { // factory under construction CUnit::Update(); return; } if (quedBuild && !opening && !stunned) { cob->Call(COBFN_Activate); groundBlockingObjectMap->OpenBlockingYard(this, yardMap); opening = true; } if (quedBuild && inBuildStance && !stunned) { // start building a unit float3 buildPos = CalcBuildPos(); bool canBuild = true; std::vector<CUnit*> units = qf->GetUnitsExact(buildPos, 16); for (std::vector<CUnit*>::iterator ui = units.begin(); ui != units.end(); ++ui) { if ((*ui) != this) canBuild = false; } if (canBuild) { quedBuild = false; CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team, true, buildFacing, this); b->lineage = this->lineage; if (!unitDef->canBeAssisted) { b->soloBuilder = this; b->AddDeathDependence(this); } AddDeathDependence(b); curBuild = b; cob->Call("StartBuilding"); int soundIdx = unitDef->sounds.build.getRandomIdx(); if (soundIdx >= 0) { sound->PlaySample( unitDef->sounds.build.getID(soundIdx), pos, unitDef->sounds.build.getVolume(0)); } } else { helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8); } } if (curBuild && !beingBuilt) { if (!stunned) { // factory not under construction and // nanolathing unit: continue building lastBuild = gs->frameNum; // buildPiece is the rotating platform const int buildPiece = GetBuildPiece(); CMatrix44f mat = localmodel->GetPieceMatrix(buildPiece); const int h = GetHeadingFromVector(mat[2], mat[10]); // rotate unit nanoframe with platform curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535; const float3 buildPos = CalcBuildPos(buildPiece); curBuild->pos = buildPos; if (curBuild->floatOnWater) { curBuild->pos.y = ground->GetHeight(buildPos.x, buildPos.z); curBuild->pos.y -= curBuild->unitDef->waterline; } curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y); const CCommandQueue& queue = commandAI->commandQue; if(!queue.empty() && (queue.front().id == CMD_WAIT)) { curBuild->AddBuildPower(0, this); } else { if (curBuild->AddBuildPower(buildSpeed, this)) { CreateNanoParticle(); } } } if (!curBuild->beingBuilt && (!unitDef->fullHealthFactory || (curBuild->health >= curBuild->maxHealth))) { if (group && curBuild->group == 0) { curBuild->SetGroup(group); } bool userOrders = true; if (curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) { userOrders = false; const CFactoryCAI* facAI = (CFactoryCAI*) commandAI; const CCommandQueue& newUnitCmds = facAI->newUnitCommands; if (newUnitCmds.empty()) { SendToEmptySpot(curBuild); } else { // XXX the pathfinder sometimes... makes mistakes, try to hack around it // XXX note this qualifies as HACK HACK HACK float3 testpos = curBuild->pos + frontdir * (this->radius - 1.0f); Command c; c.id = CMD_MOVE; c.params.push_back(testpos.x); c.params.push_back(testpos.y); c.params.push_back(testpos.z); curBuild->commandAI->GiveCommand(c); for (CCommandQueue::const_iterator ci = newUnitCmds.begin(); ci != newUnitCmds.end(); ++ci) { c = *ci; c.options |= SHIFT_KEY; curBuild->commandAI->GiveCommand(c); } } waitCommandsAI.AddLocalUnit(curBuild, this); } luaCallIns.UnitFromFactory(curBuild, this, userOrders); StopBuild(); } } if (((lastBuild + 200) < gs->frameNum) && !stunned && !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this, yardMap); opening = false; cob->Call(COBFN_Deactivate); } CBuilding::Update(); }
bool CFeature::Update(void) { bool finishedUpdate = true; finishedUpdate = UpdatePosition(); if (emitSmokeTime != 0) { --emitSmokeTime; if (!((gs->frameNum + id) & 3) && ph->particleSaturation < 0.7f) { new CSmokeProjectile(midPos + gu->usRandVector() * radius * 0.3f, gu->usRandVector() * 0.3f + UpVector, emitSmokeTime / 6 + 20, 6, 0.4f, 0, 0.5f); } if (emitSmokeTime > 0) finishedUpdate = false; } if (fireTime > 0) { fireTime--; if (fireTime == 1) featureHandler->DeleteFeature(this); finishedUpdate = false; } if (def->geoThermal) { if ((gs->frameNum + id % 5) % 5 == 0) { // Find the unit closest to the geothermal const vector<CSolidObject*> &objs = qf->GetSolidsExact(pos, 0.0f); float bestDist2 = 0; CSolidObject* so = NULL; for (vector<CSolidObject*>::const_iterator oi = objs.begin(); oi != objs.end(); ++oi) { float dist2 = ((*oi)->pos - pos).SqLength(); if (!so || dist2 < bestDist2) { bestDist2 = dist2; so = *oi; } } if (so != solidOnTop) { if (solidOnTop) DeleteDeathDependence(solidOnTop); if (so) AddDeathDependence(so); } solidOnTop = so; } // Hide the smoke if there is a geothermal unit on the vent CUnit *u = dynamic_cast<CUnit*>(solidOnTop); if (!u || !u->unitDef->needGeo) { if ((ph->particleSaturation < 0.7f) || (ph->particleSaturation < 1 && !(gs->frameNum & 3))) { float3 speed = gu->usRandVector() * 0.5f; speed.y += 2.0f; new CGeoThermSmokeProjectile(gu->usRandVector() * 10 + float3(pos.x, pos.y-10, pos.z), speed, int(50 + gu->usRandFloat() * 7), this); } } finishedUpdate = false; } return !finishedUpdate; }
void CTorpedoProjectile::Update() { // tracking only works when we are underwater if (!weaponDef->submissile && pos.y > 0.0f) { if (!luaMoveCtrl) { // must update dir and speed.w here SetVelocityAndSpeed(speed + (UpVector * mygravity)); } } else { if (--ttl > 0) { if (!luaMoveCtrl) { float3 targetVel; if (speed.w < maxSpeed) speed.w += std::max(0.2f, tracking); if (target != NULL) { const CSolidObject* so = dynamic_cast<const CSolidObject*>(target); const CWeaponProjectile* po = dynamic_cast<const CWeaponProjectile*>(target); targetPos = target->pos; if (so != NULL) { targetPos = so->aimPos; targetVel = so->speed; if (owner() != NULL && pos.SqDistance(so->aimPos) > Square(150.0f)) { const CUnit* u = dynamic_cast<const CUnit*>(so); if (u != NULL) { targetPos = u->GetErrorPos(owner()->allyteam, true); } } } if (po != NULL) { targetVel = po->speed; } } if (!weaponDef->submissile && targetPos.y > 0.0f) { targetPos.y = 0.0f; } const float3 targetLeadVec = targetVel * (pos.distance(targetPos) / maxSpeed) * 0.7f; const float3 targetLeadDir = (targetPos + targetLeadVec - pos).Normalize(); float3 targetDirDif = targetLeadDir - dir; if (targetDirDif.Length() < tracking) { dir = targetLeadDir; } else { // <tracking> is the projectile's turn-rate targetDirDif = (targetDirDif - (dir * targetDirDif.dot(dir))).SafeNormalize(); dir = (dir + (targetDirDif * tracking)).SafeNormalize(); } // do not need to update dir or speed.w here CWorldObject::SetVelocity(dir * speed.w); } explGenHandler->GenExplosion(cegID, pos, speed, ttl, areaOfEffect, 0.0f, NULL, NULL); } else { if (!luaMoveCtrl) { // must update dir and speed.w here SetVelocityAndSpeed((speed * 0.98f) + (UpVector * mygravity)); } } } if (!luaMoveCtrl) { SetPosition(pos + speed); } if (pos.y < -2.0f) { --nextBubble; if (nextBubble == 0) { nextBubble = 1 + (int) (gs->randFloat() * 1.5f); const float3 pspeed = (gs->randVector() * 0.1f) + float3(0.0f, 0.2f, 0.0f); new CBubbleProjectile( owner(), pos + gs->randVector(), pspeed, 40 + gs->randFloat() * GAME_SPEED, 1 + gs->randFloat() * 2, 0.01f, 0.3f + gs->randFloat() * 0.3f ); } } UpdateGroundBounce(); UpdateInterception(); }
#include "StdAfx.h" #include "mmgr.h" #include "Game/Camera.h" #include "MuzzleFlame.h" #include "Rendering/GL/VertexArray.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "System/GlobalUnsynced.h" CR_BIND_DERIVED(CMuzzleFlame, CProjectile, (float3(0,0,0),float3(0,0,0),float3(0,0,0),0)); CR_REG_METADATA(CMuzzleFlame,( CR_SERIALIZER(creg_Serialize), // randSmokeDir CR_MEMBER(dir), CR_MEMBER(size), CR_MEMBER(age), CR_MEMBER(numFlame), CR_MEMBER(numSmoke), CR_MEMBER(randSmokeDir), CR_RESERVED(8) )); void CMuzzleFlame::creg_Serialize(creg::ISerializer& s) { // s.Serialize(randSmokeDir, numSmoke*sizeof(float3)); } CMuzzleFlame::CMuzzleFlame(const float3& pos,const float3& speed,const float3& dir,float size GML_PARG_C) : CProjectile(pos,speed,0, false GML_PARG_P), size(size),
void CFeature::Initialize(const FeatureLoadParams& params) { def = params.featureDef; udef = params.unitDef; id = params.featureID; team = params.teamID; allyteam = params.allyTeamID; heading = params.heading; buildFacing = params.facing; smokeTime = params.smokeTime; mass = def->mass; health = def->health; maxHealth = def->health; resources = SResourcePack(def->metal, def->energy); crushResistance = def->crushResistance; xsize = ((buildFacing & 1) == 0) ? def->xsize : def->zsize; zsize = ((buildFacing & 1) == 1) ? def->xsize : def->zsize; noSelect = !def->selectable; // by default, any feature that is a dead unit can move // in all dimensions; all others (trees, rocks, ...) can // only move vertically and also do not allow velocity to // build in XZ // (movementMask exists mostly for trees, which depend on // speed for falling animations but should never actually // *move* in XZ, so their velocityMask *does* include XZ) moveCtrl.SetMovementMask(mix(OnesVector, UpVector, udef == nullptr )); moveCtrl.SetVelocityMask(mix(OnesVector, UpVector, udef == nullptr && def->drawType < DRAWTYPE_TREE)); // set position before mid-position Move((params.pos).cClampInMap(), false); // use base-class version, AddFeature() below // will already insert us in the update-queue CWorldObject::SetVelocity(params.speed); switch (def->drawType) { case DRAWTYPE_NONE: { } break; case DRAWTYPE_MODEL: { if ((model = def->LoadModel()) != NULL) { SetMidAndAimPos(model->relMidPos, model->relMidPos, true); SetRadiusAndHeight(model); // only initialize the LM for modelled features // (this is still never animated but allows for // custom piece display-lists, etc) localModel.SetModel(model); } else { LOG_L(L_ERROR, "[%s] couldn't load model for %s", __FUNCTION__, def->name.c_str()); } } break; default: { // always >= DRAWTYPE_TREE here // LoadFeaturesFromMap() doesn't set a scale for trees SetMidAndAimPos(UpVector * TREE_RADIUS, UpVector * TREE_RADIUS, true); SetRadiusAndHeight(TREE_RADIUS, TREE_RADIUS * 2.0f); drawPos = pos; drawMidPos = midPos; } break; } UpdateMidAndAimPos(); UpdateTransformAndPhysState(); collisionVolume = def->collisionVolume; if (collisionVolume.DefaultToSphere()) collisionVolume.InitSphere(radius); if (collisionVolume.DefaultToFootPrint()) collisionVolume.InitBox(float3(xsize * SQUARE_SIZE, height, zsize * SQUARE_SIZE)); // feature does not have an assigned ID yet // this MUST be done before the Block() call featureHandler->AddFeature(this); quadField->AddFeature(this); ChangeTeam(team); UpdateCollidableStateBit(CSolidObject::CSTATE_BIT_SOLIDOBJECTS, def->collidable); Block(); // allow Spring.SetFeatureBlocking to be called from gadget:FeatureCreated // (callin sees the complete default state, but can change any part of it) eventHandler.FeatureCreated(this); eventHandler.RenderFeatureCreated(this); }
MultiResSILLayer::MultiResSILLayer() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); RenderDeviceCaps const & caps = re.DeviceCaps(); { rl_quad_ = rf.MakeRenderLayout(); rl_quad_->TopologyType(RenderLayout::TT_TriangleStrip); std::vector<float3> pos; std::vector<uint16_t> index; pos.push_back(float3(+1, +1, 1)); pos.push_back(float3(-1, +1, 1)); pos.push_back(float3(+1, -1, 1)); pos.push_back(float3(-1, -1, 1)); ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(pos.size() * sizeof(pos[0])); init_data.slice_pitch = 0; init_data.data = &pos[0]; rl_quad_->BindVertexStream(rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data), make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); } vpl_tex_ = rf.MakeTexture2D(VPL_COUNT, 4, 1, 1, EF_ABGR16F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); gbuffer_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); depth_derivate_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "DepthDerivateMipMap"); gbuffer_to_normal_cone_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2NormalCone"); normal_cone_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "NormalConeMipMap"); RenderEffectPtr subsplat_stencil_effect = SyncLoadRenderEffect("MultiRes.fxml"); subsplat_stencil_tech_ = subsplat_stencil_effect->TechniqueByName("SetSubsplatStencil"); subsplat_cur_lower_level_param_ = subsplat_stencil_effect->ParameterByName("cur_lower_level"); subsplat_is_not_first_last_level_param_ = subsplat_stencil_effect->ParameterByName("is_not_first_last_level"); subsplat_depth_deriv_tex_param_ = subsplat_stencil_effect->ParameterByName("depth_deriv_tex"); subsplat_normal_cone_tex_param_ = subsplat_stencil_effect->ParameterByName("normal_cone_tex"); subsplat_depth_normal_threshold_param_ = subsplat_stencil_effect->ParameterByName("depth_normal_threshold"); RenderEffectPtr vpls_lighting_effect = SyncLoadRenderEffect("VPLsLighting.fxml"); vpls_lighting_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingInstanceID"); vpls_lighting_no_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingNoInstanceID"); vpl_view_param_ = vpls_lighting_effect->ParameterByName("view"); vpl_proj_param_ = vpls_lighting_effect->ParameterByName("proj"); vpl_depth_near_far_invfar_param_ = vpls_lighting_effect->ParameterByName("depth_near_far_invfar"); vpl_light_pos_es_param_ = vpls_lighting_effect->ParameterByName("light_pos_es"); vpl_light_color_param_ = vpls_lighting_effect->ParameterByName("light_color"); vpl_light_falloff_param_ = vpls_lighting_effect->ParameterByName("light_falloff"); vpl_x_coord_param_ = vpls_lighting_effect->ParameterByName("x_coord"); vpl_gbuffer_tex_param_ = vpls_lighting_effect->ParameterByName("gbuffer_tex"); vpl_depth_tex_param_ = vpls_lighting_effect->ParameterByName("depth_tex"); *(vpls_lighting_effect->ParameterByName("vpls_tex")) = vpl_tex_; *(vpls_lighting_effect->ParameterByName("vpl_params")) = float2(1.0f / VPL_COUNT, 0.5f / VPL_COUNT); upsampling_pp_ = SyncLoadPostProcess("MultiRes.ppml", "Upsampling"); rl_vpl_ = SyncLoadModel("indirect_light_proxy.meshml", EAH_GPU_Read | EAH_Immutable, CreateModelFactory<RenderModel>(), CreateMeshFactory<StaticMesh>())->Mesh(0)->GetRenderLayout(); if (caps.instance_id_support) { rl_vpl_->NumInstances(VPL_COUNT); } }
#include "StdAfx.h" #include "GenericParticleProjectile.h" #include "GlobalStuff.h" #include "Rendering/GL/VertexArray.h" #include "Game/Camera.h" #include "ProjectileHandler.h" #include "Rendering/Textures/ColorMap.h" CR_BIND_DERIVED(CGenericParticleProjectile, CProjectile, (float3(0,0,0),float3(0,0,0),NULL)); CR_REG_METADATA(CGenericParticleProjectile,( CR_MEMBER(gravity), CR_MEMBER(texture), CR_MEMBER(colorMap), CR_MEMBER(directional), CR_MEMBER(life), CR_MEMBER(decayrate), CR_MEMBER(size), CR_MEMBER(airdrag), CR_MEMBER(sizeGrowth), CR_MEMBER(sizeMod) )); CGenericParticleProjectile::CGenericParticleProjectile(const float3& pos,const float3& speed,CUnit* owner) : CProjectile(pos, speed, owner, false) { deleteMe=false; checkCol=false; useAirLos=true; }
bool CubeMapHandler::Init() { specTexSize = configHandler->Get("CubeTexSizeSpecular", 128); reflTexSize = configHandler->Get("CubeTexSizeReflection", 128); specTexBuf = new unsigned char[specTexSize * 4]; mapSkyReflections = !(mapInfo->smf.skyReflectModTexName.empty()); { glGenTextures(1, &specularTexID); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, specularTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, specTexSize, float3( 1, 1, 1), float3( 0, 0, -2), float3(0, -2, 0)); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, specTexSize, float3(-1, 1, -1), float3( 0, 0, 2), float3(0, -2, 0)); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, specTexSize, float3(-1, 1, -1), float3( 2, 0, 0), float3(0, 0, 2)); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, specTexSize, float3(-1, -1, 1), float3( 2, 0, 0), float3(0, 0, -2)); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, specTexSize, float3(-1, 1, 1), float3( 2, 0, 0), float3(0, -2, 0)); CreateSpecularFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, specTexSize, float3( 1, 1, -1), float3(-2, 0, 0), float3(0, -2, 0)); } { glGenTextures(1, &envReflectionTexID); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, envReflectionTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } if (mapSkyReflections) { glGenTextures(1, &skyReflectionTexID); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, skyReflectionTexID); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } if (reflectionCubeFBO.IsValid()) { reflectionCubeFBO.Bind(); reflectionCubeFBO.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT, reflTexSize, reflTexSize); reflectionCubeFBO.Unbind(); } if (!reflectionCubeFBO.IsValid()) { Free(); return false; } return true; }
void CStartPosSelecter::Draw() { if(gu->spectating){ delete this; return; } glPushMatrix(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glColor4f(0.2f,0.8f,0.2f,0.5f); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glBegin(GL_QUADS); float by=gameSetup->startRectTop[gu->myAllyTeam]*gs->mapy*8; float bx=gameSetup->startRectLeft[gu->myAllyTeam]*gs->mapx*8; float dy=(gameSetup->startRectBottom[gu->myAllyTeam]-gameSetup->startRectTop[gu->myAllyTeam])*gs->mapy*8/10; float dx=(gameSetup->startRectRight[gu->myAllyTeam]-gameSetup->startRectLeft[gu->myAllyTeam])*gs->mapx*8/10; for(int a=0;a<10;++a){ //draw start rect restrictions float3 pos1(bx+a*dx,0,by); pos1.y=ground->GetHeight(pos1.x,pos1.z); float3 pos2(bx+(a+1)*dx,0,by); pos2.y=ground->GetHeight(pos2.x,pos2.z); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2+UpVector*100); glVertexf3(pos1+UpVector*100); pos1=float3(bx+a*dx,0,by+dy*10); pos1.y=ground->GetHeight(pos1.x,pos1.z); pos2=float3(bx+(a+1)*dx,0,by+dy*10); pos2.y=ground->GetHeight(pos2.x,pos2.z); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2+UpVector*100); glVertexf3(pos1+UpVector*100); pos1=float3(bx,0,by+dy*a); pos1.y=ground->GetHeight(pos1.x,pos1.z); pos2=float3(bx,0,by+dy*(a+1)); pos2.y=ground->GetHeight(pos2.x,pos2.z); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2+UpVector*100); glVertexf3(pos1+UpVector*100); pos1=float3(bx+dx*10,0,by+dy*a); pos1.y=ground->GetHeight(pos1.x,pos1.z); pos2=float3(bx+dx*10,0,by+dy*(a+1)); pos2.y=ground->GetHeight(pos2.x,pos2.z); glVertexf3(pos1); glVertexf3(pos2); glVertexf3(pos2+UpVector*100); glVertexf3(pos1+UpVector*100); } glEnd(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glDisable(GL_DEPTH_TEST); float mx=float(mouse->lastx)/gu->viewSizeX; float my=(gu->viewSizeY-float(mouse->lasty))/gu->viewSizeY; glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); if (!showReady) { return; } if (InBox(mx, my, readyBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); } else { glColor4f(0.7f, 0.7f, 0.2f, guiAlpha); } DrawBox(readyBox); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (InBox(mx, my, readyBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); } else { glColor4f(0.7f, 0.7f, 0.2f, guiAlpha); } DrawBox(readyBox); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const float width = font->CalcTextWidth("Ready"); const float yDiff = (readyBox.y2 - readyBox.y1); const float xDiff = (readyBox.x2 - readyBox.x1); const float yScale = 0.8f * yDiff; const float xScale = 0.8f * (xDiff / width); const float xPixel = 1.0f / (xScale * (float)gu->viewSizeX); const float yPixel = 1.0f / (yScale * (float)gu->viewSizeY); const float yPos = readyBox.y1 + (0.1f * yDiff); const float xPos = readyBox.x1 + (0.1f * xDiff); glPushMatrix(); glTranslatef(xPos, yPos, 0.0f); glScalef(xScale, yScale, 1.0f); const float dark[4] = { 0.2f, 0.2f, 0.2f, 0.8f }; const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; font->glPrintOutlined("Ready", xPixel, yPixel, white, dark); glPopMatrix(); }
float3 float3x4::GetScale() const { return float3(Col(0).Length(), Col(1).Length(), Col(2).Length()); }
void CTorpedoProjectile::Update() { if (!weaponDef->submissile && pos.y > -3.0f) { // tracking etc only works when we are underwater if (!luaMoveCtrl) { speed.y += mygravity; dir.y = std::min(dir.y, 0.0f); dir = speed; dir.Normalize(); } } else { if (!weaponDef->submissile && pos.y-speed.y > -3.0f) { // level out torpedo a bit when hitting water if (!luaMoveCtrl) { dir.y *= 0.5f; dir.Normalize(); } } if (--ttl > 0) { if (!luaMoveCtrl) { if (curSpeed < maxSpeed) { curSpeed += std::max(0.2f, tracking); } if (target) { float3 targPos; if ((target->midPos - pos).SqLength() < 150 * 150 || !owner()) { targPos = target->midPos; } else { targPos = helper->GetUnitErrorPos(target, owner()->allyteam); } if (!weaponDef->submissile && targPos.y > 0) { targPos.y = 0; } float dist = targPos.distance(pos); float3 dif = (targPos + target->speed * (dist / maxSpeed) * 0.7f - pos).Normalize(); float3 dif2 = dif - dir; if (dif2.Length() < tracking) { dir = dif; } else { dif2 -= dir * (dif2.dot(dir)); dif2.SafeNormalize(); dir += dif2 * tracking; dir.SafeNormalize(); } } speed = dir * curSpeed; } gCEG->Explosion(cegID, pos, ttl, areaOfEffect, NULL, 0.0f, NULL, speed); } else { if (!luaMoveCtrl) { speed *= 0.98f; speed.y += mygravity; dir = speed; dir.SafeNormalize(); } } } if (!luaMoveCtrl) { pos += speed; } if (pos.y < -2.0f) { --nextBubble; if (nextBubble == 0) { nextBubble = 1 + (int) (gs->randFloat() * 1.5f); const float3 pspeed = (gs->randVector() * 0.1f) + float3(0.0f, 0.2f, 0.0f); new CBubbleProjectile( pos + gs->randVector(), pspeed, 40 + gs->randFloat() * 30, 1 + gs->randFloat() * 2, 0.01f, owner(), 0.3f + gs->randFloat() * 0.3f ); } } UpdateGroundBounce(); }
void CollisionVolume::Init(float r) { // <r> is the object's default RADIUS (not its diameter), // so we need to double it to get the full-length scales Init(float3(r * 2.0f, r * 2.0f, r * 2.0f), ZeroVector, volumeType, testType, primaryAxis); }