// Trace a line through the world to simulate, eg, a bullet http://www.youtube.com/watch?v=USjbg5QXk3g bool CGame::TraceLine(const Vector& v0, const Vector& v1, Vector& vecIntersection, CCharacter*& pHit) { float flLowestFraction = 1; Vector vecTestIntersection; float flTestFraction; pHit = nullptr; for (size_t i = 0; i < MAX_CHARACTERS; i++) { CCharacter* pCharacter = GetCharacterIndex(i); if (!pCharacter) continue; // Only monsters and boxes get hit by traces. The player doesn't, he's immune to his own attacks. if (!pCharacter->m_bHitByTraces) continue; Matrix4x4 mInverse = pCharacter->GetGlobalTransform().InvertedTR(); // The v0 and v1 are in the global coordinate system and we need to transform it to the target's // local coordinate system to use axis-aligned intersection. We do so using the inverse transform matrix. // http://youtu.be/-Fn4atv2NsQ if (LineAABBIntersection(pCharacter->m_aabbSize, mInverse*v0, mInverse*v1, vecTestIntersection, flTestFraction) && flTestFraction < flLowestFraction) { // Once we have the result we can use the regular transform matrix to get it back in // global coordinates. http://youtu.be/-Fn4atv2NsQ vecIntersection = pCharacter->GetGlobalTransform()*vecTestIntersection; flLowestFraction = flTestFraction; pHit = pCharacter; } } // Intersect with the floor. // Line-Plane Intersection algorithm: http://youtu.be/fIu_8b2n8ZM if (LinePlaneIntersection(Vector(0, 1, 0), Vector(0, 0, 0), v0, v1, vecTestIntersection, flTestFraction) && flTestFraction < flLowestFraction) { vecIntersection = vecTestIntersection; flLowestFraction = flTestFraction; pHit = nullptr; } if (flLowestFraction < 1) return true; return false; }
TVector CCharacterCamera::GetThirdPersonCameraPosition() { CCharacter* pCharacter = m_hCharacter; if (!pCharacter) return TVector(10, 0, 0); TVector vecEyeHeight = pCharacter->GetUpVector() * pCharacter->EyeHeight(); TMatrix mView = TMatrix(pCharacter->GetThirdPersonCameraAngles(), TVector()); TVector vecThird = pCharacter->GetGlobalTransform().GetTranslation() + vecEyeHeight; vecThird -= Vector(mView.GetForwardVector()) * m_flBack; vecThird += Vector(mView.GetUpVector()) * m_flUp; vecThird += Vector(mView.GetLeftVector()) * m_flSide; return vecThird; }
void CGame::DrawCharacters(const std::vector<CCharacter*>& apRenderList, bool bTransparent) { CRenderer* pRenderer = GetRenderer(); // Loop through all characters, render them one at a time. // Start at the back of the list so that transparent entities use the painter's algorithm. for (size_t i = apRenderList.size()-1; i < apRenderList.size(); i--) { CCharacter* pCharacter = apRenderList[i]; CRenderingContext c(pRenderer, true); c.SetBlend(BLEND_NONE); c.SetAlpha(1); // Set the color of the box to be rendered. c.SetUniform("vecColor", pCharacter->m_clrRender); if (pCharacter->m_iBillboardTexture) { c.SetBackCulling(false); c.SetUniform("bDiffuse", true); // Create a billboard by creating basis vectors. https://www.youtube.com/watch?v=puOTwCrEm7Q Vector vecForward, vecRight, vecUp; vecForward = pCharacter->GetGlobalOrigin() - pRenderer->GetCameraPosition(); vecRight = -Vector(0, 1, 0).Cross(vecForward).Normalized(); vecUp = vecForward.Cross(-vecRight).Normalized(); if (pCharacter->m_bDrawTransparent) { c.SetAlpha(0.6f); c.SetBlend(BLEND_ALPHA); } c.LoadTransform(pCharacter->GetGlobalTransform()); c.Translate(Vector(0, pCharacter->m_aabbSize.GetHeight()/2, 0)); // Move the character up so his feet don't stick in the ground. pCharacter->ShotEffect(&c); c.RenderBillboard(pCharacter->m_iBillboardTexture, pCharacter->m_aabbSize.vecMax.x, vecUp, vecRight); } else { c.SetUniform("bDiffuse", false); // The transform matrix holds all transformations for the player. Just pass it through to the renderer. // http://youtu.be/7pe1xYzFCvA c.Transform(pCharacter->GetGlobalTransform()); if (pCharacter->m_bDrawTransparent) { c.SetAlpha(0.6f); c.SetBlend(BLEND_ALPHA); } if (pCharacter->m_iTexture) { c.SetUniform("bDiffuse", true); c.BindTexture(pCharacter->m_iTexture); } // Render the player-box c.RenderBox(pCharacter->m_aabbSize.vecMin, pCharacter->m_aabbSize.vecMax); } } }