void TileMap::UpdateData(InstanceData* instanceData) const { std::size_t spriteCount = 0; for (const Layer& layer : m_layers) spriteCount += layer.tiles.size(); instanceData->data.resize(4 * spriteCount * sizeof(VertexStruct_XYZ_Color_UV)); VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(instanceData->data.data()); spriteCount = 0; for (const Layer& layer : m_layers) { SparsePtr<Color> colorPtr(&vertices[4 * spriteCount].color, sizeof(VertexStruct_XYZ_Color_UV)); SparsePtr<Vector3f> posPtr(&vertices[4 * spriteCount].position, sizeof(VertexStruct_XYZ_Color_UV)); SparsePtr<Vector2f> texCoordPtr(&vertices[4 * spriteCount].uv, sizeof(VertexStruct_XYZ_Color_UV)); for (std::size_t tileIndex : layer.tiles) { const Tile& tile = m_tiles[tileIndex]; NazaraAssert(tile.enabled, "Tile specified for rendering is not enabled"); std::size_t x = tileIndex % m_mapSize.x; std::size_t y = tileIndex / m_mapSize.x; Vector3f tileLeftCorner; if (m_isometricModeEnabled) tileLeftCorner.Set(x * m_tileSize.x + m_tileSize.x/2.f * (y % 2), y/2.f * -m_tileSize.y, 0.f); else tileLeftCorner.Set(x * m_tileSize.x, y * -m_tileSize.y, 0.f); *colorPtr++ = tile.color; *posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner); *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftTop); *colorPtr++ = tile.color; *posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right()); *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightTop); *colorPtr++ = tile.color; *posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner + m_tileSize.y * Vector3f::Down()); *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftBottom); *colorPtr++ = tile.color; *posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right() + m_tileSize.y * Vector3f::Down()); *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightBottom); } spriteCount += layer.tiles.size(); } }
/* ============= Multiply ============= Multiply a vector through a matrix. dest can be equal to source since a temp vector is used. */ void Matrix::Multiply(const Vector3f &src, Vector3f &dest) const { Vector3f t; t.x = m[0][0] * src.x + m[1][0] * src.y + m[2][0] * src.z + m[3][0]; t.y = m[0][1] * src.x + m[1][1] * src.y + m[2][1] * src.z + m[3][1]; t.z = m[0][2] * src.x + m[1][2] * src.y + m[2][2] * src.z + m[3][2]; dest.Set(t); }
void ParticleManager::Render() { float mdlview[16]; // static? glGetFloatv(GL_MODELVIEW_MATRIX, mdlview); x.Set(mdlview[0], mdlview[4], mdlview[8]); y.Set(mdlview[1], mdlview[5], mdlview[9]); glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); Particle *p; for (p = head; p; p = p->next) p->Render(); glDepthMask(GL_TRUE); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); }
void TestHalfspace3D(void) { #define DO_TEST(res) \ desc.Format("p = (%3.1f, %3.1f, %3.1f), n = (%3.1f, %3.1f, %3.1f), t = (%3.1f, %3.1f, %3.1f)", \ planePt.X(), planePt.Y(), planePt.Z(), \ normal.X(), normal.Y(), planePt.Z(), \ testPt.X(), testPt.Y(), planePt.Z()); \ AssertEqual(desc.PeekBuffer(), planePt.Halfspace(normal, testPt), vislib::math::res) using vislib::math::HalfSpace; vislib::StringA desc; Point3f planePt; Vector3f normal; Point3f testPt; // Repeat 2D tests - these must succeed, too. planePt.Set(0.0f, 0.0f, 0.0f); normal.Set(1.0f, 0.0f, 0.0f); testPt.Set(0.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetY(1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetY(-1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetX(1.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.SetX(-1.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.Set(0.5f, 0.5f, 0.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.SetX(-1.0f); DO_TEST(HALFSPACE_NEGATIVE); normal.Set(0.0f, 1.0f, 0.0f); testPt.Set(0.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetX(1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetX(-1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetY(1.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.SetY(-1.0f); DO_TEST(HALFSPACE_NEGATIVE); normal.Set(0.5f, 0.5f, 0.0f); testPt.Set(0.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(0.5f, -0.5f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(-0.5f, 0.5f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(1.0f, 1.0f, 0.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(-1.0f, -1.0f, 0.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.Set(1.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(-1.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_NEGATIVE); planePt.Set(1.0f, 0.0f, 0.0f); normal.Set(1.0f, 0.0f, 0.0f); testPt.Set(0.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.SetY(1.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.SetY(-1.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.SetX(1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.SetX(-1.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.SetX(2.0f); DO_TEST(HALFSPACE_POSITIVE); // True 3D tests planePt.Set(0.0f, 0.0f, 0.0f); normal.Set(1.0f, 1.0f, 1.0f); testPt.Set(0.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(1.0f, 1.0f, 1.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(1.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(0.0f, 1.0f, 0.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(0.0f, 0.0f, 1.0f); DO_TEST(HALFSPACE_POSITIVE); testPt.Set(-1.0f, 0.0f, 0.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.Set(0.0f, -1.0f, 0.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.Set(0.0f, 0.0f, -1.0f); DO_TEST(HALFSPACE_NEGATIVE); testPt.Set(1.0f, 0.0f, -1.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(1.0f, -1.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(0.0f, -10.0f, 10.0f); DO_TEST(HALFSPACE_IN_PLANE); testPt.Set(10.0f, -10.0f, 0.0f); DO_TEST(HALFSPACE_IN_PLANE); }
// Checks if 2 cylinders intersect. Returns true if they do. bool BodyGeometry::IntersectingCylinders(KTCylinder &cylA, KTCylinder &cylB) { float numPA2 = ((cylA.length / std::max(cylA.bottom,cylA.top))/2.00f); int numPA = (int) ((numPA2<0.0 ? -numPA2 : numPA2) + 0.5f); float numPB2 = (cylB.length / std::max(cylB.bottom,cylB.top))/2.00f; int numPB = (int) ((numPB2<0.0 ? -numPB2 : numPB2) + 0.5f); numPB = std::min(numPB, 20); numPA = std::min(numPA, 20); Vector3f obA(0.00f,0.00f,0.00f); Vector3f otA(0.00f,0.00f,cylA.length); Vector3f oA[2]; oA[0] = cylA.pose * obA; oA[1] = cylA.pose * otA; Vector3f obB(0.00f,0.00f,0.00f); Vector3f otB(0.00f,0.00f,cylB.length); Vector3f oB[2]; oB[0] = cylB.pose * obB; oB[1] = cylB.pose * otB; //approximate first conic cylinder as a series of spheres float deltaPA = 1.00f / (float) numPA; Vector3f d12 = oA[1] - oA[0]; mCentersA.resize(numPA+1); mRadiiA.resize(numPA+1); float alpha; float delta_r = cylA.top - cylA.bottom; double val = delta_r/cylA.length; float scaling = (float)t_sqrt(1.00 + (val*val)); for(int i=0;i<=numPA;i++) { alpha = ((float) i)*deltaPA; mCentersA[i].Set(oA[0].x + (alpha * d12.x) , oA[0].y + (alpha * d12.y) , oA[0].z + (alpha * d12.z) ); // = oA[0] + (alpha * d12); mRadiiA[i] = (cylA.bottom + alpha * delta_r)/scaling; } //approximate second conic cylinder as a series of spheres float deltaPB = 1.00f / (float) numPB; d12 = oB[1] - oB[0]; mCentersB.resize(numPB+1); mRadiiB.resize(numPB+1); delta_r = cylB.top - cylB.bottom; val = delta_r/cylB.length; scaling = (float)t_sqrt(1.00f + (val*val)); for(int i=0;i<=numPB;i++) { alpha = ((float) i)*deltaPB; mCentersB[i].Set(oB[0].x + (alpha * d12.x) , oB[0].y + (alpha * d12.y) , oB[0].z + (alpha * d12.z) ); // = oB[0] + alpha * d12; mRadiiB[i] = (cylB.bottom + alpha * delta_r)/scaling; } //check if any spheres intersect from one cylinder to the other Vector3f difC; float rAB; float nrmsq; for(int i=0;i<=numPA;i++) { for(int j=0;j<=numPB;j++) { difC.Set(mCentersA[i].x - mCentersB[j].x , mCentersA[i].y - mCentersB[j].y , mCentersA[i].z - mCentersB[j].z ); // = mCentersA[i] - mCentersB[j] nrmsq = (difC.x * difC.x) + (difC.y * difC.y) + (difC.z * difC.z); rAB = mRadiiA[i] + mRadiiB[j]; if (rAB*rAB> nrmsq) return true; } } return false; };