Merge branch 'master' of https://github.com/memononen/recastnavigation
This commit is contained in:
commit
9b73c5cf51
@ -662,8 +662,8 @@ dtStatus dtNavMeshQuery::getPolyHeight(dtPolyRef ref, const float* pos, float* h
|
|||||||
{
|
{
|
||||||
const float* v0 = &tile->verts[poly->verts[0]*3];
|
const float* v0 = &tile->verts[poly->verts[0]*3];
|
||||||
const float* v1 = &tile->verts[poly->verts[1]*3];
|
const float* v1 = &tile->verts[poly->verts[1]*3];
|
||||||
const float d0 = dtVdist(pos, v0);
|
const float d0 = dtVdist2D(pos, v0);
|
||||||
const float d1 = dtVdist(pos, v1);
|
const float d1 = dtVdist2D(pos, v1);
|
||||||
const float u = d0 / (d0+d1);
|
const float u = d0 / (d0+d1);
|
||||||
if (height)
|
if (height)
|
||||||
*height = v0[1] + (v1[1] - v0[1]) * u;
|
*height = v0[1] + (v1[1] - v0[1]) * u;
|
||||||
|
@ -45,6 +45,12 @@ static const int DT_CROWDAGENT_MAX_CORNERS = 4;
|
|||||||
/// dtCrowdAgentParams::obstacleAvoidanceType
|
/// dtCrowdAgentParams::obstacleAvoidanceType
|
||||||
static const int DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS = 8;
|
static const int DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS = 8;
|
||||||
|
|
||||||
|
/// The maximum number of query filter types supported by the crowd manager.
|
||||||
|
/// @ingroup crowd
|
||||||
|
/// @see dtQueryFilter, dtCrowd::getFilter() dtCrowd::getEditableFilter(),
|
||||||
|
/// dtCrowdAgentParams::queryFilterType
|
||||||
|
static const int DT_CROWD_MAX_QUERY_FILTER_TYPE = 16;
|
||||||
|
|
||||||
/// Provides neighbor data for agents managed by the crowd.
|
/// Provides neighbor data for agents managed by the crowd.
|
||||||
/// @ingroup crowd
|
/// @ingroup crowd
|
||||||
/// @see dtCrowdAgent::neis, dtCrowd
|
/// @see dtCrowdAgent::neis, dtCrowd
|
||||||
@ -87,6 +93,9 @@ struct dtCrowdAgentParams
|
|||||||
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
||||||
unsigned char obstacleAvoidanceType;
|
unsigned char obstacleAvoidanceType;
|
||||||
|
|
||||||
|
/// The index of the query filter used by this agent.
|
||||||
|
unsigned char queryFilterType;
|
||||||
|
|
||||||
/// User defined data attached to the agent.
|
/// User defined data attached to the agent.
|
||||||
void* userData;
|
void* userData;
|
||||||
};
|
};
|
||||||
@ -206,8 +215,9 @@ class dtCrowd
|
|||||||
int m_maxPathResult;
|
int m_maxPathResult;
|
||||||
|
|
||||||
float m_ext[3];
|
float m_ext[3];
|
||||||
dtQueryFilter m_filter;
|
|
||||||
|
dtQueryFilter m_filters[DT_CROWD_MAX_QUERY_FILTER_TYPE];
|
||||||
|
|
||||||
float m_maxAgentRadius;
|
float m_maxAgentRadius;
|
||||||
|
|
||||||
int m_velocitySampleCount;
|
int m_velocitySampleCount;
|
||||||
@ -251,6 +261,11 @@ public:
|
|||||||
/// @return The requested agent.
|
/// @return The requested agent.
|
||||||
const dtCrowdAgent* getAgent(const int idx);
|
const dtCrowdAgent* getAgent(const int idx);
|
||||||
|
|
||||||
|
/// Gets the specified agent from the pool.
|
||||||
|
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||||
|
/// @return The requested agent.
|
||||||
|
dtCrowdAgent* getEditableAgent(const int idx);
|
||||||
|
|
||||||
/// The maximum number of agents that can be managed by the object.
|
/// The maximum number of agents that can be managed by the object.
|
||||||
/// @return The maximum number of agents.
|
/// @return The maximum number of agents.
|
||||||
int getAgentCount() const;
|
int getAgentCount() const;
|
||||||
@ -301,11 +316,11 @@ public:
|
|||||||
|
|
||||||
/// Gets the filter used by the crowd.
|
/// Gets the filter used by the crowd.
|
||||||
/// @return The filter used by the crowd.
|
/// @return The filter used by the crowd.
|
||||||
const dtQueryFilter* getFilter() const { return &m_filter; }
|
inline const dtQueryFilter* getFilter(const int i) const { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
|
||||||
|
|
||||||
/// Gets the filter used by the crowd.
|
/// Gets the filter used by the crowd.
|
||||||
/// @return The filter used by the crowd.
|
/// @return The filter used by the crowd.
|
||||||
dtQueryFilter* getEditableFilter() { return &m_filter; }
|
inline dtQueryFilter* getEditableFilter(const int i) { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
|
||||||
|
|
||||||
/// Gets the search extents [(x, y, z)] used by the crowd for query operations.
|
/// Gets the search extents [(x, y, z)] used by the crowd for query operations.
|
||||||
/// @return The search extents used by the crowd. [(x, y, z)]
|
/// @return The search extents used by the crowd. [(x, y, z)]
|
||||||
|
@ -484,6 +484,17 @@ int dtCrowd::getAgentCount() const
|
|||||||
/// Agents in the pool may not be in use. Check #dtCrowdAgent.active before using the returned object.
|
/// Agents in the pool may not be in use. Check #dtCrowdAgent.active before using the returned object.
|
||||||
const dtCrowdAgent* dtCrowd::getAgent(const int idx)
|
const dtCrowdAgent* dtCrowd::getAgent(const int idx)
|
||||||
{
|
{
|
||||||
|
if (idx < 0 || idx >= m_maxAgents)
|
||||||
|
return 0;
|
||||||
|
return &m_agents[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Agents in the pool may not be in use. Check #dtCrowdAgent.active before using the returned object.
|
||||||
|
dtCrowdAgent* dtCrowd::getEditableAgent(const int idx)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx >= m_maxAgents)
|
||||||
|
return 0;
|
||||||
return &m_agents[idx];
|
return &m_agents[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,13 +523,13 @@ int dtCrowd::addAgent(const float* pos, const dtCrowdAgentParams* params)
|
|||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dtCrowdAgent* ag = &m_agents[idx];
|
dtCrowdAgent* ag = &m_agents[idx];
|
||||||
|
|
||||||
// Find nearest position on navmesh and place the agent there.
|
// Find nearest position on navmesh and place the agent there.
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtPolyRef ref = 0;
|
dtPolyRef ref = 0;
|
||||||
dtVcopy(nearest, pos);
|
dtVcopy(nearest, pos);
|
||||||
dtStatus status = m_navquery->findNearestPoly(pos, m_ext, &m_filter, &ref, nearest);
|
dtStatus status = m_navquery->findNearestPoly(pos, m_ext, &m_filters[ag->params.queryFilterType], &ref, nearest);
|
||||||
if (dtStatusFailed(status))
|
if (dtStatusFailed(status))
|
||||||
{
|
{
|
||||||
dtVcopy(nearest, pos);
|
dtVcopy(nearest, pos);
|
||||||
@ -691,7 +702,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
|
|||||||
|
|
||||||
// Quick search towards the goal.
|
// Quick search towards the goal.
|
||||||
static const int MAX_ITER = 20;
|
static const int MAX_ITER = 20;
|
||||||
m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos, &m_filter);
|
m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos, &m_filters[ag->params.queryFilterType]);
|
||||||
m_navquery->updateSlicedFindPath(MAX_ITER, 0);
|
m_navquery->updateSlicedFindPath(MAX_ITER, 0);
|
||||||
dtStatus status = 0;
|
dtStatus status = 0;
|
||||||
if (ag->targetReplan) // && npath > 10)
|
if (ag->targetReplan) // && npath > 10)
|
||||||
@ -758,7 +769,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
|
|||||||
{
|
{
|
||||||
dtCrowdAgent* ag = queue[i];
|
dtCrowdAgent* ag = queue[i];
|
||||||
ag->targetPathqRef = m_pathq.request(ag->corridor.getLastPoly(), ag->targetRef,
|
ag->targetPathqRef = m_pathq.request(ag->corridor.getLastPoly(), ag->targetRef,
|
||||||
ag->corridor.getTarget(), ag->targetPos, &m_filter);
|
ag->corridor.getTarget(), ag->targetPos, &m_filters[ag->params.queryFilterType]);
|
||||||
if (ag->targetPathqRef != DT_PATHQ_INVALID)
|
if (ag->targetPathqRef != DT_PATHQ_INVALID)
|
||||||
ag->targetState = DT_CROWDAGENT_TARGET_WAITING_FOR_PATH;
|
ag->targetState = DT_CROWDAGENT_TARGET_WAITING_FOR_PATH;
|
||||||
}
|
}
|
||||||
@ -912,7 +923,7 @@ void dtCrowd::updateTopologyOptimization(dtCrowdAgent** agents, const int nagent
|
|||||||
for (int i = 0; i < nqueue; ++i)
|
for (int i = 0; i < nqueue; ++i)
|
||||||
{
|
{
|
||||||
dtCrowdAgent* ag = queue[i];
|
dtCrowdAgent* ag = queue[i];
|
||||||
ag->corridor.optimizePathTopology(m_navquery, &m_filter);
|
ag->corridor.optimizePathTopology(m_navquery, &m_filters[ag->params.queryFilterType]);
|
||||||
ag->topologyOptTime = 0;
|
ag->topologyOptTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,9 +940,6 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
|
|
||||||
if (ag->state != DT_CROWDAGENT_STATE_WALKING)
|
if (ag->state != DT_CROWDAGENT_STATE_WALKING)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ag->targetReplanTime += dt;
|
ag->targetReplanTime += dt;
|
||||||
|
|
||||||
@ -942,14 +950,14 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
float agentPos[3];
|
float agentPos[3];
|
||||||
dtPolyRef agentRef = ag->corridor.getFirstPoly();
|
dtPolyRef agentRef = ag->corridor.getFirstPoly();
|
||||||
dtVcopy(agentPos, ag->npos);
|
dtVcopy(agentPos, ag->npos);
|
||||||
if (!m_navquery->isValidPolyRef(agentRef, &m_filter))
|
if (!m_navquery->isValidPolyRef(agentRef, &m_filters[ag->params.queryFilterType]))
|
||||||
{
|
{
|
||||||
// Current location is not valid, try to reposition.
|
// Current location is not valid, try to reposition.
|
||||||
// TODO: this can snap agents, how to handle that?
|
// TODO: this can snap agents, how to handle that?
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtVcopy(nearest, agentPos);
|
dtVcopy(nearest, agentPos);
|
||||||
agentRef = 0;
|
agentRef = 0;
|
||||||
m_navquery->findNearestPoly(ag->npos, m_ext, &m_filter, &agentRef, nearest);
|
m_navquery->findNearestPoly(ag->npos, m_ext, &m_filters[ag->params.queryFilterType], &agentRef, nearest);
|
||||||
dtVcopy(agentPos, nearest);
|
dtVcopy(agentPos, nearest);
|
||||||
|
|
||||||
if (!agentRef)
|
if (!agentRef)
|
||||||
@ -971,16 +979,20 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
replan = true;
|
replan = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the agent does not have move target or is controlled by velocity, no need to recover the target nor replan.
|
||||||
|
if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Try to recover move request position.
|
// Try to recover move request position.
|
||||||
if (ag->targetState != DT_CROWDAGENT_TARGET_NONE && ag->targetState != DT_CROWDAGENT_TARGET_FAILED)
|
if (ag->targetState != DT_CROWDAGENT_TARGET_NONE && ag->targetState != DT_CROWDAGENT_TARGET_FAILED)
|
||||||
{
|
{
|
||||||
if (!m_navquery->isValidPolyRef(ag->targetRef, &m_filter))
|
if (!m_navquery->isValidPolyRef(ag->targetRef, &m_filters[ag->params.queryFilterType]))
|
||||||
{
|
{
|
||||||
// Current target is not valid, try to reposition.
|
// Current target is not valid, try to reposition.
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtVcopy(nearest, ag->targetPos);
|
dtVcopy(nearest, ag->targetPos);
|
||||||
ag->targetRef = 0;
|
ag->targetRef = 0;
|
||||||
m_navquery->findNearestPoly(ag->targetPos, m_ext, &m_filter, &ag->targetRef, nearest);
|
m_navquery->findNearestPoly(ag->targetPos, m_ext, &m_filters[ag->params.queryFilterType], &ag->targetRef, nearest);
|
||||||
dtVcopy(ag->targetPos, nearest);
|
dtVcopy(ag->targetPos, nearest);
|
||||||
replan = true;
|
replan = true;
|
||||||
}
|
}
|
||||||
@ -993,7 +1005,7 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If nearby corridor is not valid, replan.
|
// If nearby corridor is not valid, replan.
|
||||||
if (!ag->corridor.isValid(CHECK_LOOKAHEAD, m_navquery, &m_filter))
|
if (!ag->corridor.isValid(CHECK_LOOKAHEAD, m_navquery, &m_filters[ag->params.queryFilterType]))
|
||||||
{
|
{
|
||||||
// Fix current path.
|
// Fix current path.
|
||||||
// ag->corridor.trimInvalidPath(agentRef, agentPos, m_navquery, &m_filter);
|
// ag->corridor.trimInvalidPath(agentRef, agentPos, m_navquery, &m_filter);
|
||||||
@ -1029,7 +1041,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
|
|
||||||
dtCrowdAgent** agents = m_activeAgents;
|
dtCrowdAgent** agents = m_activeAgents;
|
||||||
int nagents = getActiveAgents(agents, m_maxAgents);
|
int nagents = getActiveAgents(agents, m_maxAgents);
|
||||||
|
|
||||||
// Check that all agents still have valid paths.
|
// Check that all agents still have valid paths.
|
||||||
checkPathValidity(agents, nagents, dt);
|
checkPathValidity(agents, nagents, dt);
|
||||||
|
|
||||||
@ -1060,10 +1072,10 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
// if it has become invalid.
|
// if it has become invalid.
|
||||||
const float updateThr = ag->params.collisionQueryRange*0.25f;
|
const float updateThr = ag->params.collisionQueryRange*0.25f;
|
||||||
if (dtVdist2DSqr(ag->npos, ag->boundary.getCenter()) > dtSqr(updateThr) ||
|
if (dtVdist2DSqr(ag->npos, ag->boundary.getCenter()) > dtSqr(updateThr) ||
|
||||||
!ag->boundary.isValid(m_navquery, &m_filter))
|
!ag->boundary.isValid(m_navquery, &m_filters[ag->params.queryFilterType]))
|
||||||
{
|
{
|
||||||
ag->boundary.update(ag->corridor.getFirstPoly(), ag->npos, ag->params.collisionQueryRange,
|
ag->boundary.update(ag->corridor.getFirstPoly(), ag->npos, ag->params.collisionQueryRange,
|
||||||
m_navquery, &m_filter);
|
m_navquery, &m_filters[ag->params.queryFilterType]);
|
||||||
}
|
}
|
||||||
// Query neighbour agents
|
// Query neighbour agents
|
||||||
ag->nneis = getNeighbours(ag->npos, ag->params.height, ag->params.collisionQueryRange,
|
ag->nneis = getNeighbours(ag->npos, ag->params.height, ag->params.collisionQueryRange,
|
||||||
@ -1085,14 +1097,14 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
|
|
||||||
// Find corners for steering
|
// Find corners for steering
|
||||||
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys,
|
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys,
|
||||||
DT_CROWDAGENT_MAX_CORNERS, m_navquery, &m_filter);
|
DT_CROWDAGENT_MAX_CORNERS, m_navquery, &m_filters[ag->params.queryFilterType]);
|
||||||
|
|
||||||
// Check to see if the corner after the next corner is directly visible,
|
// Check to see if the corner after the next corner is directly visible,
|
||||||
// and short cut to there.
|
// and short cut to there.
|
||||||
if ((ag->params.updateFlags & DT_CROWD_OPTIMIZE_VIS) && ag->ncorners > 0)
|
if ((ag->params.updateFlags & DT_CROWD_OPTIMIZE_VIS) && ag->ncorners > 0)
|
||||||
{
|
{
|
||||||
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
|
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
|
||||||
ag->corridor.optimizePathVisibility(target, ag->params.pathOptimizationRange, m_navquery, &m_filter);
|
ag->corridor.optimizePathVisibility(target, ag->params.pathOptimizationRange, m_navquery, &m_filters[ag->params.queryFilterType]);
|
||||||
|
|
||||||
// Copy data for debug purposes.
|
// Copy data for debug purposes.
|
||||||
if (debugIdx == i)
|
if (debugIdx == i)
|
||||||
@ -1372,7 +1384,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Move along navmesh.
|
// Move along navmesh.
|
||||||
ag->corridor.movePosition(ag->npos, m_navquery, &m_filter);
|
ag->corridor.movePosition(ag->npos, m_navquery, &m_filters[ag->params.queryFilterType]);
|
||||||
// Get valid constrained position back.
|
// Get valid constrained position back.
|
||||||
dtVcopy(ag->npos, ag->corridor.getPos());
|
dtVcopy(ag->npos, ag->corridor.getPos());
|
||||||
|
|
||||||
@ -1422,5 +1434,3 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1324,6 +1324,12 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
|
|||||||
const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f);
|
const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f);
|
||||||
const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f);
|
const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f);
|
||||||
|
|
||||||
|
bool isMinX = (ox == 0);
|
||||||
|
bool isMinZ = (oz == 0);
|
||||||
|
bool isMaxX = ((unsigned short)floorf((mesh.bmax[0] - pmesh->bmax[0]) / mesh.cs + 0.5f)) == 0;
|
||||||
|
bool isMaxZ = ((unsigned short)floorf((mesh.bmax[2] - pmesh->bmax[2]) / mesh.cs + 0.5f)) == 0;
|
||||||
|
bool isOnBorder = (isMinX || isMinZ || isMaxX || isMaxZ);
|
||||||
|
|
||||||
for (int j = 0; j < pmesh->nverts; ++j)
|
for (int j = 0; j < pmesh->nverts; ++j)
|
||||||
{
|
{
|
||||||
unsigned short* v = &pmesh->verts[j*3];
|
unsigned short* v = &pmesh->verts[j*3];
|
||||||
@ -1344,6 +1350,36 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
|
|||||||
if (src[k] == RC_MESH_NULL_IDX) break;
|
if (src[k] == RC_MESH_NULL_IDX) break;
|
||||||
tgt[k] = vremap[src[k]];
|
tgt[k] = vremap[src[k]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isOnBorder)
|
||||||
|
{
|
||||||
|
for (int k = mesh.nvp; k < mesh.nvp * 2; ++k)
|
||||||
|
{
|
||||||
|
if (src[k] & 0x8000 && src[k] != 0xffff)
|
||||||
|
{
|
||||||
|
unsigned short dir = src[k] & 0xf;
|
||||||
|
switch (dir)
|
||||||
|
{
|
||||||
|
case 0: // Portal x-
|
||||||
|
if (isMinX)
|
||||||
|
tgt[k] = src[k];
|
||||||
|
break;
|
||||||
|
case 1: // Portal z+
|
||||||
|
if (isMaxZ)
|
||||||
|
tgt[k] = src[k];
|
||||||
|
break;
|
||||||
|
case 2: // Portal x+
|
||||||
|
if (isMaxX)
|
||||||
|
tgt[k] = src[k];
|
||||||
|
break;
|
||||||
|
case 3: // Portal z-
|
||||||
|
if (isMinZ)
|
||||||
|
tgt[k] = src[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,4 +1317,3 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -174,8 +174,12 @@ bool InputGeom::load(rcContext* ctx, const char* filePath)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fread(buf, bufSize, 1, fp);
|
size_t readLen = fread(buf, bufSize, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
if (readLen != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_offMeshConCount = 0;
|
m_offMeshConCount = 0;
|
||||||
m_volumeCount = 0;
|
m_volumeCount = 0;
|
||||||
|
@ -78,7 +78,6 @@ void rcMeshLoaderObj::addTriangle(int a, int b, int c, int& cap)
|
|||||||
|
|
||||||
static char* parseRow(char* buf, char* bufEnd, char* row, int len)
|
static char* parseRow(char* buf, char* bufEnd, char* row, int len)
|
||||||
{
|
{
|
||||||
bool cont = false;
|
|
||||||
bool start = true;
|
bool start = true;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -90,7 +89,6 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len)
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '\\':
|
case '\\':
|
||||||
cont = true; // multirow
|
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
if (start) break;
|
if (start) break;
|
||||||
@ -103,7 +101,6 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len)
|
|||||||
if (start) break;
|
if (start) break;
|
||||||
default:
|
default:
|
||||||
start = false;
|
start = false;
|
||||||
cont = false;
|
|
||||||
row[n++] = c;
|
row[n++] = c;
|
||||||
if (n >= len-1)
|
if (n >= len-1)
|
||||||
done = true;
|
done = true;
|
||||||
@ -153,9 +150,14 @@ bool rcMeshLoaderObj::load(const char* filename)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fread(buf, bufSize, 1, fp);
|
size_t readLen = fread(buf, bufSize, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
if (readLen != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char* src = buf;
|
char* src = buf;
|
||||||
char* srcEnd = buf + bufSize;
|
char* srcEnd = buf + bufSize;
|
||||||
char row[512];
|
char row[512];
|
||||||
|
@ -312,8 +312,8 @@ bool FileIO::write(const void* ptr, const size_t size)
|
|||||||
bool FileIO::read(void* ptr, const size_t size)
|
bool FileIO::read(void* ptr, const size_t size)
|
||||||
{
|
{
|
||||||
if (!m_fp || m_mode != 2) return false;
|
if (!m_fp || m_mode != 2) return false;
|
||||||
fread(ptr, size, 1, m_fp);
|
size_t readLen = fread(ptr, size, 1, m_fp);
|
||||||
return true;
|
return readLen == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,7 +285,12 @@ dtNavMesh* Sample_TileMesh::loadAll(const char* path)
|
|||||||
|
|
||||||
// Read header.
|
// Read header.
|
||||||
NavMeshSetHeader header;
|
NavMeshSetHeader header;
|
||||||
fread(&header, sizeof(NavMeshSetHeader), 1, fp);
|
size_t readLen = fread(&header, sizeof(NavMeshSetHeader), 1, fp);
|
||||||
|
if (readLen != 1)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (header.magic != NAVMESHSET_MAGIC)
|
if (header.magic != NAVMESHSET_MAGIC)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -314,15 +319,20 @@ dtNavMesh* Sample_TileMesh::loadAll(const char* path)
|
|||||||
for (int i = 0; i < header.numTiles; ++i)
|
for (int i = 0; i < header.numTiles; ++i)
|
||||||
{
|
{
|
||||||
NavMeshTileHeader tileHeader;
|
NavMeshTileHeader tileHeader;
|
||||||
fread(&tileHeader, sizeof(tileHeader), 1, fp);
|
readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp);
|
||||||
|
if (readLen != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
|
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
|
||||||
if (!data) break;
|
if (!data) break;
|
||||||
memset(data, 0, tileHeader.dataSize);
|
memset(data, 0, tileHeader.dataSize);
|
||||||
fread(data, tileHeader.dataSize, 1, fp);
|
readLen = fread(data, tileHeader.dataSize, 1, fp);
|
||||||
|
if (readLen != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
|
mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +106,12 @@ bool TestCase::load(const char* filePath)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fread(buf, bufSize, 1, fp);
|
size_t readLen = fread(buf, bufSize, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
if (readLen != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char* src = buf;
|
char* src = buf;
|
||||||
char* srcEnd = buf + bufSize;
|
char* srcEnd = buf + bufSize;
|
||||||
|
@ -247,7 +247,7 @@ bool imguiRenderGLInit(const char* fontpath)
|
|||||||
FILE* fp = fopen(fontpath, "rb");
|
FILE* fp = fopen(fontpath, "rb");
|
||||||
if (!fp) return false;
|
if (!fp) return false;
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
int size = ftell(fp);
|
size_t size = ftell(fp);
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
unsigned char* ttfBuffer = (unsigned char*)malloc(size);
|
unsigned char* ttfBuffer = (unsigned char*)malloc(size);
|
||||||
@ -257,8 +257,13 @@ bool imguiRenderGLInit(const char* fontpath)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(ttfBuffer, 1, size, fp);
|
size_t readLen = fread(ttfBuffer, 1, size, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
if (readLen != size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fp = 0;
|
fp = 0;
|
||||||
|
|
||||||
unsigned char* bmap = (unsigned char*)malloc(512*512);
|
unsigned char* bmap = (unsigned char*)malloc(512*512);
|
||||||
|
@ -101,7 +101,8 @@ int main(int /*argc*/, char** /*argv*/)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = vi->current_w - 20;
|
width = rcMin(vi->current_w, (int)(vi->current_h * 16.0 / 9.0));
|
||||||
|
width = width - 80;
|
||||||
height = vi->current_h - 80;
|
height = vi->current_h - 80;
|
||||||
screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL);
|
screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user