Missing files for ConvexVolumeTool.
This commit is contained in:
parent
4d778cbf39
commit
1eaf28c548
52
RecastDemo/Include/ConvexVolumeTool.h
Normal file
52
RecastDemo/Include/ConvexVolumeTool.h
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef CONVEXVOLUMETOOL_H
|
||||
#define CONVEXVOLUMETOOL_H
|
||||
|
||||
#include "Sample.h"
|
||||
|
||||
// Tool to create convex volumess for InputGeom
|
||||
|
||||
class ConvexVolumeTool : public SampleTool
|
||||
{
|
||||
Sample* m_sample;
|
||||
int m_areaType;
|
||||
float m_boxHeight;
|
||||
float m_boxDescent;
|
||||
|
||||
static const int MAX_PTS = 12;
|
||||
float m_pts[MAX_PTS*3];
|
||||
int m_npts;
|
||||
int m_hull[MAX_PTS];
|
||||
int m_nhull;
|
||||
|
||||
public:
|
||||
ConvexVolumeTool();
|
||||
~ConvexVolumeTool();
|
||||
|
||||
virtual int type() { return TOOL_CONVEX_VOLUME; }
|
||||
virtual void init(Sample* sample);
|
||||
virtual void reset();
|
||||
virtual void handleMenu();
|
||||
virtual void handleClick(const float* p, bool shift);
|
||||
virtual void handleRender();
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
};
|
||||
|
||||
#endif // CONVEXVOLUMETOOL_H
|
263
RecastDemo/Source/ConvexVolumeTool.cpp
Normal file
263
RecastDemo/Source/ConvexVolumeTool.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "imgui.h"
|
||||
#include "ConvexVolumeTool.h"
|
||||
#include "InputGeom.h"
|
||||
#include "Sample.h"
|
||||
#include "Recast.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// Quick and dirty convex hull.
|
||||
inline bool left(const float* a, const float* b, const float* c)
|
||||
{
|
||||
return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]) < 0;
|
||||
}
|
||||
|
||||
inline bool cmppt(const float* a, const float* b)
|
||||
{
|
||||
if (a[0] < b[0]) return true;
|
||||
if (a[0] > b[0]) return false;
|
||||
if (a[2] < b[2]) return true;
|
||||
if (a[2] > b[2]) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int convexhull(const float* pts, int npts, int* out)
|
||||
{
|
||||
// Find leftmost point.
|
||||
int hull = 0;
|
||||
for (int i = 1; i < npts; ++i)
|
||||
if (cmppt(&pts[i*3], &pts[hull*3]))
|
||||
hull = i;
|
||||
// Gif wrap hull.
|
||||
int endpt = 0;
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
out[i++] = hull;
|
||||
endpt = 0;
|
||||
for (int j = 1; j < npts; ++j)
|
||||
if (hull == endpt || left(&pts[hull*3], &pts[endpt*3], &pts[j*3]))
|
||||
endpt = j;
|
||||
hull = endpt;
|
||||
}
|
||||
while (endpt != out[0]);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int pointInPoly(int nvert, const float* verts, const float* p)
|
||||
{
|
||||
int i, j, c = 0;
|
||||
for (i = 0, j = nvert-1; i < nvert; j = i++)
|
||||
{
|
||||
const float* vi = &verts[i*3];
|
||||
const float* vj = &verts[j*3];
|
||||
if (((vi[2] > p[2]) != (vj[2] > p[2])) &&
|
||||
(p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
|
||||
c = !c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
ConvexVolumeTool::ConvexVolumeTool() :
|
||||
m_sample(0),
|
||||
m_areaType(SAMPLE_POLYAREA_GRASS),
|
||||
m_boxHeight(6.0f),
|
||||
m_boxDescent(1.0f),
|
||||
m_npts(0),
|
||||
m_nhull(0)
|
||||
{
|
||||
}
|
||||
|
||||
ConvexVolumeTool::~ConvexVolumeTool()
|
||||
{
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::init(Sample* sample)
|
||||
{
|
||||
m_sample = sample;
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::reset()
|
||||
{
|
||||
m_npts = 0;
|
||||
m_nhull = 0;
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::handleMenu()
|
||||
{
|
||||
imguiSlider("Shape Height", &m_boxHeight, 0.1f, 20.0f, 0.1f);
|
||||
imguiSlider("Shape Descent", &m_boxDescent, 0.1f, 20.0f, 0.1f);
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
imguiLabel("Area Type");
|
||||
imguiIndent();
|
||||
if (imguiCheck("Grass", m_areaType == SAMPLE_POLYAREA_GRASS))
|
||||
m_areaType = SAMPLE_POLYAREA_GRASS;
|
||||
if (imguiCheck("Road", m_areaType == SAMPLE_POLYAREA_ROAD))
|
||||
m_areaType = SAMPLE_POLYAREA_ROAD;
|
||||
if (imguiCheck("Water", m_areaType == SAMPLE_POLYAREA_WATER))
|
||||
m_areaType = SAMPLE_POLYAREA_WATER;
|
||||
if (imguiCheck("Door", m_areaType == SAMPLE_POLYAREA_DOOR))
|
||||
m_areaType = SAMPLE_POLYAREA_DOOR;
|
||||
imguiUnindent();
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
if (imguiButton("Clear Shape"))
|
||||
{
|
||||
m_npts = 0;
|
||||
m_nhull = 0;
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
imguiValue("Click to create points.");
|
||||
imguiValue("The shape is convex hull");
|
||||
imguiValue("of all the create points.");
|
||||
imguiValue("Click on highlited point");
|
||||
imguiValue("to finish the shape.");
|
||||
|
||||
imguiSeparator();
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::handleClick(const float* p, bool shift)
|
||||
{
|
||||
if (!m_sample) return;
|
||||
InputGeom* geom = m_sample->getInputGeom();
|
||||
if (!geom) return;
|
||||
|
||||
if (shift)
|
||||
{
|
||||
// Delete
|
||||
int nearestIndex = -1;
|
||||
const ConvexVolume* vols = geom->getConvexVolumes();
|
||||
for (int i = 0; i < geom->getConvexVolumeCount(); ++i)
|
||||
{
|
||||
if (pointInPoly(vols[i].nverts, vols[i].verts, p) &&
|
||||
p[1] >= vols[i].hmin, p[1] <= vols[i].hmax)
|
||||
{
|
||||
nearestIndex = i;
|
||||
}
|
||||
}
|
||||
// If end point close enough, delete it.
|
||||
if (nearestIndex != -1)
|
||||
{
|
||||
geom->deleteConvexVolume(nearestIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create
|
||||
|
||||
// If clicked on that last pt, create the shape.
|
||||
if (m_npts && vdistSqr(p, &m_pts[(m_npts-1)*3]) < rcSqr(0.2f))
|
||||
{
|
||||
if (m_nhull > 2)
|
||||
{
|
||||
// Create shape.
|
||||
float verts[MAX_PTS*3];
|
||||
for (int i = 0; i < m_nhull; ++i)
|
||||
vcopy(&verts[i*3], &m_pts[m_hull[i]*3]);
|
||||
|
||||
float minh = FLT_MAX, maxh = 0;
|
||||
for (int i = 0; i < m_nhull; ++i)
|
||||
minh = rcMin(minh, verts[i*3+1]);
|
||||
minh -= m_boxDescent;
|
||||
maxh = minh + m_boxHeight;
|
||||
|
||||
geom->addConvexVolume(verts, m_nhull, minh, maxh, (unsigned char)m_areaType);
|
||||
}
|
||||
|
||||
m_npts = 0;
|
||||
m_nhull = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new point
|
||||
if (m_npts < MAX_PTS)
|
||||
{
|
||||
vcopy(&m_pts[m_npts*3], p);
|
||||
m_npts++;
|
||||
// Update hull.
|
||||
if (m_npts > 1)
|
||||
m_nhull = convexhull(m_pts, m_npts, m_hull);
|
||||
else
|
||||
m_nhull = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::handleRender()
|
||||
{
|
||||
DebugDrawGL dd;
|
||||
const float s = m_sample->getAgentRadius();
|
||||
|
||||
// Find height extents of the shape.
|
||||
float minh = FLT_MAX, maxh = 0;
|
||||
for (int i = 0; i < m_npts; ++i)
|
||||
minh = rcMin(minh, m_pts[i*3+1]);
|
||||
minh -= m_boxDescent;
|
||||
maxh = minh + m_boxHeight;
|
||||
|
||||
dd.begin(DU_DRAW_POINTS, 4.0f);
|
||||
for (int i = 0; i < m_npts; ++i)
|
||||
{
|
||||
unsigned int col = duRGBA(255,255,255,255);
|
||||
if (i == m_npts-1)
|
||||
col = duRGBA(240,32,16,255);
|
||||
dd.vertex(m_pts[i*3+0],m_pts[i*3+1]+0.1f,m_pts[i*3+2], col);
|
||||
}
|
||||
dd.end();
|
||||
|
||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int i = 0, j = m_nhull-1; i < m_nhull; j = i++)
|
||||
{
|
||||
const float* vi = &m_pts[m_hull[j]*3];
|
||||
const float* vj = &m_pts[m_hull[i]*3];
|
||||
dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64));
|
||||
dd.vertex(vi[0],minh,vi[2], duRGBA(255,255,255,64));
|
||||
dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64));
|
||||
dd.vertex(vi[0],maxh,vi[2], duRGBA(255,255,255,64));
|
||||
dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64));
|
||||
dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64));
|
||||
}
|
||||
dd.end();
|
||||
}
|
||||
|
||||
void ConvexVolumeTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user