123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- //
- // ShapeModule.cpp
- // cocos2d_libs
- //
- // Created by 徐俊杰 on 2020/4/24.
- //
- #include "rparticle/Modules/ShapeModule.h"
- //#include "UnityPrefix.h"
- //#include "rparticle/Modules/ShapeModule.h"
- #include "rparticle/ParticleSystemUtils.h"
- #include "rparticle/RParticleSystem.h"
- //#include "Runtime/Graphics/TriStripper.h"
- //#include "Runtime/Math/Vector2.h"
- #include "rparticle/Math/Random/Random.h"
- //#include "Runtime/Geometry/ComputionalGeometry.h"
- //#include "Runtime/BaseClasses/IsPlaying.h"
- //#include "Runtime/Utilities/StrideIterator.h"
- //#include "Runtime/Filters/Mesh/LodMesh.h"
- #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
- #define zero ZERO
- #define one ONE
- #define yAxis UNIT_Y
- #define zAxis UNIT_Z
- // MinMaxAABB
- #define m_Max _max
- #define m_Min _min
- NS_RRP_BEGIN
- static const float kMinRadius = 0.001f;
- enum MeshDistributionMode
- {
- kDistributionVertex,
- kDistributionTriangle,
- };
- /// This gives a random barycentric coord (on the edge of triangle)
- // @TODO: Stupid: Make this in a faster way
- inline Vector3f RandomBarycentricCoordEdge (Rand& rand)
- {
- float u = rand.GetFloat ();
- float v = rand.GetFloat ();
- if (u + v > 1.0F)
- {
- u = 1.0F - u;
- v = 1.0F - v;
- }
- float w = 1.0F - u - v;
-
- int edge = RangedRandom(rand, 0, 2);
- if(0 == edge)
- {
- v += 0.5f * u;
- w += 0.5f * u;
- u = 0.0f;
- }
- else if(1 == edge)
- {
- u += 0.5f * v;
- w += 0.5f * v;
- v = 0.0f;
- }
- else
- {
- u += 0.5f * w;
- v += 0.5f * w;
- w = 0.0f;
- }
-
- return Vector3f (u, v, w);
- }
- // TODO: It could make sense to initialize in separated loops. i.e. separate position and velcoity vectors
- inline void EmitterStoreData(const Matrix4x4f& localToWorld, const Vector3f& scale, ParticleSystemParticles& ps, size_t q, Vector3f& pos, Vector3f& n, Rand& random, bool randomDirection)
- {
- if(randomDirection)
- n = RandomUnitVector (random);
-
- n = NormalizeSafe(n);
-
- pos = ScaleVec3(pos, scale);
-
- Vector3f vel = Magnitude (ps.velocity[q]) * n;
- vel = localToWorld.MultiplyVector3 (vel);
-
- // @TODO: Sooo... why multiply point and then undo the result of it? Why not just MultiplyVector?
- pos = localToWorld.MultiplyPoint3 (pos) - localToWorld.GetPosition();
- ps.position[q] += pos;
- ps.velocity[q] = vel;
-
- #if 0 // WIP code for converting to spherical
- Vector3f sp = ps.position[q];
- ps.position[q].x = Sqrt(sp.x*sp.x + sp.y*sp.y + sp.z*sp.z);
- ps.position[q].y = acosf(sp.z/ps.position[q].x);
- ps.position[q].z = acosf(sp.y/ps.position[q].x);
- #endif
-
- if(ps.usesAxisOfRotation)
- {
- Vector3f tan = Cross (-n, Vector3f::zAxis);
- if (SqrMagnitude (tan) <= 0.01)
- tan = Cross (-pos, Vector3f::zAxis);
- if (SqrMagnitude (tan) <= 0.01)
- tan = Vector3f::yAxis;
- ps.axisOfRotation[q] = Normalize (tan);
- }
- }
- inline void EmitterStoreData(const Matrix4x4f& localToWorld, const Vector3f& scale, ParticleSystemParticles& ps, size_t q, Vector3f& pos, Vector3f& n, ColorRGBA32& color, Rand& random, bool randomDirection)
- {
- EmitterStoreData(localToWorld, scale, ps, q, pos, n, random, randomDirection);
- ps.color[q] *= color;
- }
- //TODO: Mesh stuff
- /*
- template<MeshDistributionMode distributionMode>
- void GetPositionMesh (Vector3f& pos,
- Vector3f& n,
- ColorRGBA32& color,
- const ParticleSystemEmitterMeshVertex* vertexData,
- const int vertexCount,
- const MeshTriangleData* triangleData,
- const UInt32 numPrimitives,
- float totalTriangleArea,
- Rand& random,
- bool edge)
- {
- // position/normal of particle is vertex/vertex normal from mesh
- if(kDistributionVertex == distributionMode)
- {
- int vertexIndex = RangedRandom (random, 0, vertexCount);
- pos = vertexData[vertexIndex].position;
- n = vertexData[vertexIndex].normal;
- color = vertexData[vertexIndex].color;
- }
- else if(kDistributionTriangle == distributionMode)
- {
- float randomArea = RangedRandom(random, 0.0f, totalTriangleArea);
- float accArea = 0.0f;
- UInt32 triangleIndex = 0;
-
- for(UInt32 i = 0; i < numPrimitives; i++)
- {
- const MeshTriangleData& data = triangleData[i];
- accArea += data.area;
- if(accArea >= randomArea)
- {
- triangleIndex = i;
- break;
- }
- }
-
- const MeshTriangleData& data = triangleData[triangleIndex];
- UInt16 a = data.indices[0];
- UInt16 b = data.indices[1];
- UInt16 c = data.indices[2];
-
- Vector3f barycenter;
- if(edge)
- barycenter = RandomBarycentricCoordEdge (random);
- else
- barycenter = RandomBarycentricCoord (random);
-
- // Interpolate vertex with barycentric coordinate
- pos = barycenter.x * vertexData[a].position + barycenter.y * vertexData[b].position + barycenter.z * vertexData[c].position;
- n = barycenter.x * vertexData[a].normal + barycenter.y * vertexData[b].normal + barycenter.z * vertexData[c].normal;
-
- // TODO: Don't convert to floats!!!
- ColorRGBAf color1(vertexData[a].color);
- ColorRGBAf color2(vertexData[b].color);
- ColorRGBAf color3(vertexData[c].color);
- color = barycenter.x * color1 + barycenter.y * color2 + barycenter.z * color3;
- }
- }
- static bool CompareMeshTriangleData (const MeshTriangleData& a, const MeshTriangleData& b)
- {
- return (a.area > b.area);
- }
- static float BuildMeshAreaTable(MeshTriangleData* triData, const StrideIterator<Vector3f> vertices, const UInt16* indices, int numTriangles)
- {
- float result = 0.0f;
- for(int i = 0; i < numTriangles; i++)
- {
- const UInt16 a = indices[i * 3 + 0];
- const UInt16 b = indices[i * 3 + 1];
- const UInt16 c = indices[i * 3 + 2];
- float area = TriangleArea3D (vertices[a], vertices[b], vertices[c]);
- result += area;
-
- triData[i].indices[0] = a;
- triData[i].indices[1] = b;
- triData[i].indices[2] = c;
- triData[i].area = area;
- }
-
- return result;
- }
- */
- // ------------------------------------------------------------------------------------------
- ShapeModule::ShapeModule () : ParticleSystemModule(true)
- , m_Type (kCone)
- , m_RandomDirection (false)
- , m_Angle(25.0f)
- , m_Radius(1.0f)
- , m_RadiusThickness(1.0f)
- , m_BurstSpread(false)
- , m_SpreadSpaceThickness(1.0f)
- , m_Length(5.0f)
- , m_Arc(360.0f)
- , m_BoxX(1.0f)
- , m_BoxY(1.0f)
- , m_BoxZ(1.0f)
- //TODO: Mesh stuff
- /*
- , m_PlacementMode(kVertex)
- , m_CachedMesh(NULL)
- , m_MeshNode (NULL)
- */
- {
- }
- void ShapeModule::Start (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, const Matrix4x4f& matrix, size_t fromIndex, float t)
- {
- DebugAssert(roState.lengthInSec > 0.0001f);
- const float normalizedT = t / roState.lengthInSec;
- DebugAssert (normalizedT >= 0.0f);
- DebugAssert (normalizedT <= 1.0f);
-
- Rand& random = GetRandom();
-
- //TODO: Mesh stuff
- /*
- if (m_Type == kMesh)
- {
- if(!m_CachedMesh)
- return;
-
- if(!m_CachedVertexData.size())
- return;
-
- if(!m_CachedTriangleData.size())
- return;
-
- const ParticleSystemEmitterMeshVertex* vertexData = &m_CachedVertexData[0];
- const int vertexCount = m_CachedVertexData.size();
- size_t count = ps.array_size ();
- switch(m_PlacementMode)
- {
- case kVertex:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos;
- Vector3f n;
- ColorRGBA32 color;
- GetPositionMesh<kDistributionVertex>(pos, n, color, vertexData, vertexCount, NULL, 0, m_CachedTotalTriangleArea, random, false);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, color, random, m_RandomDirection);
- }
- break;
- }
- case kEdge:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos;
- Vector3f n;
- ColorRGBA32 color;
- GetPositionMesh<kDistributionTriangle>(pos, n, color, vertexData, vertexCount, m_CachedTriangleData.begin(), m_CachedTriangleData.size(), m_CachedTotalTriangleArea, random, true);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, color, random, m_RandomDirection);
- }
- break;
- }
- case kTriangle:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos;
- Vector3f n;
- ColorRGBA32 color;
- GetPositionMesh<kDistributionTriangle>(pos, n, color, vertexData, vertexCount, m_CachedTriangleData.begin(), m_CachedTriangleData.size(), m_CachedTotalTriangleArea, random, false);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, color, random, m_RandomDirection);
- }
- break;
- }
- default:
- {
- DebugAssert(0 && "PlacementMode Not Supported");
- }
- }
- }
- else
- */
- {
- const float r = m_Radius;
-
- float a = Deg2Rad (m_Angle);
- float sinA = Sin (a);
- float cosA = Cos (a);
- float length = m_Length;
-
- const size_t count = ps.array_size ();
- switch(m_Type)
- {
- case kSphere:
- {
- float innerRadiusThickness = std::pow(1.0f - m_RadiusThickness, 3.0f);
- for (int q = fromIndex; q < count; ++q)
- {
- float rr = std::pow(RangedRandom(m_Random, innerRadiusThickness, 1.0f), 1.0f / 3.0f);
- Vector3f pos = RandomUnitVector (random) * (r * rr);
- Vector3f n = pos;
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kSphereShell:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos = RandomUnitVector(random) * r;
- Vector3f n = pos;
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kHemiSphere:
- {
- float innerRadiusThickness = std::pow(1.0f - m_RadiusThickness, 3.0f);
- for (int q = fromIndex; q < count; ++q)
- {
- float rr = std::pow(RangedRandom(m_Random, innerRadiusThickness, 1.0f), 1.0f / 3.0f);
- Vector3f pos = RandomUnitVector (random) * (r * rr);
- if (pos.z < 0.0f)
- pos.z *= -1.0f;
- Vector3f n = pos;
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kHemiSphereShell:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos = RandomUnitVector (random) * r;
- if (pos.z < 0.0f)
- pos.z *= -1.0f;
- Vector3f n = pos;
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kCone:
- {
- const float innerRadiusThickness = std::max(kMinRadius, 1.0f - m_RadiusThickness);
- for (int q = fromIndex; q < count; ++q)
- {
- float rr = RangedRandom(m_Random, innerRadiusThickness, 1.0f);
- Vector2f posXY = NormalizeSafe(RandomUnitVector2 (random)) * rr;
- Vector2f nXY;
- if(m_RandomDirection)
- nXY = RandomPointInsideUnitCircle (random) * sinA;
- else
- nXY = Vector2f(posXY.x, posXY.y)* sinA;
- Vector3f n (nXY.x, nXY.y, cosA);
- Vector3f pos (posXY.x * r, posXY.y * r, 0.0f);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, false);
- }
- break;
- }
- case kConeShell:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector2f posXY = NormalizeSafe(RandomUnitVector2 (random));
-
- Vector2f nXY;
- if(m_RandomDirection)
- nXY = RandomPointInsideUnitCircle (random) * sinA;
- else
- nXY = Vector2f(posXY.x, posXY.y)* sinA;
- Vector3f n (nXY.x, nXY.y, cosA);
- Vector3f pos (posXY.x * r, posXY.y * r, 0.0f);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, false);
- }
- break;
- }
- case kConeVolume:
- {
- const float innerRadiusThickness = std::max(kMinRadius, 1.0f - m_RadiusThickness);
- for (int q = fromIndex; q < count; ++q)
- {
- float rr = RangedRandom(m_Random, innerRadiusThickness, 1.0f);
- Vector2f posXY = NormalizeSafe(RandomUnitVector2 (random)) * rr;
- Vector2f nXY = Vector2f(posXY.x, posXY.y)* sinA;
- Vector3f n (nXY.x, nXY.y, cosA);
- Vector3f pos (posXY.x * r, posXY.y * r, 0.0f);
- pos += length * Random01(random) * NormalizeSafe(n);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kConeVolumeShell:
- {
- for (int q = fromIndex; q < count; ++q)
- {
- Vector2f posXY = NormalizeSafe(RandomUnitVector2 (random));
- Vector2f nXY = Vector2f(posXY.x, posXY.y)* sinA;
- Vector3f n (nXY.x, nXY.y, cosA);
- Vector3f pos = Vector3f(posXY.x * r, posXY.y * r, 0.0f);
- pos += length * Random01(random) * NormalizeSafe(n);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kCircle:
- {
- float arc = CC_DEGREES_TO_RADIANS(m_Arc);
- float innerRadiusThicknessSqr = std::sqrt(1.0f - m_RadiusThickness);
- auto burstCount = count - fromIndex;
- float randomAngle = m_BurstSpread ? Random01(m_Random) * (1 - m_SpreadSpaceThickness) : 0;
- for (int q = fromIndex; q < count; ++q)
- {
- // angle
- float ra = 0.0f;
- if (m_BurstSpread) {
- ra = (Random01(m_Random) * m_SpreadSpaceThickness + randomAngle + q - fromIndex) * (arc / burstCount);
- } else {
- ra = Random01(m_Random) * arc;
- }
-
- // distance from center
- float radiusRandom = std::sqrt(Lerp(innerRadiusThicknessSqr, 1.0f, m_Random.GetFloat()));
- float rr = (radiusRandom * r);
-
- // generate
- float sra = sin(ra);
- float cra = cos(ra);
- Vector3f pos(cra * rr, sra * rr, 0);
- Vector3f n(cra, sra, 0);
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- break;
- }
- case kBox:
- {
- const Vector3f extents (0.5f * m_BoxX, 0.5f * m_BoxY, 0.5f * m_BoxZ);
- for (int q = fromIndex; q < count; ++q)
- {
- Vector3f pos = RandomPointInsideCube (random, extents);
- Vector3f n = Vector3f::zAxis;
- EmitterStoreData(matrix, state.emitterScale, ps, q, pos, n, random, m_RandomDirection);
- }
- }
- break;
- default:
- {
- DebugAssert(0 && "Shape not supported");
- }
- }
- }
- }
- void ShapeModule::CalculateProceduralBounds(MinMaxAABB& bounds, const Vector3f& emitterScale, Vector2f minMaxBounds) const
- {
- DebugAssert(minMaxBounds.x <= minMaxBounds.y);
-
- switch(m_Type)
- {
- case kSphere:
- case kSphereShell:
- bounds.m_Max = Vector3f(m_Radius, m_Radius, m_Radius);
- bounds.m_Min = -bounds.m_Max;
- break;
- case kHemiSphere:
- case kHemiSphereShell:
- bounds.m_Max = Vector3f(m_Radius, m_Radius, m_Radius);
- bounds.m_Min = Vector3f(-m_Radius, -m_Radius, 0.0f);
- break;
- case kCone:
- case kConeShell:
- bounds.m_Max = Vector3f(m_Radius, m_Radius, 0.0f);
- bounds.m_Min = -bounds.m_Max;
- break;
- case kConeVolume:
- case kConeVolumeShell:
- {
- const float a = Deg2Rad (m_Angle);
- const float coneRadius2 = m_Radius + m_Length * Sin (a);
- const float coneLength = m_Length * Cos (a);
- bounds.m_Max = Vector3f(coneRadius2, coneRadius2, coneLength);
- bounds.m_Min = -Vector3f(coneRadius2, coneRadius2, 0.0f);
- break;
- }
- case kBox:
- bounds.m_Max = Vector3f(m_BoxX, m_BoxY, m_BoxZ) * 0.5f;
- bounds.m_Min = -bounds.m_Max;
- break;
- case kMesh:
- {
- //TODO: Mesh stuff
- /*
- if(m_CachedMesh)
- bounds = m_CachedMesh->GetBounds(0);
- else
- bounds = MinMaxAABB(Vector3f::zero, Vector3f::zero);
- */
- break;
- }
- default:
- {
- AssertBreak(!"Shape not implemented.");
- }
- }
-
- bounds.m_Min = ScaleVec3(bounds.m_Min, emitterScale);
- bounds.m_Max = ScaleVec3(bounds.m_Max, emitterScale);
-
- MinMaxAABB speedBounds;
-
- // Cone and cone shell random direction only deviate inside the bound
- if(m_RandomDirection && (m_Type != kCone) && (m_Type != kConeShell))
- {
- speedBounds.m_Max = Vector3f::one;
- speedBounds.m_Min = -Vector3f::one;
- minMaxBounds = Abs(minMaxBounds);
- }
- else
- {
- switch(m_Type)
- {
- case kSphere:
- case kSphereShell:
- case kMesh:
- speedBounds.m_Max = Vector3f::one;
- speedBounds.m_Min = -Vector3f::one;
- break;
- case kHemiSphere:
- case kHemiSphereShell:
- speedBounds.m_Max = Vector3f::one;
- speedBounds.m_Min = Vector3f(-1.0f, -1.0f, 0.0f);
- break;
- case kCone:
- case kConeShell:
- case kConeVolume:
- case kConeVolumeShell:
- {
- const float a = Deg2Rad (m_Angle);
- const float sinA = Sin (a);
- speedBounds.m_Max = Vector3f(sinA, sinA, 1.0f);
- speedBounds.m_Min = Vector3f(-sinA, -sinA, 0.0f);
- break;
- }
- case kBox:
- speedBounds.m_Max = Vector3f::zAxis;
- speedBounds.m_Min = Vector3f::zero;
- break;
- default:
- {
- AssertBreak(!"Shape not implemented.");
- }
- }
- }
-
- MinMaxAABB speedBound;
- speedBound.m_Min = bounds.m_Min + speedBounds.m_Min * minMaxBounds.y;
- speedBound.m_Max = bounds.m_Max + speedBounds.m_Max * minMaxBounds.y;
- bounds.Encapsulate(speedBound);
-
- MinMaxAABB negSpeedBound;
- negSpeedBound.m_Min = speedBounds.m_Min * minMaxBounds.x;
- negSpeedBound.m_Max = speedBounds.m_Max * minMaxBounds.x;
- speedBound.m_Min = MIN(negSpeedBound.m_Min, negSpeedBound.m_Max);
- speedBound.m_Max = MAX(negSpeedBound.m_Min, negSpeedBound.m_Max);
- bounds.Encapsulate(speedBound);
- }
- void ShapeModule::CheckConsistency ()
- {
- m_Type = clamp<int> (m_Type, kSphere, kMax-1);
- //TODO: Mesh stuff
- // m_PlacementMode = clamp<int> (m_PlacementMode, kVertex, kModeMax-1);
-
- m_Angle = clamp(m_Angle, 0.0f, 90.0f);
- m_Radius = MAX(0.01f, m_Radius);
- m_Length = MAX(0.0f, m_Length);
- m_BoxX = MAX(0.0f, m_BoxX);
- m_BoxY = MAX(0.0f, m_BoxY);
- m_BoxZ = MAX(0.0f, m_BoxZ);
- }
- void ShapeModule::AwakeFromLoad (RParticleSystem* system, const ParticleSystemReadOnlyState& roState)
- {
- //TODO: Mesh stuff
- /*
- m_MeshNode.RemoveFromList();
- m_MeshNode.SetData(system);
- m_CachedMesh = m_Mesh;
- if (m_CachedMesh != NULL)
- m_CachedMesh->AddObjectUser( m_MeshNode );
- DidModifyMeshData();
- */
-
- ResetSeed(roState);
- }
- void ShapeModule::ResetSeed(const ParticleSystemReadOnlyState& roState)
- {
- if(roState.randomSeed == 0)
- m_Random.SetSeed(GetGlobalRandomSeed ());
- else
- m_Random.SetSeed(roState.randomSeed);
- }
- void ShapeModule::DidDeleteMesh (RParticleSystem* system)
- {
- //TODO: Mesh stuff
- // m_CachedMesh = NULL;
- }
- void ShapeModule::DidModifyMeshData ()
- {
- //TODO: Mesh stuff
- /*
- if (m_CachedMesh == NULL)
- {
- m_CachedTriangleData.resize_uninitialized(0);
- m_CachedVertexData.resize_uninitialized(0);
- m_CachedTotalTriangleArea = 0;
- return;
- }
-
-
- const StrideIterator<Vector3f> vertexBuffer = m_CachedMesh->GetVertexBegin();
- const UInt16* indexBuffer = m_CachedMesh->GetSubMeshBuffer16(0);
- const SubMesh& submesh = m_CachedMesh->GetSubMeshFast (0);
- if (submesh.topology == kPrimitiveTriangleStripDeprecated)
- {
- const int numTriangles = CountTrianglesInStrip(indexBuffer, submesh.indexCount);
- const int capacity = numTriangles * 3;
- UNITY_TEMP_VECTOR(UInt16) tempIndices(capacity);
- Destripify(indexBuffer, submesh.indexCount, &tempIndices[0], capacity);
- m_CachedTriangleData.resize_uninitialized(numTriangles);
- m_CachedTotalTriangleArea = BuildMeshAreaTable(m_CachedTriangleData.begin(), vertexBuffer, &tempIndices[0], numTriangles);
- }
- else if (submesh.topology == kPrimitiveTriangles)
- {
- const int numTriangles = submesh.indexCount/3;
- m_CachedTriangleData.resize_uninitialized(numTriangles);
- m_CachedTotalTriangleArea = BuildMeshAreaTable(m_CachedTriangleData.begin(), vertexBuffer, indexBuffer, numTriangles);
- }
- else
- {
- m_CachedMesh = NULL;
- }
-
- // Optimization: This sorts so big triangles comes before small, which means finding the right triangle is faster
- std::sort(m_CachedTriangleData.begin(), m_CachedTriangleData.begin() + m_CachedTriangleData.size(), CompareMeshTriangleData);
-
- // Cache vertices
- const int vertexCount = m_CachedMesh->GetVertexCount();
- const StrideIterator<Vector3f> vertices = m_CachedMesh->GetVertexBegin();
- const StrideIterator<Vector3f> normals = m_CachedMesh->GetNormalBegin();
- const StrideIterator<ColorRGBA32> colors = m_CachedMesh->GetColorBegin();
- m_CachedVertexData.resize_uninitialized(vertexCount);
- for(int i = 0; i < vertexCount; i++)
- {
- m_CachedVertexData[i].position = vertices[i];
-
- if(!normals.IsNull())
- m_CachedVertexData[i].normal = normals[i];
- else
- m_CachedVertexData[i].normal = Vector3f::zero;
-
- if(!colors.IsNull())
- m_CachedVertexData[i].color = colors[i];
- else
- m_CachedVertexData[i].color = ColorRGBA32(0xffffffff);
- }
- */
- }
- Rand& ShapeModule::GetRandom()
- {
- #if UNITY_EDITOR
- if(!IsWorldPlaying())
- return m_EditorRandom;
- else
- #endif
- return m_Random;
- }
- template<class TransferFunction>
- void ShapeModule::Transfer (TransferFunction& transfer)
- {
- transfer.SetVersion(2);
- ParticleSystemModule::Transfer (transfer);
- transfer.Transfer (m_Type, "type");
-
- // Primitive
- transfer.Transfer(m_Radius, "radius");
- transfer.Transfer(m_RadiusThickness, "radiusThickness");
- transfer.Transfer(m_Angle, "angle");
- transfer.Transfer(m_Length, "length");
- transfer.Transfer(m_BoxX, "boxX");
- transfer.Transfer(m_BoxY, "boxY");
- transfer.Transfer(m_BoxZ, "boxZ");
-
- //TODO: Mesh stuff
- /*(
- // Mesh
- transfer.Transfer (m_PlacementMode, "placementMode");
- TRANSFER (m_Mesh);
- */
-
- transfer.Transfer (m_RandomDirection, "randomDirection"); transfer.Align();
-
- // In Unity 3.5 all cone emitters had random direction set to false, but behaved as if it was true
- if(transfer.IsOldVersion(1))
- if(kCone == m_Type)
- m_RandomDirection = true;
- }
- INSTANTIATE_TEMPLATE_TRANSFER(ShapeModule)
- NS_RRP_END
|