Implement more complex area modifications (#260)

This implements rcAreaModification which allows combining of area types when they overlap
and otherwise usage of the area type as a bit mask.
This commit is contained in:
Domenico Albani
2017-03-12 12:18:29 +01:00
committed by Jakob Botsch Nielsen
parent ef3ea40f7a
commit 433986a5a4
15 changed files with 200 additions and 134 deletions
+47 -2
View File
@@ -71,6 +71,50 @@ void rcContext::log(const rcLogCategory category, const char* format, ...)
doLog(category, msg, len);
}
rcAreaModification::rcAreaModification(unsigned char value) :
m_value(value),
m_mask(RC_AREA_FLAGS_MASK)
{
}
rcAreaModification::rcAreaModification(unsigned char value, unsigned char mask) :
m_value(value),
m_mask(mask)
{
}
rcAreaModification::rcAreaModification(const rcAreaModification& other) :
m_value(other.m_value),
m_mask(other.m_mask)
{
}
void rcAreaModification::operator = (const rcAreaModification& other)
{
m_value = other.m_value;
m_mask = other.m_mask;
}
bool rcAreaModification::operator == (const rcAreaModification& other) const
{
return ((m_value == other.m_value) && (m_mask == other.m_mask));
}
bool rcAreaModification::operator != (const rcAreaModification& other) const
{
return ((m_value == other.m_value) && (m_mask == other.m_mask));
}
void rcAreaModification::apply(unsigned char& area) const
{
area = ((m_value & m_mask) | (area & ~m_mask));
}
unsigned char rcAreaModification::getMaskedValue() const
{
return (m_value & m_mask);
}
rcHeightfield* rcAllocHeightfield()
{
return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield;
@@ -263,7 +307,8 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
const float* verts, int nv,
const int* tris, int nt,
unsigned char* areas)
unsigned char* areas,
rcAreaModification areaMod)
{
rcIgnoreUnused(ctx);
rcIgnoreUnused(nv);
@@ -278,7 +323,7 @@ void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
// Check if the face is walkable.
if (norm[1] > walkableThr)
areas[i] = RC_WALKABLE_AREA;
areaMod.apply(areas[i]);
}
}