Humble beginnings of box volume too. Allow to save and restore GeomInput state.

This commit is contained in:
Mikko Mononen 2010-01-29 13:58:36 +00:00
parent d6a5eb5ee2
commit 1753297fd5
15 changed files with 1961 additions and 257 deletions

File diff suppressed because it is too large Load Diff

View File

@ -281,14 +281,13 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>32</integer>
<integer>23</integer>
<integer>61</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 247}, {358, 643}}</string>
<string>{{0, 752}, {358, 643}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -323,7 +322,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>Sample_SoloMeshTiled.cpp</string>
<string>InputGeom.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -331,11 +330,11 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>Sample_SoloMeshTiled.cpp</string>
<string>InputGeom.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6BF7C3791112FE75002B3F46</string>
<string>6BF7C4061113209A002B3F46</string>
<key>history</key>
<array>
<string>6B8DE70D10B01BBF00DF20FB</string>
@ -344,7 +343,6 @@
<string>6BBB883C10EA9B6F008FEA1F</string>
<string>6BB7FDC010F37703006DA0A6</string>
<string>6BB7FDC110F37703006DA0A6</string>
<string>6BB7FE1010F37CF7006DA0A6</string>
<string>6BB7FF6D10F4E8E2006DA0A6</string>
<string>6B69739F10FFCA4500984788</string>
<string>6BCF325F1104CFE7009445BF</string>
@ -360,38 +358,39 @@
<string>6BF7C0EF11116E74002B3F46</string>
<string>6BF7C0F011116E74002B3F46</string>
<string>6BF7C0F311116E74002B3F46</string>
<string>6BF7C13411118CEB002B3F46</string>
<string>6BF7C16211119C69002B3F46</string>
<string>6BF7C16C11119D8F002B3F46</string>
<string>6BF7C1CF1111BCF2002B3F46</string>
<string>6BF7C1D01111BCF2002B3F46</string>
<string>6BF7C1E21111BD81002B3F46</string>
<string>6BF7C1ED1111C0A6002B3F46</string>
<string>6BF7C20F1111D361002B3F46</string>
<string>6BF7C2431111DAC1002B3F46</string>
<string>6BF7C2441111DAC1002B3F46</string>
<string>6BF7C2591112B456002B3F46</string>
<string>6BF7C25A1112B456002B3F46</string>
<string>6BF7C25B1112B456002B3F46</string>
<string>6BF7C2761112BE4F002B3F46</string>
<string>6BF7C2851112C348002B3F46</string>
<string>6BF7C2A51112D13E002B3F46</string>
<string>6BF7C2BD1112D453002B3F46</string>
<string>6BF7C2BE1112D453002B3F46</string>
<string>6BF7C2BF1112D453002B3F46</string>
<string>6BF7C2DB1112D4DA002B3F46</string>
<string>6BF7C2EF1112D646002B3F46</string>
<string>6BF7C2F51112D716002B3F46</string>
<string>6BF7C2F61112D716002B3F46</string>
<string>6BF7C3201112DB82002B3F46</string>
<string>6BF7C3211112DB82002B3F46</string>
<string>6BF7C3281112DDCE002B3F46</string>
<string>6BF7C3431112E74B002B3F46</string>
<string>6BF7C35D1112EA84002B3F46</string>
<string>6BF7C36A1112EB0C002B3F46</string>
<string>6BF7C36E1112EB25002B3F46</string>
<string>6BF7C3761112FE75002B3F46</string>
<string>6BF7C3771112FE75002B3F46</string>
<string>6BF7C37C1113026E002B3F46</string>
<string>6BF7C37D1113026E002B3F46</string>
<string>6BF7C392111316AD002B3F46</string>
<string>6BF7C393111316AD002B3F46</string>
<string>6BF7C394111316AD002B3F46</string>
<string>6BF7C395111316AD002B3F46</string>
<string>6BF7C3BC111318BA002B3F46</string>
<string>6BF7C3CC11131F26002B3F46</string>
<string>6BF7C3CD11131F26002B3F46</string>
<string>6BF7C3CE11131F26002B3F46</string>
<string>6BF7C3CF11131F26002B3F46</string>
<string>6BF7C3D011131F26002B3F46</string>
<string>6BF7C3F611131F84002B3F46</string>
<string>6BF7C3FA11132015002B3F46</string>
<string>6BF7C4021113209A002B3F46</string>
<string>6BF7C4031113209A002B3F46</string>
</array>
<key>prevStack</key>
<array>
@ -402,10 +401,7 @@
<string>6BBB885510EA9ECC008FEA1F</string>
<string>6BBB889D10EAA094008FEA1F</string>
<string>6BB7FDC710F37703006DA0A6</string>
<string>6BB7FDD910F37703006DA0A6</string>
<string>6BB7FDDA10F37703006DA0A6</string>
<string>6BB7FDDC10F37703006DA0A6</string>
<string>6BB7FDDD10F37703006DA0A6</string>
<string>6BB7FE1A10F37CF7006DA0A6</string>
<string>6BB7FE2110F37CF7006DA0A6</string>
<string>6BB7FE2210F37CF7006DA0A6</string>
@ -414,7 +410,6 @@
<string>6BB7FF2410F4D699006DA0A6</string>
<string>6BB7FF9610F4E8E2006DA0A6</string>
<string>6BB700C310FA3AB1006DA0A6</string>
<string>6B69739810FFC43600984788</string>
<string>6B6973A210FFCA4500984788</string>
<string>6BCF32441104CDB5009445BF</string>
<string>6BCF324A1104CDB5009445BF</string>
@ -463,7 +458,6 @@
<string>6BF7C14F11119BB4002B3F46</string>
<string>6BF7C15411119BB4002B3F46</string>
<string>6BF7C16611119C69002B3F46</string>
<string>6BF7C16711119C69002B3F46</string>
<string>6BF7C16E11119D8F002B3F46</string>
<string>6BF7C17511119EDD002B3F46</string>
<string>6BF7C17711119EDD002B3F46</string>
@ -486,8 +480,6 @@
<string>6BF7C1F21111C0A6002B3F46</string>
<string>6BF7C15711119BB4002B3F46</string>
<string>6BF7C20B1111D299002B3F46</string>
<string>6BF7C2131111D361002B3F46</string>
<string>6BF7C2141111D361002B3F46</string>
<string>6BF7C2151111D361002B3F46</string>
<string>6BF7C2161111D361002B3F46</string>
<string>6BF7C2171111D361002B3F46</string>
@ -504,12 +496,8 @@
<string>6BF7C2271111D491002B3F46</string>
<string>6BF7C2461111DAC1002B3F46</string>
<string>6BF7C2471111DAC1002B3F46</string>
<string>6BF7C2481111DAC1002B3F46</string>
<string>6BF7C2491111DAC1002B3F46</string>
<string>6BF7C25D1112B456002B3F46</string>
<string>6BF7C25E1112B456002B3F46</string>
<string>6BF7C25F1112B456002B3F46</string>
<string>6BF7C2601112B456002B3F46</string>
<string>6BF7C2701112B56F002B3F46</string>
<string>6BF7C2791112BE4F002B3F46</string>
<string>6BF7C27A1112BE4F002B3F46</string>
@ -517,7 +505,6 @@
<string>6BF7C28A1112C349002B3F46</string>
<string>6BF7C28B1112C349002B3F46</string>
<string>6BF7C28C1112C349002B3F46</string>
<string>6BF7C28D1112C349002B3F46</string>
<string>6BF7C2971112C4A2002B3F46</string>
<string>6BF7C2A81112D13E002B3F46</string>
<string>6BF7C2A91112D13E002B3F46</string>
@ -536,46 +523,89 @@
<string>6BF7C2CB1112D453002B3F46</string>
<string>6BF7C2CD1112D453002B3F46</string>
<string>6BF7C2CF1112D453002B3F46</string>
<string>6BF7C2D01112D453002B3F46</string>
<string>6BF7C2D11112D453002B3F46</string>
<string>6BF7C2D71112D479002B3F46</string>
<string>6BF7C2E21112D520002B3F46</string>
<string>6BF7C2E81112D611002B3F46</string>
<string>6BF7C2E91112D611002B3F46</string>
<string>6BF7C2F11112D646002B3F46</string>
<string>6BF7C2F21112D646002B3F46</string>
<string>6BF7C2F91112D716002B3F46</string>
<string>6BF7C2FA1112D716002B3F46</string>
<string>6BF7C3061112D780002B3F46</string>
<string>6BF7C30C1112D8C1002B3F46</string>
<string>6BF7C30D1112D8C1002B3F46</string>
<string>6BF7C3141112DAFB002B3F46</string>
<string>6BF7C3161112DAFB002B3F46</string>
<string>6BF7C3171112DAFB002B3F46</string>
<string>6BF7C3231112DB82002B3F46</string>
<string>6BF7C3241112DB82002B3F46</string>
<string>6BF7C3251112DB82002B3F46</string>
<string>6BF7C32A1112DDCE002B3F46</string>
<string>6BF7C3371112E571002B3F46</string>
<string>6BF7C33C1112E5D1002B3F46</string>
<string>6BF7C3451112E74B002B3F46</string>
<string>6BF7C3461112E74B002B3F46</string>
<string>6BF7C3471112E74B002B3F46</string>
<string>6BF7C3481112E74B002B3F46</string>
<string>6BF7C3551112E875002B3F46</string>
<string>6BF7C3601112EA84002B3F46</string>
<string>6BF7C3611112EA84002B3F46</string>
<string>6BF7C3621112EA84002B3F46</string>
<string>6BF7C3631112EA84002B3F46</string>
<string>6BF7C3641112EA84002B3F46</string>
<string>6BF7C3651112EA84002B3F46</string>
<string>6BF7C3661112EA84002B3F46</string>
<string>6BF7C3671112EA84002B3F46</string>
<string>6BF7C3681112EA84002B3F46</string>
<string>6BF7C36C1112EB0C002B3F46</string>
<string>6BF7C3701112EB25002B3F46</string>
<string>6BF7C3711112EB25002B3F46</string>
<string>6BF7C3781112FE75002B3F46</string>
<string>6BF7C37F1113026E002B3F46</string>
<string>6BF7C3801113026E002B3F46</string>
<string>6BF7C3811113026E002B3F46</string>
<string>6BF7C38A11130EA2002B3F46</string>
<string>6BF7C390111313CC002B3F46</string>
<string>6BF7C398111316AD002B3F46</string>
<string>6BF7C399111316AD002B3F46</string>
<string>6BF7C39A111316AD002B3F46</string>
<string>6BF7C39B111316AD002B3F46</string>
<string>6BF7C39C111316AD002B3F46</string>
<string>6BF7C39D111316AD002B3F46</string>
<string>6BF7C39E111316AD002B3F46</string>
<string>6BF7C39F111316AD002B3F46</string>
<string>6BF7C3A0111316AD002B3F46</string>
<string>6BF7C3A1111316AD002B3F46</string>
<string>6BF7C3A2111316AD002B3F46</string>
<string>6BF7C3A3111316AD002B3F46</string>
<string>6BF7C3A4111316AD002B3F46</string>
<string>6BF7C3B1111317BF002B3F46</string>
<string>6BB7FDD910F37703006DA0A6</string>
<string>6BF7C16711119C69002B3F46</string>
<string>6BF7C3BE111318BA002B3F46</string>
<string>6BF7C3D511131F26002B3F46</string>
<string>6BF7C3D611131F26002B3F46</string>
<string>6BF7C3D711131F26002B3F46</string>
<string>6BF7C3D811131F26002B3F46</string>
<string>6BF7C3D911131F26002B3F46</string>
<string>6BF7C3DA11131F26002B3F46</string>
<string>6BF7C3DB11131F26002B3F46</string>
<string>6BF7C3DC11131F26002B3F46</string>
<string>6BF7C3DD11131F26002B3F46</string>
<string>6BF7C3DE11131F26002B3F46</string>
<string>6BF7C3DF11131F26002B3F46</string>
<string>6BF7C3E011131F26002B3F46</string>
<string>6BF7C3E111131F26002B3F46</string>
<string>6BF7C3E211131F26002B3F46</string>
<string>6BF7C3E311131F26002B3F46</string>
<string>6BF7C3E411131F26002B3F46</string>
<string>6BF7C3E511131F26002B3F46</string>
<string>6BF7C3E611131F26002B3F46</string>
<string>6BF7C3E711131F26002B3F46</string>
<string>6BF7C3E811131F26002B3F46</string>
<string>6BF7C3E911131F26002B3F46</string>
<string>6BF7C3EA11131F26002B3F46</string>
<string>6BF7C3EB11131F26002B3F46</string>
<string>6BF7C3EC11131F26002B3F46</string>
<string>6BF7C3ED11131F26002B3F46</string>
<string>6BF7C3EE11131F26002B3F46</string>
<string>6BF7C3EF11131F26002B3F46</string>
<string>6BF7C3F011131F26002B3F46</string>
<string>6BF7C3F111131F26002B3F46</string>
<string>6BF7C3F211131F26002B3F46</string>
<string>6BF7C3F311131F26002B3F46</string>
<string>6BF7C3F811131F84002B3F46</string>
<string>6BF7C3FC11132015002B3F46</string>
<string>6BF7C4041113209A002B3F46</string>
<string>6BF7C4051113209A002B3F46</string>
</array>
</dict>
<key>SplitCount</key>
@ -589,18 +619,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {876, 502}}</string>
<string>{{0, 0}, {876, 563}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>502pt</string>
<string>563pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>154pt</string>
<string>93pt</string>
<key>Tabs</key>
<array>
<dict>
@ -668,7 +698,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {876, 127}}</string>
<string>{{10, 27}, {876, 66}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>

View File

@ -42,6 +42,7 @@
6BB93CF610CFEC4500F74F2B /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93CF510CFEC4500F74F2B /* RecastDump.cpp */; };
6BCF32361104CD05009445BF /* OffMeshConnectionTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */; };
6BF7C1401111953A002B3F46 /* TestCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BF7C13F1111953A002B3F46 /* TestCase.cpp */; };
6BF7C3C511131B1F002B3F46 /* BoxVolumeTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BF7C3C411131B1F002B3F46 /* BoxVolumeTool.cpp */; };
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
/* End PBXBuildFile section */
@ -113,6 +114,8 @@
6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OffMeshConnectionTool.cpp; path = ../../Source/OffMeshConnectionTool.cpp; sourceTree = SOURCE_ROOT; };
6BF7C13E11119520002B3F46 /* TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestCase.h; path = ../../Include/TestCase.h; sourceTree = SOURCE_ROOT; };
6BF7C13F1111953A002B3F46 /* TestCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TestCase.cpp; path = ../../Source/TestCase.cpp; sourceTree = SOURCE_ROOT; };
6BF7C3C311131B0F002B3F46 /* BoxVolumeTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoxVolumeTool.h; path = ../../Include/BoxVolumeTool.h; sourceTree = SOURCE_ROOT; };
6BF7C3C411131B1F002B3F46 /* BoxVolumeTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoxVolumeTool.cpp; path = ../../Source/BoxVolumeTool.cpp; sourceTree = SOURCE_ROOT; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* Recast.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recast.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@ -268,6 +271,8 @@
6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */,
6BB7FC0910EBB6AA006DA0A6 /* NavMeshTesterTool.h */,
6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */,
6BF7C3C311131B0F002B3F46 /* BoxVolumeTool.h */,
6BF7C3C411131B1F002B3F46 /* BoxVolumeTool.cpp */,
);
name = Tools;
sourceTree = "<group>";
@ -389,6 +394,7 @@
6BB7FDA510F36F0E006DA0A6 /* InputGeom.cpp in Sources */,
6BCF32361104CD05009445BF /* OffMeshConnectionTool.cpp in Sources */,
6BF7C1401111953A002B3F46 /* TestCase.cpp in Sources */,
6BF7C3C511131B1F002B3F46 /* BoxVolumeTool.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,47 @@
//
// 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 BOXVOLUMETOOL_H
#define BOXVOLUMETOOL_H
#include "Sample.h"
// Tool to create box volumess for InputGeom
class BoxVolumeTool : public SampleTool
{
Sample* m_sample;
float m_hitPos[3];
bool m_hitPosSet;
float m_areaType;
float m_boxHeight;
public:
BoxVolumeTool();
~BoxVolumeTool();
virtual int type() { return TOOL_BOX_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 // BOXVOLUMETOOL_H

View File

@ -28,12 +28,18 @@ class InputGeom
rcMeshLoaderObj* m_mesh;
float m_meshBMin[3], m_meshBMax[3];
// Off-Mesh connections.
static const int MAX_OFFMESH_CONNECTIONS = 256;
float m_offMeshConVerts[MAX_OFFMESH_CONNECTIONS*3*2];
float m_offMeshConRads[MAX_OFFMESH_CONNECTIONS];
unsigned char m_offMeshConDirs[MAX_OFFMESH_CONNECTIONS];
int m_offMeshConCount;
// Box Volumes.
static const int MAX_BOX_VOLUMES = 256;
float m_boxVolVerts[MAX_BOX_VOLUMES*3*2];
unsigned char m_boxVolTypes[MAX_BOX_VOLUMES];
int m_boxVolCount;
public:
InputGeom();
@ -41,6 +47,9 @@ public:
bool loadMesh(const char* filepath);
bool load(const char* filepath);
bool save(const char* filepath);
// Method to return static mesh data.
inline const rcMeshLoaderObj* getMesh() const { return m_mesh; }
inline const float* getMeshBoundsMin() const { return m_meshBMin; }
@ -48,7 +57,7 @@ public:
inline const rcChunkyTriMesh* getChunkyMesh() const { return m_chunkyMesh; }
bool raycastMesh(float* src, float* dst, float& tmin);
// Extra links
// Off-Mesh connections.
int getOffMeshConnectionCount() const { return m_offMeshConCount; }
const float* getOffMeshConnectionVerts() const { return m_offMeshConVerts; }
const float* getOffMeshConnectionRads() const { return m_offMeshConRads; }
@ -56,6 +65,14 @@ public:
void addOffMeshConnection(const float* spos, const float* epos, const float rad, unsigned char bidir);
void deleteOffMeshConnection(int i);
void drawOffMeshConnections(struct duDebugDraw* dd, bool hilight = false);
// Box Volumes.
int getBoxVolumeCount() const { return m_boxVolCount; }
const float* getBoxVolumeVerts() const { return m_boxVolVerts; }
const unsigned char* getBoxVolumeTypes() const { return m_boxVolTypes; }
void addBoxVolume(const float* bmin, const float* bmax, unsigned char type);
void deleteBoxVolume(int i);
void drawBoxVolumes(struct duDebugDraw* dd, bool hilight = false);
};
#endif // INPUTGEOM_H

View File

@ -32,12 +32,14 @@ public:
inline const int* getTris() const { return m_tris; }
inline int getVertCount() const { return m_vertCount; }
inline int getTriCount() const { return m_triCount; }
inline const char* getFileName() const { return m_filename; }
private:
void addVertex(float x, float y, float z, int& cap);
void addTriangle(int a, int b, int c, int& cap);
char m_filename[260];
float* m_verts;
int* m_tris;

View File

@ -21,7 +21,7 @@
#include "Sample.h"
// Tool to create extra links for InputGeom
// Tool to create off-mesh connection for InputGeom
class OffMeshConnectionTool : public SampleTool
{

View File

@ -37,6 +37,7 @@ enum SampleToolType
TOOL_TILE_EDIT,
TOOL_NAVMESH_TESTER,
TOOL_OFFMESH_CONNECTION,
TOOL_BOX_VOLUME,
};
struct SampleTool
@ -89,7 +90,6 @@ public:
virtual void handleRenderOverlay(double* proj, double* model, int* view);
virtual void handleMeshChanged(class InputGeom* geom);
virtual bool handleBuild();
// virtual void handleNavMeshChanged();
virtual class InputGeom* getInputGeom() { return m_geom; }
virtual class dtNavMesh* getNavMesh() { return m_navMesh; }

View File

@ -0,0 +1,152 @@
//
// 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 "BoxVolumeTool.h"
#include "InputGeom.h"
#include "Sample.h"
#include "Recast.h"
#include "RecastDebugDraw.h"
#include "DetourDebugDraw.h"
#ifdef WIN32
# define snprintf _snprintf
#endif
BoxVolumeTool::BoxVolumeTool() :
m_sample(0),
m_hitPosSet(0),
m_areaType(1),
m_boxHeight(5.0f)
{
}
BoxVolumeTool::~BoxVolumeTool()
{
}
void BoxVolumeTool::init(Sample* sample)
{
m_sample = sample;
}
void BoxVolumeTool::reset()
{
m_hitPosSet = false;
}
void BoxVolumeTool::handleMenu()
{
imguiSlider("Box Height", &m_boxHeight, 0.1f, 20.0f, 0.1f);
imguiSlider("Area Type", &m_areaType, 1.0f, 20.0f, 1.0f);
if (!m_hitPosSet)
{
imguiValue("Click to set connection start.");
}
else
{
imguiValue("Click to set connection end.");
}
}
void BoxVolumeTool::handleClick(const float* p, bool shift)
{
if (!m_sample) return;
InputGeom* geom = m_sample->getInputGeom();
if (!geom) return;
if (shift)
{
// Delete
// Find nearest link end-point
int nearestIndex = -1;
const float* verts = geom->getBoxVolumeVerts();
for (int i = 0; i < geom->getBoxVolumeCount(); ++i)
{
const float* bmin = &verts[(i*2+0)*3];
const float* bmax = &verts[(i*2+1)*3];
if (p[0] >= bmin[0] && p[0] <= bmax[0] &&
p[1] >= bmin[1] && p[1] <= bmax[1] &&
p[2] >= bmin[2] && p[2] <= bmax[2])
{
nearestIndex = i; // Each link has two vertices.
}
}
// If end point close enough, delete it.
if (nearestIndex != -1)
{
geom->deleteBoxVolume(nearestIndex);
}
}
else
{
// Create
if (!m_hitPosSet)
{
vcopy(m_hitPos, p);
m_hitPosSet = true;
}
else
{
float bmin[3], bmax[3];
vcopy(bmin, m_hitPos);
vcopy(bmax, m_hitPos);
vmin(bmin, p);
vmax(bmax, p);
bmin[1] -= m_boxHeight/4.0f;
bmax[1] = bmin[1]+m_boxHeight;
geom->addBoxVolume(bmin, bmax, (unsigned char)m_areaType);
m_hitPosSet = false;
}
}
}
void BoxVolumeTool::handleRender()
{
DebugDrawGL dd;
const float s = m_sample->getAgentRadius();
if (m_hitPosSet)
duDebugDrawCross(&dd, m_hitPos[0],m_hitPos[1]+0.1f,m_hitPos[2], s, duRGBA(0,0,0,128), 2.0f);
InputGeom* geom = m_sample->getInputGeom();
if (geom)
geom->drawBoxVolumes(&dd, true);
}
void BoxVolumeTool::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
// Draw start and end point labels
if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
model, proj, view, &x, &y, &z))
{
imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220));
}
}

View File

@ -18,6 +18,8 @@
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdio.h>
#include <ctype.h>
#include "Recast.h"
#include "RecastLog.h"
#include "InputGeom.h"
@ -67,12 +69,46 @@ static bool intersectSegmentTriangle(const float* sp, const float* sq,
return true;
}
static char* parseRow(char* buf, char* bufEnd, char* row, int len)
{
bool start = true;
bool done = false;
int n = 0;
while (!done && buf < bufEnd)
{
char c = *buf;
buf++;
// multirow
switch (c)
{
case '\n':
if (start) break;
done = true;
break;
case '\r':
break;
case '\t':
case ' ':
if (start) break;
default:
start = false;
row[n++] = c;
if (n >= len-1)
done = true;
break;
}
}
row[n] = '\0';
return buf;
}
InputGeom::InputGeom() :
m_chunkyMesh(0),
m_mesh(0),
m_offMeshConCount(0)
m_offMeshConCount(0),
m_boxVolCount(0)
{
}
@ -92,6 +128,7 @@ bool InputGeom::loadMesh(const char* filepath)
m_mesh = 0;
}
m_offMeshConCount = 0;
m_boxVolCount = 0;
m_mesh = new rcMeshLoaderObj;
if (!m_mesh)
@ -125,7 +162,123 @@ bool InputGeom::loadMesh(const char* filepath)
return true;
}
bool InputGeom::load(const char* filePath)
{
char* buf = 0;
FILE* fp = fopen(filePath, "rb");
if (!fp)
return false;
fseek(fp, 0, SEEK_END);
int bufSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
buf = new char[bufSize];
if (!buf)
{
fclose(fp);
return false;
}
fread(buf, bufSize, 1, fp);
fclose(fp);
m_offMeshConCount = 0;
m_boxVolCount = 0;
delete m_mesh;
m_mesh = 0;
char* src = buf;
char* srcEnd = buf + bufSize;
char row[512];
while (src < srcEnd)
{
// Parse one row
row[0] = '\0';
src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
if (row[0] == 'f')
{
// File name.
const char* name = row+1;
// Skip white spaces
while (*name && isspace(*name))
name++;
if (*name)
{
if (!loadMesh(name))
{
delete [] buf;
return false;
}
}
}
else if (row[0] == 'c')
{
// Off-mesh connection
if (m_offMeshConCount < MAX_OFFMESH_CONNECTIONS)
{
float* v = &m_offMeshConVerts[m_offMeshConCount*3*2];
int bidir;
float rad;
sscanf(row+1, "%f %f %f %f %f %f %f %d",
&v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &rad, &bidir);
m_offMeshConRads[m_offMeshConCount] = rad;
m_offMeshConDirs[m_offMeshConCount] = bidir;
m_offMeshConCount++;
}
}
else if (row[0] == 'b')
{
// Box volumes
if (m_boxVolCount < MAX_BOX_VOLUMES)
{
float* v = &m_boxVolVerts[m_boxVolCount*3*2];
int type;
sscanf(row+1, "%f %f %f %f %f %f %d",
&v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &type);
m_boxVolTypes[m_boxVolCount] = (unsigned char)type;
m_boxVolCount++;
}
}
}
delete [] buf;
return true;
}
bool InputGeom::save(const char* filepath)
{
if (!m_mesh) return false;
FILE* fp = fopen(filepath, "w");
if (!fp) return false;
// Store mesh filename.
fprintf(fp, "f %s\n", m_mesh->getFileName());
// Store off-mesh links.
for (int i = 0; i < m_offMeshConCount; ++i)
{
const float* v = &m_offMeshConVerts[i*3*2];
const float rad = m_offMeshConRads[i];
const int bidir = m_offMeshConDirs[i];
fprintf(fp, "c %f %f %f %f %f %f %f %d\n",
v[0], v[1], v[2], v[3], v[4], v[5], rad, bidir);
}
// Box volumes
for (int i = 0; i < m_boxVolCount; ++i)
{
const float* v = &m_boxVolVerts[i*3*2];
const int bidir = m_boxVolTypes[i];
fprintf(fp, "b %f %f %f %f %f %f %d\n",
v[0], v[1], v[2], v[3], v[4], v[5], bidir);
}
fclose(fp);
return true;
}
bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
{
float dir[3];
@ -211,3 +364,39 @@ void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool hilight)
dd->depthMask(true);
}
void InputGeom::addBoxVolume(const float* bmin, const float* bmax, unsigned char type)
{
if (m_boxVolCount >= MAX_OFFMESH_CONNECTIONS) return;
float* v = &m_boxVolVerts[m_boxVolCount*3*2];
m_boxVolTypes[m_boxVolCount] = type;
vcopy(&v[0], bmin);
vcopy(&v[3], bmax);
m_boxVolCount++;
}
void InputGeom::deleteBoxVolume(int i)
{
m_boxVolCount--;
float* src = &m_boxVolVerts[m_boxVolCount*3*2];
float* dst = &m_boxVolVerts[i*3*2];
vcopy(&dst[0], &src[0]);
vcopy(&dst[3], &src[3]);
m_boxVolTypes[i] = m_boxVolTypes[m_boxVolCount];
}
void InputGeom::drawBoxVolumes(struct duDebugDraw* dd, bool hilight)
{
dd->depthMask(false);
dd->begin(DU_DRAW_LINES, 1.0f);
for (int i = 0; i < m_boxVolCount; ++i)
{
unsigned int col = duIntToCol(m_boxVolTypes[i], 220);
const float* bounds = &m_boxVolVerts[i*3*2];
duAppendBoxWire(dd, bounds[0],bounds[1],bounds[2],bounds[3],bounds[4],bounds[5], col);
}
dd->end();
dd->depthMask(true);
}

View File

@ -215,5 +215,8 @@ bool rcMeshLoaderObj::load(const char* filename)
}
}
strncpy(m_filename, filename, sizeof(m_filename));
m_filename[sizeof(m_filename)-1] = '\0';
return true;
}

View File

@ -112,8 +112,6 @@ void OffMeshConnectionTool::handleClick(const float* p, bool shift)
{
geom->deleteOffMeshConnection(nearestIndex);
}
// geom->updateOffMeshConnectionVisibility(m_sample->getNavMesh());
}
else
{
@ -127,7 +125,6 @@ void OffMeshConnectionTool::handleClick(const float* p, bool shift)
{
geom->addOffMeshConnection(m_hitPos, p, m_sample->getAgentRadius(), m_bidir ? 1 : 0);
m_hitPosSet = false;
// geom->updateOffMeshConnectionVisibility(m_sample->getNavMesh());
}
}

View File

@ -35,6 +35,7 @@
#include "DetourDebugDraw.h"
#include "NavMeshTesterTool.h"
#include "OffMeshConnectionTool.h"
#include "BoxVolumeTool.h"
#ifdef WIN32
# define snprintf _snprintf
@ -99,6 +100,10 @@ void Sample_SoloMeshSimple::handleTools()
{
setTool(new OffMeshConnectionTool);
}
if (imguiCheck("Create Box Volumes", type == TOOL_BOX_VOLUME))
{
setTool(new BoxVolumeTool);
}
imguiSeparator();
@ -198,6 +203,7 @@ void Sample_SoloMeshSimple::handleRender()
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope);
m_geom->drawOffMeshConnections(&dd);
m_geom->drawBoxVolumes(&dd);
}
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{
@ -205,6 +211,7 @@ void Sample_SoloMeshSimple::handleRender()
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd);
m_geom->drawBoxVolumes(&dd);
}
glDisable(GL_FOG);

View File

@ -256,6 +256,49 @@ int main(int argc, char *argv[])
showTestCases = true;
scanDirectory("Tests", ".txt", files);
}
else if (event.key.keysym.sym == SDLK_1)
{
if (geom)
geom->save("geomset.txt");
}
else if (event.key.keysym.sym == SDLK_2)
{
delete geom;
geom = new InputGeom;
if (!geom || !geom->load("geomset.txt"))
{
delete geom;
geom = 0;
showLog = true;
logScroll = 0;
printf("Geom load log %s:\n", meshName);
for (int i = 0; i < log.getMessageCount(); ++i)
printf("%s\n", log.getMessageText(i));
}
if (sample && geom)
{
sample->handleMeshChanged(geom);
}
if (geom)
{
const float* bmin = geom->getMeshBoundsMin();
const float* bmax = geom->getMeshBoundsMax();
// Reset camera and fog to match the mesh bounds.
camr = sqrtf(rcSqr(bmax[0]-bmin[0]) +
rcSqr(bmax[1]-bmin[1]) +
rcSqr(bmax[2]-bmin[2])) / 2;
camx = (bmax[0] + bmin[0]) / 2 + camr;
camy = (bmax[1] + bmin[1]) / 2 + camr;
camz = (bmax[2] + bmin[2]) / 2 + camr;
camr *= 3;
rx = 45;
ry = -45;
glFogf(GL_FOG_START, camr*0.2f);
glFogf(GL_FOG_END, camr*1.25f);
}
}
break;
case SDL_MOUSEBUTTONDOWN: