void Ship::Render(Graphics::Renderer *renderer, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { if (IsDead()) return; //angthrust negated, for some reason GetModel()->SetThrust(vector3f(m_thrusters), -vector3f(m_angThrusters)); matrix3x3f mt; matrix3x3dtof(viewTransform.Inverse().GetOrient(), mt); s_heatGradientParams.heatingMatrix = mt; s_heatGradientParams.heatingNormal = vector3f(GetVelocity().Normalized()); s_heatGradientParams.heatingAmount = Clamp(GetHullTemperature(),0.0,1.0); // This has to be done per-model with a shield and just before it's rendered const bool shieldsVisible = m_shieldCooldown > 0.01f && m_stats.shield_mass_left > (m_stats.shield_mass / 100.0f); GetShields()->SetEnabled(shieldsVisible); GetShields()->Update(m_shieldCooldown, 0.01f*GetPercentShields()); //strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText)); RenderModel(renderer, camera, viewCoords, viewTransform); m_navLights->Render(renderer); renderer->GetStats().AddToStatCount(Graphics::Stats::STAT_SHIPS, 1); if (m_ecmRecharge > 0.0f) { // ECM effect: a cloud of particles for a sparkly effect vector3f v[100]; for (int i=0; i<100; i++) { const double r1 = Pi::rng.Double()-0.5; const double r2 = Pi::rng.Double()-0.5; const double r3 = Pi::rng.Double()-0.5; v[i] = vector3f(GetPhysRadius()*vector3d(r1, r2, r3).NormalizedSafe()); } Color c(128,128,255,255); float totalRechargeTime = GetECMRechargeTime(); if (totalRechargeTime >= 0.0f) { c.a = (m_ecmRecharge / totalRechargeTime) * 255; } SfxManager::ecmParticle->diffuse = c; matrix4x4f t; for (int i=0; i<12; i++) t[i] = float(viewTransform[i]); t[12] = viewCoords.x; t[13] = viewCoords.y; t[14] = viewCoords.z; t[15] = 1.0f; renderer->SetTransform(t); renderer->DrawPointSprites(100, v, SfxManager::additiveAlphaState, SfxManager::ecmParticle.get(), 50.f); } }
/* * Collide one edgeNode (all edges below it) of this Geom with the triangle * BVH of another geom (b), starting from btriNode. */ void Geom::CollideEdgesTris(int &maxContacts, const BVHNode *edgeNode, const matrix4x4d &transToB, Geom *b, const BVHNode *btriNode, void (*callback)(CollisionContact*)) { if (maxContacts <= 0) return; if (edgeNode->triIndicesStart) { const GeomTree::Edge *edges = this->GetGeomTree()->GetEdges(); int numContacts = 0; vector3f dir; isect_t isect; for (int i=0; i<edgeNode->numTris; i++) { int vtxNum = edges[ edgeNode->triIndicesStart[i] ].v1i; vector3d v1 = transToB * vector3d(&GetGeomTree()->m_vertices[vtxNum]); vector3f _from((float)v1.x, (float)v1.y, (float)v1.z); vector3d _dir( (double)edges[ edgeNode->triIndicesStart[i] ].dir.x, (double)edges[ edgeNode->triIndicesStart[i] ].dir.y, (double)edges[ edgeNode->triIndicesStart[i] ].dir.z); _dir = transToB.ApplyRotationOnly(_dir); dir = vector3f(&_dir.x); isect.dist = edges[ edgeNode->triIndicesStart[i] ].len; isect.triIdx = -1; b->GetGeomTree()->TraceRay(btriNode, _from, dir, &isect); if (isect.triIdx == -1) continue; numContacts++; const double depth = edges[ edgeNode->triIndicesStart[i] ].len - isect.dist; // in world coords CollisionContact contact; contact.pos = b->GetTransform() * (v1 + vector3d(&dir.x)*(double)isect.dist); vector3f n = b->m_geomtree->GetTriNormal(isect.triIdx); contact.normal = vector3d(n.x, n.y, n.z); contact.normal = b->GetTransform().ApplyRotationOnly(contact.normal); contact.dist = isect.dist; contact.depth = depth; contact.triIdx = isect.triIdx; contact.userData1 = m_data; contact.userData2 = b->m_data; // contact geomFlag is bitwise OR of triangle's and edge's flags contact.geomFlag = b->m_geomtree->GetTriFlag(isect.triIdx) | edges[ edgeNode->triIndicesStart[i] ].triFlag; callback(&contact); if (--maxContacts <= 0) return; } } else { CollideEdgesTris(maxContacts, edgeNode->kids[0], transToB, b, btriNode, callback); CollideEdgesTris(maxContacts, edgeNode->kids[1], transToB, b, btriNode, callback); } }
void Geom::MoveTo(const matrix4x4d &m) { m_orient = m; m_invOrient = m.InverseOf(); }
void Frame::GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m) { matrix3x3d forient = fFrom->GetOrientRelTo(fTo); vector3d fpos = fFrom->GetPositionRelTo(fTo); m = forient; m.SetTranslate(fpos); }
void Geom::MoveTo(const matrix4x4d &m) { PROFILE_SCOPED() m_orient = m; m_invOrient = m.Inverse(); }