|
|
@@ -204,6 +204,291 @@ bool CustomGeometry::DrawOcclusion(OcclusionBuffer* buffer)
|
|
|
return success;
|
|
|
}
|
|
|
|
|
|
+Vector<Vector3> CustomGeometry::GetCircleShape(float radius, size_t iterations, float startTheta, float endTheta)
|
|
|
+{
|
|
|
+ float stepSize = (endTheta - startTheta) / (float)iterations;
|
|
|
+ Vector<Vector3> shapeList;
|
|
|
+ for (int i = 0; i < iterations; i++) {
|
|
|
+ float curTheta1 = startTheta + ((float)i * stepSize);
|
|
|
+ float curTheta2 = startTheta + ((float)(i+1) * stepSize);
|
|
|
+ float curX1 = radius * cos(curTheta1);
|
|
|
+ float curY1 = radius * sin(curTheta1);
|
|
|
+ float curX2 = radius * cos(curTheta2);
|
|
|
+ float curY2 = radius * sin(curTheta2);
|
|
|
+
|
|
|
+ shapeList.Push(Urho3D::Vector3(curX1, 0, curY1));
|
|
|
+ shapeList.Push(Urho3D::Vector3(curX2, 0, curY2));
|
|
|
+
|
|
|
+ if (i >= iterations - 1) {
|
|
|
+ float curTheta =0;
|
|
|
+ if (Abs(endTheta - startTheta) < (2*M_PI)) {
|
|
|
+ curTheta = endTheta;
|
|
|
+ }
|
|
|
+ float curX = radius * cos(curTheta);
|
|
|
+ float curY = radius * sin(curTheta);
|
|
|
+ shapeList.Push(Urho3D::Vector3(curX, 0, curY));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return shapeList;
|
|
|
+}
|
|
|
+
|
|
|
+Vector<Vector3> CustomGeometry::GetSquareShape(float size)
|
|
|
+{
|
|
|
+ Vector<Vector3> mSquareList = { Urho3D::Vector3(-(size / 2.0f),0,(size / 2.0f)),Urho3D::Vector3(-(size / 2.0f),0,-(size / 2.0f)),
|
|
|
+ Urho3D::Vector3((size / 2.0f), 0, -(size / 2.0f)),Urho3D::Vector3((size / 2.0f), 0, (size / 2.0f)) };
|
|
|
+ return mSquareList;
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::MakeCircle(float radius, size_t iterations, float startTheta,
|
|
|
+ float endTheta, bool clear, int geomNum)
|
|
|
+{
|
|
|
+ Vector<Vector3> mCircleShape = GetCircleShape(radius, iterations, startTheta, endTheta);
|
|
|
+ FillShape(mCircleShape,false,clear,geomNum);
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::MakeCircleGraph(const Vector<Pair<float, Urho3D::SharedPtr<Urho3D::Material> > >& parts,
|
|
|
+ int radius, int iterations)
|
|
|
+{
|
|
|
+ if (parts.Size() > 0) {
|
|
|
+ float totalWeight = 0;
|
|
|
+ SetNumGeometries(parts.Size());
|
|
|
+ auto it = parts.Begin();
|
|
|
+ while (it != parts.End()) {
|
|
|
+ const auto current = (*it);
|
|
|
+ totalWeight += current.first_;
|
|
|
+ it++;
|
|
|
+ }
|
|
|
+
|
|
|
+ it = parts.Begin();
|
|
|
+ float currentStartTheta = 0;
|
|
|
+ float currentEndTheta = 0;
|
|
|
+ int count = 0;
|
|
|
+ while (it != parts.End()) {
|
|
|
+ const auto current = (*it);
|
|
|
+ currentEndTheta = ((current.first_ / totalWeight)*(2 * M_PI)) + currentStartTheta;
|
|
|
+ MakeCircle(radius, (iterations / parts.Size()), currentStartTheta, currentEndTheta,false,count);
|
|
|
+ if (current.second_.NotNull()) {
|
|
|
+ SetMaterial(count, current.second_);
|
|
|
+ }
|
|
|
+ it++;
|
|
|
+ count++;
|
|
|
+ currentStartTheta = currentEndTheta;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::MakeShape(const Vector<Vector3>& pointList , bool connectTail)
|
|
|
+{
|
|
|
+ Clear();
|
|
|
+ SetNumGeometries(1);
|
|
|
+ BeginGeometry(0, Urho3D::PrimitiveType::LINE_STRIP);
|
|
|
+ Vector3 current;
|
|
|
+ Vector3 next;
|
|
|
+ for (size_t i = 0; i < pointList.Size(); i++) {
|
|
|
+ if ((connectTail && i >= pointList.Size() - 1) || i < pointList.Size() - 1) {
|
|
|
+ current = pointList[i];
|
|
|
+ next = pointList[0];
|
|
|
+ if (i < pointList.Size() - 1) {
|
|
|
+ next = pointList[i + 1];
|
|
|
+ }
|
|
|
+ DefineVertex(current);
|
|
|
+ DefineVertex(next);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ Commit();
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::FillShape(const Vector<Vector3>& shapeList, bool connectTail, bool clear, int geomNum)
|
|
|
+{
|
|
|
+ if (shapeList.Size() > 0) {
|
|
|
+ int usedGeomNum = geomNum;
|
|
|
+ if (clear) {
|
|
|
+ Clear();
|
|
|
+ SetNumGeometries(1);
|
|
|
+ usedGeomNum = 0;
|
|
|
+ }
|
|
|
+ BeginGeometry(usedGeomNum, PrimitiveType::TRIANGLE_STRIP);
|
|
|
+ auto centerPoint = Vector3(0, 0, 0);
|
|
|
+ if (connectTail) {
|
|
|
+ auto centerPoint = Urho3D::Average(shapeList);
|
|
|
+ }
|
|
|
+ Vector<Vector3> vertices(3);
|
|
|
+ Vector3 current;
|
|
|
+ Vector3 next;
|
|
|
+ Vector3 normal;
|
|
|
+ auto it = shapeList.Begin();
|
|
|
+ auto nextIt = it;
|
|
|
+ while (it != shapeList.End()) {
|
|
|
+ nextIt = it + 1;
|
|
|
+ if (connectTail && nextIt == shapeList.End() || nextIt != shapeList.End())
|
|
|
+ {
|
|
|
+ current = (*it);
|
|
|
+
|
|
|
+ if (nextIt != shapeList.End()) {
|
|
|
+ next = (*nextIt);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ next = (*shapeList.Begin());
|
|
|
+ }
|
|
|
+
|
|
|
+ vertices = { centerPoint, current, next };
|
|
|
+
|
|
|
+ normal = Urho3D::Average(vertices);
|
|
|
+ normal.Normalize();
|
|
|
+ normal.Orthogonalize(normal);
|
|
|
+ DefineVertex(vertices.At(0));
|
|
|
+ DefineNormal(normal);
|
|
|
+
|
|
|
+ DefineVertex(vertices.At(1));
|
|
|
+ DefineNormal(normal);
|
|
|
+
|
|
|
+ DefineVertex(vertices.At(2));
|
|
|
+ DefineNormal(normal);
|
|
|
+ }
|
|
|
+ it++;
|
|
|
+ }
|
|
|
+ Commit();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::MakeSphere(float radius, size_t iterations)
|
|
|
+{
|
|
|
+ //Create the geometry buffer
|
|
|
+ float angleStepSize = (2.0f * M_PI) / (float)iterations;
|
|
|
+ Vector<Vector3> m_xyPoints;
|
|
|
+ for (int i = 0; i < iterations; i++) {
|
|
|
+ float curTheta = i * angleStepSize;
|
|
|
+ for (int j = 0; j < iterations; j++) {
|
|
|
+ float curPhi = j * angleStepSize;
|
|
|
+ float curX = radius * cos(curTheta) * sin(curPhi);
|
|
|
+ float curY = radius * sin(curTheta) * sin(curPhi);
|
|
|
+ float curZ = radius * cos(curPhi);
|
|
|
+ m_xyPoints.Push(Vector3(curX,curY,curZ));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CreateQuadsFromBuffer(m_xyPoints, iterations, iterations, true);
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::ProtrudeShape(const Vector<Vector3>& mShapeList,
|
|
|
+ const Vector<Vector3>& mPointList, bool connectTail)
|
|
|
+{
|
|
|
+ Vector3 centerPoint = Urho3D::Average<Vector3>(mShapeList);
|
|
|
+ Vector3 pointCurrent;
|
|
|
+ Vector3 shapeCurrent;
|
|
|
+ Vector3 shapePointVec;
|
|
|
+ Vector3 shapePointDir;
|
|
|
+ Vector<Vector3> mPointBuffer(mShapeList.Size()*mPointList.Size()+mShapeList.Size());
|
|
|
+
|
|
|
+ Vector<Vector3> mLastShapePos = mShapeList;
|
|
|
+ auto pointIter = mPointList.Begin();
|
|
|
+ auto shapeIter = mLastShapePos.Begin();
|
|
|
+
|
|
|
+ int bufferCount = 0;
|
|
|
+ while (shapeIter != mLastShapePos.End()) {
|
|
|
+ mPointBuffer.At(bufferCount) = (*shapeIter);
|
|
|
+ shapeIter++;
|
|
|
+ bufferCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ int count = 0;
|
|
|
+ while (pointIter != mPointList.End()) {
|
|
|
+ shapeIter = mLastShapePos.Begin();
|
|
|
+ pointCurrent = (*pointIter);
|
|
|
+ count = 0;
|
|
|
+ while (shapeIter != mLastShapePos.End()) {
|
|
|
+ shapeCurrent = (*shapeIter);
|
|
|
+ if (shapeIter == mLastShapePos.Begin()) { //protrude from first point of the shape and create dir Vector to point
|
|
|
+ shapePointVec = pointCurrent - centerPoint;
|
|
|
+ centerPoint = pointCurrent;
|
|
|
+ }
|
|
|
+ // protrude from the rest of the points on the shape to the next point given a dir and length vector
|
|
|
+ shapePointDir = shapePointVec;
|
|
|
+ shapePointDir.Normalize();
|
|
|
+ mLastShapePos[count] = mLastShapePos[count] + shapePointDir * shapePointVec.Length();
|
|
|
+ mPointBuffer.At(bufferCount) = mLastShapePos[count];
|
|
|
+
|
|
|
+ bufferCount++;
|
|
|
+ shapeIter++;
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ pointIter++;
|
|
|
+ }
|
|
|
+ CreateQuadsFromBuffer(mPointBuffer, mPointList.Size() + 1, mShapeList.Size(), connectTail);
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::CreateQuadsFromBuffer(const Vector<Vector3>& pointList, size_t zIterations,
|
|
|
+ size_t thetaIterations, bool connectTail)
|
|
|
+{
|
|
|
+ if (!connectTail) {
|
|
|
+ SetNumGeometries(3);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ SetNumGeometries(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Create the quads from the buffer
|
|
|
+ BeginGeometry(0, Urho3D::PrimitiveType::TRIANGLE_STRIP);
|
|
|
+ for (size_t i = 0; i < zIterations; i++) {
|
|
|
+ if ((i >= zIterations - 1 && connectTail) || i < zIterations - 1) {
|
|
|
+ for (size_t j = 0; j < thetaIterations; j++) {
|
|
|
+ //if at the end connect to the beginning to complete pass
|
|
|
+ size_t iplus = i + 1;
|
|
|
+ size_t jplus = j + 1;
|
|
|
+ if (i >= zIterations - 1) {
|
|
|
+ iplus = 0;
|
|
|
+ }
|
|
|
+ if (j >= thetaIterations - 1) {
|
|
|
+ jplus = 0;
|
|
|
+ }
|
|
|
+ Vector<Vector3> avList;
|
|
|
+ avList = { pointList.At((i*thetaIterations) + j) ,pointList.At((iplus*thetaIterations)+
|
|
|
+ j) ,pointList.At((i*thetaIterations) + jplus) };
|
|
|
+ Vector3 normal = Urho3D::Average<Vector3>(avList);
|
|
|
+ normal.Normalize();
|
|
|
+ DefineVertex(avList.At(0));
|
|
|
+ DefineVertex(avList.At(1));
|
|
|
+ DefineVertex(avList.At(2));
|
|
|
+ DefineNormal(normal);
|
|
|
+ avList.Clear();
|
|
|
+
|
|
|
+ avList = { pointList.At((i*thetaIterations) + j) ,pointList.At((iplus*thetaIterations)+
|
|
|
+ j) ,pointList.At((iplus*thetaIterations) + jplus) };
|
|
|
+ normal = Urho3D::Average<Vector3>(avList);
|
|
|
+ normal.Normalize();
|
|
|
+ DefineVertex(avList.At(0));
|
|
|
+ DefineVertex(avList.At(1));
|
|
|
+ DefineVertex(avList.At(2));
|
|
|
+ DefineNormal(normal);
|
|
|
+ avList.Clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Commit();
|
|
|
+
|
|
|
+ if (!connectTail) {
|
|
|
+ //fill in the head and tail
|
|
|
+ auto tailBegin = pointList.Begin();
|
|
|
+ auto tailEnd = pointList.Begin() + thetaIterations;
|
|
|
+ Vector<Vector3> tail(tailBegin, tailEnd);
|
|
|
+ auto headBegin = pointList.Begin() + pointList.Size() - thetaIterations;
|
|
|
+ auto headEnd = pointList.Begin() + pointList.Size();
|
|
|
+ Vector<Vector3> head(headBegin, headEnd);
|
|
|
+
|
|
|
+ FillShape(tail, true, false, 1);
|
|
|
+ FillShape(head, true, false, 2);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CustomGeometry::MakeSquare(float size)
|
|
|
+{
|
|
|
+ Vector<Vector3> mSquareList = { Urho3D::Vector3(-(size / 2.0f),0,(size / 2.0f)),Urho3D::Vector3(-(size / 2.0f),0,-(size / 2.0f)),
|
|
|
+ Urho3D::Vector3((size / 2.0f), 0, -(size / 2.0f)),Urho3D::Vector3((size / 2.0f), 0, (size / 2.0f)) };
|
|
|
+ FillShape(mSquareList,true);
|
|
|
+}
|
|
|
+
|
|
|
void CustomGeometry::Clear()
|
|
|
{
|
|
|
elementMask_ = MASK_POSITION;
|