Skip to content

Commit 30fed8f

Browse files
committed
scene picking (wip)
1 parent fdf88b5 commit 30fed8f

File tree

12 files changed

+196
-30
lines changed

12 files changed

+196
-30
lines changed

sources/asset-processor/model.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "processor.h"
44

5+
#include <cage-core/collider.h>
56
#include <cage-core/flatSet.h>
67
#include <cage-core/hashString.h>
78
#include <cage-core/mesh.h>
@@ -332,6 +333,21 @@ void processModel()
332333

333334
CAGE_LOG(SeverityEnum::Info, "assetProcessor", Stringizer() + "bounding box: " + part.boundingBox);
334335

336+
Holder<PointerRange<const char>> serMesh = part.mesh->exportBuffer();
337+
dsm.meshSize = serMesh.size();
338+
339+
Holder<PointerRange<const char>> serCol;
340+
if (part.mesh->type() == MeshTypeEnum::Triangles)
341+
{
342+
CAGE_LOG(SeverityEnum::Info, "assetProcessor", "building collider");
343+
Holder<Collider> collider = newCollider();
344+
collider->importMesh(+part.mesh);
345+
collider->optimize();
346+
collider->rebuild();
347+
serCol = collider->exportBuffer();
348+
dsm.colliderSize = serCol.size();
349+
}
350+
335351
CAGE_LOG(SeverityEnum::Info, "assetProcessor", "serializing");
336352
AssetHeader h = processor->initializeAssetHeader();
337353
for (uint32 i = 0; i < MaxTexturesCountPerMaterial; i++)
@@ -343,7 +359,9 @@ void processModel()
343359
Serializer ser(buffer);
344360
ser << dsm;
345361
ser << mat;
346-
ser.write(part.mesh->exportBuffer());
362+
ser.write(serMesh);
363+
if (serMesh)
364+
ser.write(serCol);
347365
h.originalSize = buffer.size();
348366
Holder<PointerRange<char>> compressed = memoryCompress(buffer);
349367
h.compressedSize = compressed.size();

sources/include/cage-core/core.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
} \
2020
}
2121
#else
22-
#define CAGE_ASSERT(EXPR) {}
22+
#define CAGE_ASSERT(EXPR) \
23+
{ \
24+
(void)(true ? (void)0 : (void)(EXPR)); \
25+
}
2326
#endif
2427

2528
#define CAGE_THROW_SILENT(EXCEPTION, ...) \

sources/include/cage-engine/assetStructs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,13 @@ namespace cage
7676
sint32 renderLayer = 0;
7777
uint32 skeletonBones = 0;
7878
uint32 materialSize = 0; // bytes
79+
uint32 meshSize = 0; // bytes
80+
uint32 colliderSize = 0; // bytes
7981

8082
// follows:
8183
// material (may or may not be the MeshImportMaterial)
8284
// serialized mesh
85+
// serialized collider (may be absent)
8386
};
8487

8588
struct CAGE_ENGINE_API RenderObjectHeader

sources/include/cage-engine/model.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#ifndef guard_model_h_sdx54gfgh24jksd5f4
22
#define guard_model_h_sdx54gfgh24jksd5f4
33

4+
#include <cage-core/geometry.h>
45
#include <cage-engine/core.h>
56

67
namespace cage
78
{
89
class Mesh;
10+
class Collider;
911
enum class MeshRenderFlags : uint32;
1012

1113
class CAGE_ENGINE_API Model : private Immovable
@@ -19,22 +21,24 @@ namespace cage
1921
uint32 id() const;
2022
void bind() const;
2123

22-
void importMesh(const Mesh *poly, PointerRange<const char> materialBuffer);
24+
void importMesh(const Mesh *mesh, PointerRange<const char> materialBuffer);
2325

2426
void setPrimitiveType(uint32 type);
25-
void setBoundingBox(const Aabb &box);
2627
void setBuffers(uint32 vertexSize, PointerRange<const char> vertexData, PointerRange<const uint32> indexData, PointerRange<const char> materialBuffer);
2728
void setAttribute(uint32 index, uint32 size, uint32 type, uint32 stride, uint32 startOffset);
2829

2930
uint32 verticesCount() const;
3031
uint32 indicesCount() const;
3132
uint32 primitivesCount() const;
32-
Aabb boundingBox() const;
3333

3434
void dispatch() const;
3535
void dispatch(uint32 instances) const;
3636

37+
Holder<const Mesh> mesh;
38+
Holder<const Collider> collider;
39+
3740
Mat4 importTransform;
41+
Aabb boundingBox = Aabb::Universe();
3842
uint32 textureNames[MaxTexturesCountPerMaterial] = {};
3943
uint32 shaderName = 0;
4044
MeshRenderFlags flags = {};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef guard_scenePicking_h_dzjlhgfds
2+
#define guard_scenePicking_h_dzjlhgfds
3+
4+
#include <cage-core/entities.h>
5+
#include <cage-core/geometry.h>
6+
#include <cage-engine/scene.h>
7+
8+
namespace cage
9+
{
10+
class Mesh;
11+
12+
struct CAGE_ENGINE_API PickableComponent
13+
{};
14+
15+
/*
16+
enum class ScenePickingPrecisionEnum
17+
{
18+
None = 0,
19+
BoundingBoxesOnly,
20+
BoundingMeshesOnly,
21+
Models,
22+
ModelsWithAlphaCut,
23+
ModelsWithAnimations,
24+
ModelsWithAnimationsAndAlphaCut,
25+
};
26+
*/
27+
28+
struct CAGE_ENGINE_API ScenePickingConfig
29+
{
30+
Line picker;
31+
const AssetsManager *assets = nullptr;
32+
const EntityManager *entities = nullptr;
33+
//ScenePickingPrecisionEnum precision = ScenePickingPrecisionEnum::Models;
34+
35+
// used for lod selection
36+
const Entity *camera = nullptr;
37+
uint32 screenHeight = 0;
38+
};
39+
40+
struct CAGE_ENGINE_API ScenePickingResult
41+
{
42+
Vec3 point;
43+
Entity *entity = nullptr;
44+
};
45+
46+
CAGE_ENGINE_API Holder<PointerRange<ScenePickingResult>> scenePicking(const ScenePickingConfig &config);
47+
}
48+
49+
#endif // guard_scenePicking_h_dzjlhgfds

sources/libcore/assets/assetsManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ namespace cage
811811

812812
namespace
813813
{
814-
constexpr uint32 CurrentAssetVersion = 1;
814+
constexpr uint32 CurrentAssetVersion = 2;
815815

816816
void defaultFetch(AssetContext *asset)
817817
{

sources/libengine/assets/model.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cage-core/assetContext.h>
2+
#include <cage-core/collider.h>
23
#include <cage-core/memoryBuffer.h>
34
#include <cage-core/mesh.h>
45
#include <cage-core/serialization.h>
@@ -23,12 +24,22 @@ namespace cage
2324
des.read(mat);
2425

2526
Holder<Mesh> mesh = newMesh();
26-
mesh->importBuffer(des.read(des.available()));
27-
27+
mesh->importBuffer(des.read(data.meshSize));
2828
model->importMesh(+mesh, mat);
29-
model->setBoundingBox(data.box);
29+
model->mesh = std::move(mesh);
30+
31+
if (data.colliderSize)
32+
{
33+
Holder<Collider> col = newCollider();
34+
col->importBuffer(des.read(data.colliderSize));
35+
col->rebuild();
36+
model->collider = std::move(col);
37+
}
38+
39+
CAGE_ASSERT(des.available() == 0);
3040

3141
model->importTransform = data.importTransform;
42+
model->boundingBox = data.box;
3243
for (int i = 0; i < MaxTexturesCountPerMaterial; i++)
3344
model->textureNames[i] = data.textureNames[i];
3445
model->shaderName = data.shaderName;

sources/libengine/graphics/model.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ namespace cage
2222
class ModelImpl : public Model
2323
{
2424
public:
25-
Aabb box = Aabb::Universe();
2625
uint32 id = 0;
2726
uint32 vbo = 0;
2827
uint32 verticesCount = 0;
@@ -213,7 +212,7 @@ namespace cage
213212
for (const Attr &a : attrs)
214213
setAttribute(a.index, a.count, a.type, a.stride, a.offset);
215214

216-
setBoundingBox(poly->boundingBox());
215+
boundingBox = poly->boundingBox();
217216
}
218217

219218
void Model::setPrimitiveType(uint32 type)
@@ -223,15 +222,10 @@ namespace cage
223222
impl->updatePrimitivesCount();
224223
}
225224

226-
void Model::setBoundingBox(const Aabb &box)
227-
{
228-
ModelImpl *impl = (ModelImpl *)this;
229-
impl->box = box;
230-
}
231-
232225
void Model::setBuffers(uint32 vertexSize, PointerRange<const char> vertexData, PointerRange<const uint32> indexData, PointerRange<const char> materialBuffer)
233226
{
234227
ModelImpl *impl = (ModelImpl *)this;
228+
impl->mesh.clear();
235229
{
236230
if (impl->vbo)
237231
{
@@ -329,12 +323,6 @@ namespace cage
329323
return impl->primitivesCount;
330324
}
331325

332-
Aabb Model::boundingBox() const
333-
{
334-
const ModelImpl *impl = (const ModelImpl *)this;
335-
return impl->box;
336-
}
337-
338326
void Model::dispatch() const
339327
{
340328
const ModelImpl *impl = (const ModelImpl *)this;

sources/libengine/graphics/renderPipeline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ namespace cage
821821
return;
822822

823823
const Mat4 mvpMat = viewProj * rd.model;
824-
if (!intersects(rm.mesh->boundingBox(), Frustum(mvpMat)))
824+
if (!intersects(rm.mesh->boundingBox, Frustum(mvpMat)))
825825
return;
826826

827827
std::optional<SkeletalAnimationComponent> ps;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include <algorithm>
2+
3+
#include <cage-core/assetsManager.h>
4+
#include <cage-core/entitiesVisitor.h>
5+
#include <cage-core/pointerRangeHolder.h>
6+
#include <cage-engine/model.h>
7+
#include <cage-engine/renderObject.h>
8+
#include <cage-engine/scenePicking.h>
9+
10+
namespace cage
11+
{
12+
namespace
13+
{
14+
struct Boxes
15+
{
16+
const AssetsManager *assets = nullptr;
17+
18+
Aabb model(uint32 name) const
19+
{
20+
Holder<Model> m = assets->get<AssetSchemeIndexModel, Model>(name);
21+
if (!m)
22+
return Aabb();
23+
return m->boundingBox;
24+
}
25+
26+
Aabb object(const RenderObject *o) const
27+
{
28+
if (!o)
29+
return Aabb();
30+
Aabb res;
31+
for (uint32 i = 0; i < o->lodsCount(); i++) // not sure which LOD is loaded, so we need to check all
32+
for (uint32 it : o->models(i))
33+
res += model(it);
34+
return res;
35+
}
36+
37+
Aabb asset(uint32 name) const
38+
{
39+
if (name == 0)
40+
return Aabb();
41+
{
42+
Holder<Model> m = assets->get<AssetSchemeIndexModel, Model>(name);
43+
if (m)
44+
return m->boundingBox;
45+
}
46+
{
47+
Holder<RenderObject> o = assets->get<AssetSchemeIndexRenderObject, RenderObject>(name);
48+
if (o)
49+
return object(+o);
50+
}
51+
return Aabb();
52+
}
53+
};
54+
}
55+
56+
Holder<PointerRange<ScenePickingResult>> scenePicking(const ScenePickingConfig &config)
57+
{
58+
CAGE_ASSERT(config.picker.valid());
59+
CAGE_ASSERT(config.assets);
60+
CAGE_ASSERT(config.entities);
61+
CAGE_ASSERT(!config.camera || config.camera->manager() == config.entities);
62+
CAGE_ASSERT(!config.camera || config.screenHeight > 0);
63+
64+
PointerRangeHolder<ScenePickingResult> results;
65+
66+
entitiesVisitor(
67+
[&](Entity *e, const TransformComponent &tr, const ModelComponent &md, const PickableComponent &)
68+
{
69+
// todo respect different precisions
70+
// todo animations and alpha cut
71+
const Aabb box = Boxes{ config.assets }.asset(md.model) * tr;
72+
const Line ln = intersection(box, config.picker);
73+
if (!ln.valid())
74+
return;
75+
ScenePickingResult r;
76+
r.entity = e;
77+
r.point = ln.a();
78+
results.push_back(r);
79+
},
80+
config.entities, false);
81+
82+
// todo entities with icons instead of models
83+
84+
if (!results.empty())
85+
std::sort(results.begin(), results.end(), [&](const ScenePickingResult &a, const ScenePickingResult &b) -> bool { return distanceSquared(a.point, config.picker.a()) < distanceSquared(b.point, config.picker.b()); });
86+
return results;
87+
}
88+
}

0 commit comments

Comments
 (0)