Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
3.0 kB · 76 lines
C++
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#include "recastmesh.hpp"
#include "detourdebugdraw.hpp"
#include <components/detournavigator/recastmesh.hpp>#include <components/detournavigator/recastmeshbuilder.hpp>#include <components/detournavigator/settings.hpp>#include <components/sceneutil/material.hpp>
#include <RecastDebugDraw.h>
#include <osg/Group>#include <osg/PolygonOffset>
#include <algorithm>#include <vector>
namespace{ std::vector<float> calculateNormals(const std::vector<float>& vertices, const std::vector<int>& indices) { std::vector<float> result(indices.size()); for (std::size_t i = 0, n = indices.size(); i < n; i += 3) { const float* v0Ptr = &vertices[indices[i] * 3]; const float* v1Ptr = &vertices[indices[i + 1] * 3]; const float* v2Ptr = &vertices[indices[i + 2] * 3]; const osg::Vec3f v0(v0Ptr[0], v0Ptr[1], v0Ptr[2]); const osg::Vec3f v1(v1Ptr[0], v1Ptr[1], v1Ptr[2]); const osg::Vec3f v2(v2Ptr[0], v2Ptr[1], v2Ptr[2]); const osg::Vec3f e0 = v1 - v0; const osg::Vec3f e1 = v2 - v0; osg::Vec3f normal = e0 ^ e1; normal.normalize(); for (int j = 0; j < 3; ++j) result[i + j] = normal[j]; } return result; }}
namespace SceneUtil{ osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh, const DetourNavigator::RecastSettings& settings, const osg::ref_ptr<osg::StateSet>& debugDrawStateSet) { using namespace DetourNavigator;
const osg::ref_ptr<osg::Group> group(new osg::Group);
DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, 0), 1.0f); const DetourNavigator::Mesh& mesh = recastMesh.getMesh(); std::vector<int> indices = mesh.getIndices(); std::vector<float> vertices = mesh.getVertices();
for (const Heightfield& heightfield : recastMesh.getHeightfields()) { const Mesh heightfieldMesh = makeMesh(heightfield); const int indexShift = static_cast<int>(vertices.size() / 3); std::copy(heightfieldMesh.getVertices().begin(), heightfieldMesh.getVertices().end(), std::back_inserter(vertices)); std::transform(heightfieldMesh.getIndices().begin(), heightfieldMesh.getIndices().end(), std::back_inserter(indices), [&](int index) { return index + indexShift; }); }
for (std::size_t i = 0; i < vertices.size(); i += 3) std::swap(vertices[i + 1], vertices[i + 2]);
const auto normals = calculateNormals(vertices, indices); const auto texScale = 1.0f / (settings.mCellSize * 10.0f); duDebugDrawTriMeshSlope(&debugDraw, vertices.data(), static_cast<int>(vertices.size() / 3), indices.data(), normals.data(), static_cast<int>(indices.size() / 3), settings.mMaxSlope, texScale);
return group; }}