//! Merge all segments triangle's height of which bigger or equal than minTriangleHeight // http://www.math.ru/dic/276 void Polygon3::MergeFlatPolygonSegments(const Polygon3 &srcPolygon, Polygon3 &destPolygon, float32 minTriangleHeight) { float mh2 = minTriangleHeight * minTriangleHeight; destPolygon.Clear(); for (int i0 = 0; i0 < srcPolygon.pointCount - 2; ++i0) { destPolygon.AddPoint(srcPolygon.points[i0]); Vector3 v0 = srcPolygon.points[i0]; for (int i2 = i0 + 2; i2 < srcPolygon.pointCount; ++i2) { Vector3 v2 = srcPolygon.points[i2]; float c = (v2 - v0).Length(); float hc2 = 0.0f; for (int i1 = i0 + 1; i1 < i2; ++i1) { Vector3 v1 = srcPolygon.points[i1]; float a = (v1 - v0).Length(); float b = (v2 - v1).Length(); float p = (a + b + c) / 2.0f; hc2 = 4.0f * p * (p - a) * (p - b) * (p - c) / (c * c); if (hc2 >= mh2) { break; } } if (hc2 >= mh2) { i0 = i2 - 1 - 1; break; } } } destPolygon.AddPoint(srcPolygon.points.back()); }
void RenderHelper::DrawCylinder(const Vector3 & center, float32 radius, bool useFilling) { Polygon3 pts; float32 angle = SEGMENT_LENGTH / radius; int32 ptsCount = (int32)(PI_2 / (DegToRad(angle))) + 1; Vector<Vector2> vertexes; for(int32 i = 0; i <= ptsCount; i++) { float32 seta = i * 360.0f / (float32)ptsCount; float32 x = sin(DegToRad(seta)) * radius; float32 y = cos(DegToRad(seta)) * radius; vertexes.push_back(Vector2(x, y)); } for(int32 i = 0; i < ptsCount; ++i) { pts.AddPoint((Vector3(vertexes[i].x, vertexes[i].y, 1) * radius) + center); pts.AddPoint((Vector3(vertexes[i].x, vertexes[i].y, -1) * radius) + center); pts.AddPoint((Vector3(vertexes[i+1].x, vertexes[i+1].y, -1) * radius) + center); pts.AddPoint((Vector3(vertexes[i].x, vertexes[i].y, 1) * radius) + center); pts.AddPoint((Vector3(vertexes[i+1].x, vertexes[i+1].y, 1) * radius) + center); pts.AddPoint((Vector3(vertexes[i+1].x, vertexes[i+1].y, -1) * radius) + center); } if (useFilling) { FillPolygon(pts); } else { DrawPolygon(pts, true); } }
void RenderHelper::DrawCircle3D(const Vector3 & center, const Vector3 &emissionVector, float32 radius, bool useFilling) { Polygon3 pts; float32 angle = SEGMENT_LENGTH / radius; int ptsCount = (int)(PI_2 / (DegToRad(angle))) + 1; for (int k = 0; k < ptsCount; ++k) { float32 angleA = ((float)k / (ptsCount - 1)) * PI_2; float sinAngle = 0.0f; float cosAngle = 0.0f; SinCosFast(angleA, sinAngle, cosAngle); Vector3 directionVector(radius * cosAngle, radius * sinAngle, 0.0f); // Rotate the direction vector according to the current emission vector value. Vector3 zNormalVector(0.0f, 0.0f, 1.0f); Vector3 curEmissionVector = emissionVector; curEmissionVector.Normalize(); // This code rotates the (XY) plane with the particles to the direction vector. // Taking into account that a normal vector to the (XY) plane is (0,0,1) this // code is very simplified version of the generic "plane rotation" code. float32 length = curEmissionVector.Length(); if (FLOAT_EQUAL(length, 0.0f) == false) { float32 cosAngleRot = curEmissionVector.z / length; float32 angleRot = acos(cosAngleRot); Vector3 axisRot(curEmissionVector.y, -curEmissionVector.x, 0); Matrix3 planeRotMatrix; planeRotMatrix.CreateRotation(axisRot, angleRot); Vector3 rotatedVector = directionVector * planeRotMatrix; directionVector = rotatedVector; } Vector3 pos = center - directionVector; pts.AddPoint(pos); } if (useFilling) { FillPolygon(pts); } else { DrawPolygon(pts, false); } }
void RenderHelper::DrawCircle(const Vector3 & center, float32 radius) { Polygon3 pts; float32 angle = SEGMENT_LENGTH / radius; int ptsCount = (int)(2 * PI / (DegToRad(angle))) + 1; for (int k = 0; k < ptsCount; ++k) { float32 angle = ((float)k / (ptsCount - 1)) * 2 * PI; float32 sinA = sinf(angle); float32 cosA = cosf(angle); Vector3 pos = center - Vector3(sinA * radius, cosA * radius, 0); pts.AddPoint(pos); } DrawPolygon(pts, false); }