watch out for killer zombie squirells

This commit is contained in:
Mikulas Florek 2018-09-20 23:17:45 +02:00
parent 98abdb552f
commit 08b2f3dde3
18 changed files with 268 additions and 243 deletions

View file

@ -192,14 +192,14 @@ struct EditorIconsImpl final : public EditorIcons
hit.entity = INVALID_ENTITY;
const Viewport& vp = m_editor.getViewport();
Matrix camera_mtx = vp.rot.toMatrix();
for(auto& icon : m_icons) {
const Transform icon_tr = getIconTransform(icon, vp.rot, vp.is_ortho, vp.ortho_size);
const Vec3 rel_origin = (origin - icon_tr.pos).toFloat();
const Vec3 rel_origin = icon_tr.rot.conjugated() * (origin - icon_tr.pos).toFloat();
const Vec3 rel_dir = icon_tr.rot.conjugated() * dir;
float t = m_editor.getRenderInterface()->castRay(m_models[(int)icon.type], rel_origin, rel_dir, nullptr);
RenderInterface* ri = m_editor.getRenderInterface();
const float t = ri->castRay(m_models[(int)icon.type], rel_origin, rel_dir, nullptr);
if (t >= 0 && (t < hit.t || hit.t < 0)) {
hit.t = t;
hit.entity = icon.entity;

View file

@ -35,7 +35,6 @@ public:
virtual bool isCameraOrtho(EntityRef entity) = 0;
virtual float getCameraOrthoSize(EntityRef entity) = 0;
virtual Vec2 getCameraScreenSize(EntityRef entity) = 0;
virtual void getRay(EntityRef entity, const Vec2& screen_pos, DVec3& origin, Vec3& dir) = 0;
virtual float castRay(ModelHandle model, const Vec3& origin, const Vec3& dir, const Pose* pose) = 0;
virtual void renderModel(ModelHandle model, const Matrix& mtx) = 0;
virtual ModelHandle loadModel(Path& path) = 0;
@ -64,7 +63,7 @@ public:
virtual void addRect2D(const Vec2& a, const Vec2& b, u32 color) = 0;
virtual void addRectFilled2D(const Vec2& a, const Vec2& b, u32 color) = 0;
virtual void getModelInstaces(Array<EntityRef>& entity, const ShiftedFrustum& frustum, const DVec3& lod_ref_point, float fov, bool is_ortho) = 0;
virtual Frustum getFrustum(EntityRef camera, const Vec2& a, const Vec2& b) = 0;
virtual ShiftedFrustum getFrustum(EntityRef camera, const Vec2& a, const Vec2& b) = 0;
};

View file

@ -1942,7 +1942,7 @@ public:
DVec3 origin;
Vec3 dir;
m_viewport.getRay({(float)x, (float)y}, origin, dir);
auto hit = m_render_interface->castRay(origin, dir, INVALID_ENTITY);
const RayHit hit = m_render_interface->castRay(origin, dir, INVALID_ENTITY);
if (m_gizmo->isActive()) return;
for (int i = 0; i < m_plugins.size(); ++i)
@ -2000,17 +2000,15 @@ public:
void rectSelect()
{
/*Array<EntityRef> entities(m_allocator);
Array<EntityRef> entities(m_allocator);
Vec2 min = m_rect_selection_start;
Vec2 max = m_mouse_pos;
if (min.x > max.x) Math::swap(min.x, max.x);
if (min.y > max.y) Math::swap(min.y, max.y);
Frustum frustum = m_viewport.getFrustum(min, max);
const ShiftedFrustum frustum = m_viewport.getFrustum(min, max);
m_render_interface->getModelInstaces(entities, frustum, m_viewport.pos, m_viewport.fov, m_viewport.is_ortho);
selectEntities(entities.empty() ? nullptr : &entities[0], entities.size(), false);*/
// TODO
ASSERT(false);
selectEntities(entities.empty() ? nullptr : &entities[0], entities.size(), false);
}
@ -2426,7 +2424,7 @@ public:
void setCustomPivot() override
{
/*if (m_selected_entities.empty()) return;
if (m_selected_entities.empty()) return;
DVec3 origin;
Vec3 dir;
@ -2436,11 +2434,8 @@ public:
const DVec3 snap_pos = getClosestVertex(hit);
Matrix mtx = m_universe->getMatrix(m_selected_entities[0]);
mtx.inverse();
m_gizmo->setOffset(mtx.transformPoint(snap_pos));*/
// TODO
ASSERT(false);
const Transform tr = m_universe->getTransform(m_selected_entities[0]);
m_gizmo->setOffset(tr.rot.conjugated() * (snap_pos - tr.pos).toFloat());
}
@ -3953,10 +3948,9 @@ public:
if (!m_identity)
{
/*if (i == 0)
if (i == 0)
{
Matrix inv = tr;
inv.inverse();
const Transform inv = tr.inverted();
base_tr.rot = tr.rot;
base_tr.scale = tr.scale;
base_tr = base_tr * inv;
@ -3965,9 +3959,7 @@ public:
else
{
tr = base_tr * tr;
}*/
ASSERT(false);
// TODO
}
}
const EntityRef new_entity = map.entities[i];
@ -4024,6 +4016,7 @@ private:
void WorldEditorImpl::pasteEntities()
{
if (!canPasteEntities()) return;
PasteEntityCommand* command = LUMIX_NEW(m_allocator, PasteEntityCommand)(*this, m_copy_buffer);
executeCommand(command);
}

View file

@ -189,6 +189,17 @@ void Frustum::computeOrtho(const Vec3& position,
}
void ShiftedFrustum::computeOrtho(const DVec3& position,
const Vec3& direction,
const Vec3& up,
float width,
float height,
float near_distance,
float far_distance)
{
computeOrtho(position, direction, up, width, height, near_distance, far_distance, {-1, -1}, {1, 1});
}
void Frustum::setPlanesFromPoints()
{
Vec3 normal_near = -crossProduct(points[0] - points[1], points[0] - points[2]).normalized();
@ -278,7 +289,9 @@ void ShiftedFrustum::computeOrtho(const DVec3& position,
float width,
float height,
float near_distance,
float far_distance)
float far_distance,
const Vec2& viewport_min,
const Vec2& viewport_max)
{
Vec3 z = direction;
z.normalize();
@ -289,7 +302,7 @@ void ShiftedFrustum::computeOrtho(const DVec3& position,
Vec3 x = crossProduct(up, z).normalized() * width;
Vec3 y = crossProduct(z, x).normalized() * height;
setPoints(*this, near_center, far_center, x, y, x, y, {-1, -1}, {1, 1});
setPoints(*this, near_center, far_center, x, y, x, y, viewport_min, viewport_max);
}
@ -357,27 +370,29 @@ void ShiftedFrustum::computePerspective(const DVec3& position,
float fov,
float ratio,
float near_distance,
float far_distance)
float far_distance,
const Vec2& viewport_min,
const Vec2& viewport_max)
{
ASSERT(near_distance > 0);
ASSERT(far_distance > 0);
ASSERT(near_distance < far_distance);
ASSERT(fov > 0);
ASSERT(ratio > 0);
float scale = (float)tan(fov * 0.5f);
Vec3 right = crossProduct(direction, up);
Vec3 up_near = up * near_distance * scale;
Vec3 right_near = right * (near_distance * scale * ratio);
Vec3 up_far = up * far_distance * scale;
Vec3 right_far = right * (far_distance * scale * ratio);
const float scale = (float)tan(fov * 0.5f);
const Vec3 right = crossProduct(direction, up);
const Vec3 up_near = up * near_distance * scale;
const Vec3 right_near = right * (near_distance * scale * ratio);
const Vec3 up_far = up * far_distance * scale;
const Vec3 right_far = right * (far_distance * scale * ratio);
Vec3 z = direction.normalized();
const Vec3 z = direction.normalized();
Vec3 near_center = z * near_distance;
Vec3 far_center = z * far_distance;
const Vec3 near_center = z * near_distance;
const Vec3 far_center = z * far_distance;
origin = position;
setPoints(*this, near_center, far_center, right_near, up_near, right_far, up_far, {-1, -1}, {1, 1});
setPoints(*this, near_center, far_center, right_near, up_near, right_far, up_far, viewport_min, viewport_max);
}
void Frustum::computePerspective(const Vec3& position,
@ -391,6 +406,17 @@ void Frustum::computePerspective(const Vec3& position,
computePerspective(position, direction, up, fov, ratio, near_distance, far_distance, {-1, -1}, {1, 1});
}
void ShiftedFrustum::computePerspective(const DVec3& position,
const Vec3& direction,
const Vec3& up,
float fov,
float ratio,
float near_distance,
float far_distance)
{
computePerspective(position, direction, up, fov, ratio, near_distance, far_distance, {-1, -1}, {1, 1});
}
void AABB::transform(const Matrix& matrix)
{

View file

@ -137,6 +137,26 @@ struct alignas(16) LUMIX_ENGINE_API Frustum
struct alignas(16) LUMIX_ENGINE_API ShiftedFrustum
{
void computeOrtho(const DVec3& position,
const Vec3& direction,
const Vec3& up,
float width,
float height,
float near_distance,
float far_distance,
const Vec2& viewport_min,
const Vec2& viewport_max);
void computePerspective(const DVec3& position,
const Vec3& direction,
const Vec3& up,
float fov,
float ratio,
float near_distance,
float far_distance,
const Vec2& viewport_min,
const Vec2& viewport_max);
void computeOrtho(const DVec3& position,
const Vec3& direction,
const Vec3& up,
@ -153,11 +173,6 @@ struct alignas(16) LUMIX_ENGINE_API ShiftedFrustum
float near_distance,
float far_distance);
float xs[(int)Frustum::Planes::COUNT];
float ys[(int)Frustum::Planes::COUNT];
float zs[(int)Frustum::Planes::COUNT];
float ds[(int)Frustum::Planes::COUNT];
bool containsAABB(const DVec3& pos, const Vec3& size) const;
bool intersectsAABB(const DVec3& pos, const Vec3& size) const;
Frustum getRelative(const DVec3& origin) const;
@ -165,6 +180,10 @@ struct alignas(16) LUMIX_ENGINE_API ShiftedFrustum
void setPlanesFromPoints();
void setPlane(Frustum::Planes side, const Vec3& normal, const Vec3& point);
float xs[(int)Frustum::Planes::COUNT];
float ys[(int)Frustum::Planes::COUNT];
float zs[(int)Frustum::Planes::COUNT];
float ds[(int)Frustum::Planes::COUNT];
Vec3 points[8];
DVec3 origin;
};

View file

@ -105,6 +105,10 @@ struct LUMIX_ENGINE_API Transform
return {rot.rotate(rhs.pos * scale) + pos, rot * rhs.rot, scale * rhs.scale};
}
Transform operator*(const LocalRigidTransform& rhs) const
{
return {pos + rot.rotate(rhs.pos * scale), rot * rhs.rot, scale};
}
DVec3 transform(const Vec3& value) const
{

View file

@ -60,6 +60,16 @@ void TextSerializer::write(const char* label, const RigidTransform& value)
<< asU32(value.rot.w) << "\n";
}
void TextSerializer::write(const char* label, const LocalRigidTransform& value)
{
blob << "#" << label << " (" << value.pos.x << ", " << value.pos.y << ", " << value.pos.z << ") "
<< " (" << value.rot.x << ", " << value.rot.y << ", " << value.rot.z << ", " << value.rot.w << ")\n\t"
<< asU32(value.pos.x) << "\n\t" << asU32(value.pos.y) << "\n\t" << asU32(value.pos.z) << "\n\t"
<< asU32(value.rot.x) << "\n\t" << asU32(value.rot.y) << "\n\t" << asU32(value.rot.z) << "\n\t"
<< asU32(value.rot.w) << "\n";
}
void TextSerializer::write(const char* label, const Transform& value)
{
blob << "#" << label << " (" << value.pos.x << ", " << value.pos.y << ", " << value.pos.z << ") "
@ -187,6 +197,24 @@ void TextDeserializer::read(RigidTransform* value)
value->rot.w = asFloat(readU32());
}
void TextDeserializer::read(LocalRigidTransform* value)
{
skip();
value->pos.x = asFloat(readU32());
skip();
value->pos.y = asFloat(readU32());
skip();
value->pos.z = asFloat(readU32());
skip();
value->rot.x = asFloat(readU32());
skip();
value->rot.y = asFloat(readU32());
skip();
value->rot.z = asFloat(readU32());
skip();
value->rot.w = asFloat(readU32());
}
void TextDeserializer::read(Transform* value)
{

View file

@ -9,6 +9,7 @@ namespace Lumix
struct DVec3;
class InputBlob;
struct LocalRigidTransform;
class OutputBlob;
struct Quat;
struct RigidTransform;
@ -50,6 +51,7 @@ struct LUMIX_ENGINE_API ISerializer
virtual void write(const char* label, EntityRef entity) = 0;
virtual void write(const char* label, const Transform& value) = 0;
virtual void write(const char* label, const RigidTransform& value) = 0;
virtual void write(const char* label, const LocalRigidTransform& value) = 0;
virtual void write(const char* label, const Vec4& value) = 0;
virtual void write(const char* label, const DVec3& value) = 0;
virtual void write(const char* label, const Vec3& value) = 0;
@ -77,6 +79,7 @@ struct LUMIX_ENGINE_API IDeserializer
virtual void read(EntityRef* entity) = 0;
virtual void read(Transform* value) = 0;
virtual void read(RigidTransform* value) = 0;
virtual void read(LocalRigidTransform* value) = 0;
virtual void read(Vec4* value) = 0;
virtual void read(DVec3* value) = 0;
virtual void read(Vec3* value) = 0;
@ -108,6 +111,7 @@ struct LUMIX_ENGINE_API TextSerializer final : public ISerializer
void write(const char* label, EntityPtr entity) override;
void write(const char* label, EntityRef entity) override;
void write(const char* label, const RigidTransform& value) override;
void write(const char* label, const LocalRigidTransform& value) override;
void write(const char* label, const Transform& value) override;
void write(const char* label, const Vec4& value) override;
void write(const char* label, const DVec3& value) override;
@ -142,6 +146,7 @@ struct LUMIX_ENGINE_API TextDeserializer final : public IDeserializer
void read(EntityPtr* entity) override;
void read(EntityRef* entity) override;
void read(RigidTransform* value) override;
void read(LocalRigidTransform* value) override;
void read(Transform* value) override;
void read(Vec4* value) override;
void read(DVec3* value) override;

View file

@ -90,16 +90,16 @@ Vec2 Viewport::worldToScreenPixels(const DVec3& world) const
return screen_pos * screen_size;
}
/*
Frustum Viewport::getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_max_px) const
ShiftedFrustum Viewport::getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_max_px) const
{
const Matrix mtx(pos, rot);
Frustum ret;
float ratio = h > 0 ? w / (float)h : 1;
Vec2 viewport_min = { viewport_min_px.x / w * 2 - 1, (1 - viewport_max_px.y / h) * 2 - 1 };
Vec2 viewport_max = { viewport_max_px.x / w * 2 - 1, (1 - viewport_min_px.y / h) * 2 - 1 };
const Matrix mtx = rot.toMatrix();
ShiftedFrustum ret;
const float ratio = h > 0 ? w / (float)h : 1;
const Vec2 viewport_min = { viewport_min_px.x / w * 2 - 1, (1 - viewport_max_px.y / h) * 2 - 1 };
const Vec2 viewport_max = { viewport_max_px.x / w * 2 - 1, (1 - viewport_min_px.y / h) * 2 - 1 };
if (is_ortho) {
ret.computeOrtho(mtx.getTranslation(),
ret.computeOrtho({0, 0, 0},
mtx.getZVector(),
mtx.getYVector(),
ortho_size * ratio,
@ -108,9 +108,10 @@ Frustum Viewport::getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_m
far,
viewport_min,
viewport_max);
ret.origin = pos;
return ret;
}
ret.computePerspective(mtx.getTranslation(),
ret.computePerspective({0, 0, 0},
-mtx.getZVector(),
mtx.getYVector(),
fov,
@ -119,9 +120,10 @@ Frustum Viewport::getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_m
far,
viewport_min,
viewport_max);
ret.origin = pos;
return ret;
}
*/
ShiftedFrustum Viewport::getFrustum() const
{

View file

@ -18,8 +18,7 @@ struct LUMIX_ENGINE_API Viewport
Matrix getView(const DVec3& origin) const;
Matrix getViewRotation() const;
ShiftedFrustum getFrustum() const;
// TODO
//Frustum getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_max_px) const;
ShiftedFrustum getFrustum(const Vec2& viewport_min_px, const Vec2& viewport_max_px) const;
Vec2 worldToScreenPixels(const DVec3& world) const;
void getRay(const Vec2& screen_pos, DVec3& origin, Vec3& dir) const;

View file

@ -1026,16 +1026,14 @@ bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK); renderer->viewCounterAdd();
if (in_mtx) {
mtx = *in_mtx;
}
// TODO
ASSERT(false);
/*Viewport viewport;
Viewport viewport;
viewport.is_ortho = false;
viewport.far = 10000.f;
viewport.near = 0.1f;
viewport.fov = Math::degreesToRadians(60.f);
viewport.h = AssetBrowser::TILE_SIZE;
viewport.w = AssetBrowser::TILE_SIZE;
viewport.pos = eye;
viewport.pos = DVec3(eye.x, eye.y, eye.z);
viewport.rot = mtx.getRotation();
m_tile.pipeline->setViewport(viewport);
m_tile.pipeline->render();
@ -1065,7 +1063,7 @@ bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK); renderer->viewCounterAdd();
m_tile.universe->destroyEntity(mesh_entity);
m_tile.frame_countdown = 2;
m_tile.path_hash = model->getPath().getHash();
model->getResourceManager().unload(*model);*/
model->getResourceManager().unload(*model);
}
@ -2174,11 +2172,8 @@ struct RenderInterfaceImpl final : public RenderInterface
DVec3 getClosestVertex(Universe* universe, EntityRef entity, const DVec3& wpos) override
{
/*
Matrix mtx = universe->getMatrix(entity);
Matrix inv_mtx = mtx;
inv_mtx.inverse();
Vec3 lpos = inv_mtx.transformPoint(wpos);
const Transform tr = universe->getTransform(entity);
const Vec3 lpos = tr.rot.conjugated() * (wpos - tr.pos).toFloat();
auto* scene = (RenderScene*)universe->getScene(MODEL_INSTANCE_TYPE);
if (!universe->hasComponent(entity, MODEL_INSTANCE_TYPE)) return wpos;
@ -2218,10 +2213,7 @@ struct RenderInterfaceImpl final : public RenderInterface
}
}
}
return mtx.transformPoint(closest_vertex);*/
// TODO
ASSERT(false);
return {};
return tr.pos + tr.rot * closest_vertex;
}
@ -2337,15 +2329,9 @@ struct RenderInterfaceImpl final : public RenderInterface
WorldEditor::RayHit castRay(const DVec3& origin, const Vec3& dir, EntityPtr ignored) override
{
auto hit = m_render_scene->castRay(origin, dir, ignored);
const RayCastModelHit hit = m_render_scene->castRay(origin, dir, ignored);
return {hit.m_is_hit, hit.m_t, hit.m_entity, hit.m_origin + hit.m_dir * hit.m_t};
}
void getRay(EntityRef camera, const Vec2& screen_pos, DVec3& origin, Vec3& dir) override
{
m_render_scene->getRay(camera, screen_pos, origin, dir);
return {hit.is_hit, hit.t, hit.entity, hit.origin + hit.dir * hit.t};
}
@ -2409,7 +2395,7 @@ struct RenderInterfaceImpl final : public RenderInterface
float castRay(ModelHandle model, const Vec3& origin, const Vec3& dir, const Pose* pose) override
{
RayCastModelHit hit = m_models[model]->castRay(origin, dir, pose);
return hit.m_is_hit ? hit.m_t : -1;
return hit.is_hit ? hit.t : -1;
}
@ -2473,7 +2459,7 @@ struct RenderInterfaceImpl final : public RenderInterface
}
Frustum getFrustum(EntityRef camera, const Vec2& viewport_min, const Vec2& viewport_max) override
ShiftedFrustum getFrustum(EntityRef camera, const Vec2& viewport_min, const Vec2& viewport_max) override
{
return m_render_scene->getCameraFrustum(camera, viewport_min, viewport_max);
}

View file

@ -329,7 +329,7 @@ void SceneView::handleDrop(const char* path, float x, float y)
if (PathUtils::hasExtension(path, "msh"))
{
const DVec3 pos = hit.m_origin + (hit.m_is_hit ? hit.m_t : 1) * hit.m_dir;
const DVec3 pos = hit.origin + (hit.is_hit ? hit.t : 1) * hit.dir;
m_editor.beginCommandGroup(crc32("insert_mesh"));
EntityRef entity = m_editor.addEntity();
@ -343,17 +343,17 @@ void SceneView::handleDrop(const char* path, float x, float y)
else if (PathUtils::hasExtension(path, "fab"))
{
DeferredPrefabInsert defer;
defer.pos = hit.m_origin + (hit.m_is_hit ? hit.m_t : 1) * hit.m_dir;
defer.pos = hit.origin + (hit.is_hit ? hit.t : 1) * hit.dir;
ResourceManagerHub& manager = m_editor.getEngine().getResourceManager();
defer.prefab = manager.load<PrefabResource>(Path(path));
m_deferred_prefab_inserts.push(defer);
}
else if (PathUtils::hasExtension(path, "phy"))
{
if (hit.m_is_hit && hit.m_entity.isValid())
if (hit.is_hit && hit.entity.isValid())
{
m_editor.beginCommandGroup(crc32("insert_phy_component"));
const EntityRef e = (EntityRef)hit.m_entity;
const EntityRef e = (EntityRef)hit.entity;
m_editor.selectEntities(&e, 1, false);
m_editor.addComponent(MESH_ACTOR_TYPE);
auto* prop = Reflection::getProperty(MESH_ACTOR_TYPE, "Source");
@ -362,7 +362,7 @@ void SceneView::handleDrop(const char* path, float x, float y)
}
else
{
const DVec3 pos = hit.m_origin + (hit.m_is_hit ? hit.m_t : 1) * hit.m_dir;
const DVec3 pos = hit.origin + (hit.is_hit ? hit.t : 1) * hit.dir;
m_editor.beginCommandGroup(crc32("insert_phy"));
EntityRef entity = m_editor.addEntity();
m_editor.setEntitiesPositions(&entity, &pos, 1);
@ -373,16 +373,16 @@ void SceneView::handleDrop(const char* path, float x, float y)
m_editor.endCommandGroup();
}
}
else if (hit.m_is_hit && PathUtils::hasExtension(path, "mat") && hit.m_mesh)
else if (hit.is_hit && PathUtils::hasExtension(path, "mat") && hit.mesh)
{
const EntityRef e = (EntityRef)hit.m_entity;
const EntityRef e = (EntityRef)hit.entity;
m_editor.selectEntities(&e, 1, false);
RenderScene* scene = m_pipeline->getScene();
Model* model = scene->getModelInstanceModel(e);
int mesh_index = 0;
for (int i = 0; i < model->getMeshCount(); ++i)
{
if (&model->getMesh(i) == hit.m_mesh)
if (&model->getMesh(i) == hit.mesh)
{
mesh_index = i;
break;

View file

@ -1562,6 +1562,7 @@ void destroy(BufferHandle buffer)
void clear(uint flags, const float* color, float depth)
{
CHECK_GL(glDisable(GL_BLEND));
checkThread();
GLbitfield gl_flags = 0;
if (flags & (uint)ClearFlags::COLOR) {
@ -1569,6 +1570,7 @@ void clear(uint flags, const float* color, float depth)
gl_flags |= GL_COLOR_BUFFER_BIT;
}
if (flags & (uint)ClearFlags::DEPTH) {
CHECK_GL(glDepthMask(GL_TRUE));
CHECK_GL(glClearDepth(depth));
gl_flags |= GL_DEPTH_BUFFER_BIT;
}

View file

@ -159,7 +159,7 @@ static void computeSkinMatrices(const Pose& pose, const Model& model, Matrix* ma
RayCastModelHit Model::castRay(const Vec3& origin, const Vec3& dir, const Pose* pose)
{
RayCastModelHit hit;
hit.m_is_hit = false;
hit.is_hit = false;
if (!isReady()) return hit;
Matrix matrices[256];
@ -234,16 +234,16 @@ RayCastModelHit Model::castRay(const Vec3& origin, const Vec3& dir, const Pose*
Vec3 VP2 = hit_point - p2;
if (dotProduct(normal, crossProduct(edge2, VP2)) < 0) continue;
if (!hit.m_is_hit || hit.m_t > t)
if (!hit.is_hit || hit.t > t)
{
hit.m_is_hit = true;
hit.m_t = t;
hit.m_mesh = &m_meshes[mesh_index];
hit.is_hit = true;
hit.t = t;
hit.mesh = &m_meshes[mesh_index];
}
}
}
hit.m_origin = DVec3(origin.x, origin.y, origin.z);
hit.m_dir = dir;
hit.origin = DVec3(origin.x, origin.y, origin.z);
hit.dir = dir;
return hit;
}
@ -583,10 +583,7 @@ bool Model::load(FS::IFile& file)
static Vec3 getBonePosition(Model* model, int bone_index)
{
// TODO
ASSERT(false);
return {};
//return model->getBone(bone_index).transform.pos;
return model->getBone(bone_index).transform.pos;
}

View file

@ -37,13 +37,13 @@ struct IFile;
struct LUMIX_RENDERER_API RayCastModelHit
{
bool m_is_hit;
float m_t;
DVec3 m_origin;
Vec3 m_dir;
Mesh* m_mesh;
EntityPtr m_entity;
ComponentType m_component_type;
bool is_hit;
float t;
DVec3 origin;
Vec3 dir;
Mesh* mesh;
EntityPtr entity;
ComponentType component_type;
};

View file

@ -132,7 +132,7 @@ struct BoneAttachment
EntityRef entity;
EntityPtr parent_entity;
int bone_index;
RigidTransform relative_transform;
LocalRigidTransform relative_transform;
};
@ -375,7 +375,7 @@ public:
DVec3& origin,
Vec3& dir) override
{
/*Camera& camera = m_cameras[camera_entity];
Camera& camera = m_cameras[camera_entity];
origin = m_universe.getPosition(camera_entity);
float width = camera.screen_width;
@ -390,28 +390,24 @@ public:
float ny = 2 * ((height - screen_pos.y) / height) - 1;
const Matrix projection_matrix = getCameraProjection(camera_entity);
Matrix view_matrix = m_universe.getMatrix(camera_entity);
const Transform view = m_universe.getTransform(camera_entity);
if (camera.is_ortho)
{
float ratio = camera.screen_height > 0 ? camera.screen_width / camera.screen_height : 1;
origin += view_matrix.getXVector() * nx * camera.ortho_size * ratio
+ view_matrix.getYVector() * ny * camera.ortho_size;
if (camera.is_ortho) {
const float ratio = camera.screen_height > 0 ? camera.screen_width / camera.screen_height : 1;
origin += view.rot * Vec3(1, 0, 0) * nx * camera.ortho_size * ratio
+ view.rot * Vec3(0, 1, 0) * ny * camera.ortho_size;
}
view_matrix.inverse();
Matrix inverted = (projection_matrix * view_matrix);
inverted.inverse();
Matrix inv_projection = projection_matrix;
inv_projection.inverse();
Vec4 p0 = inverted * Vec4(nx, ny, -1, 1);
Vec4 p1 = inverted * Vec4(nx, ny, 1, 1);
Vec4 p0 = inv_projection * Vec4(nx, ny, -1, 1);
Vec4 p1 = inv_projection * Vec4(nx, ny, 1, 1);
p0 *= 1 / p0.w;
p1 *= 1 / p1.w;
dir = (p1 - p0).xyz();
dir.normalize();*/
// TODO
ASSERT(false);
dir.normalize();
dir = view.rot * dir;
}
@ -458,55 +454,46 @@ public:
}
Frustum getCameraFrustum(EntityRef entity) const override
ShiftedFrustum getCameraFrustum(EntityRef entity) const override
{
/*const Camera& camera = m_cameras[entity];
Matrix mtx = m_universe.getMatrix(entity);
Frustum ret;
ShiftedFrustum ret;
const Camera& camera = m_cameras[entity];
const Transform tr = m_universe.getTransform(entity);
float ratio = camera.screen_height > 0 ? camera.screen_width / camera.screen_height : 1;
if (camera.is_ortho)
{
ret.computeOrtho(mtx.getTranslation(),
mtx.getZVector(),
mtx.getYVector(),
if (camera.is_ortho) {
ret.computeOrtho(tr.pos,
tr.rot * Vec3(0, 0, 1),
tr.rot * Vec3(0, 1, 0),
camera.ortho_size * ratio,
camera.ortho_size,
camera.near,
camera.far);
return ret;
}
ret.computePerspective(mtx.getTranslation(),
-mtx.getZVector(),
mtx.getYVector(),
ret.computePerspective(tr.pos,
tr.rot * Vec3(0, 0, -1),
tr.rot * Vec3(0, 1, 0),
camera.fov,
ratio,
camera.near,
camera.far);
return ret;*/
// TODO
ASSERT(false);
return {};
return ret;
}
Frustum getCameraFrustum(EntityRef entity, const Vec2& viewport_min_px, const Vec2& viewport_max_px) const override
ShiftedFrustum getCameraFrustum(EntityRef entity, const Vec2& viewport_min_px, const Vec2& viewport_max_px) const override
{
// TODO
ASSERT(false);
return {};
/*
ShiftedFrustum ret;
const Camera& camera = m_cameras[entity];
Matrix mtx = m_universe.getMatrix(entity);
Frustum ret;
const Transform tr = m_universe.getTransform(entity);
float ratio = camera.screen_height > 0 ? camera.screen_width / camera.screen_height : 1;
Vec2 viewport_min = { viewport_min_px.x / camera.screen_width * 2 - 1, (1 - viewport_max_px.y / camera.screen_height) * 2 - 1 };
Vec2 viewport_max = { viewport_max_px.x / camera.screen_width * 2 - 1, (1 - viewport_min_px.y / camera.screen_height) * 2 - 1 };
if (camera.is_ortho)
{
ret.computeOrtho(mtx.getTranslation(),
mtx.getZVector(),
mtx.getYVector(),
if (camera.is_ortho) {
ret.computeOrtho(tr.pos,
tr.rot * Vec3(0, 0, 1),
tr.rot * Vec3(0, 1, 0),
camera.ortho_size * ratio,
camera.ortho_size,
camera.near,
@ -515,25 +502,22 @@ public:
viewport_max);
return ret;
}
ret.computePerspective(mtx.getTranslation(),
-mtx.getZVector(),
mtx.getYVector(),
ret.computePerspective(tr.pos,
tr.rot * Vec3(0, 0, -1),
tr.rot * Vec3(0, 1, 0),
camera.fov,
ratio,
camera.near,
camera.far,
viewport_min,
viewport_max);
return ret;*/
return ret;
}
void updateBoneAttachment(const BoneAttachment& bone_attachment)
{
// TODO
ASSERT(false);
/*
if (!bone_attachment.parent_entity.isValid()) return;
const EntityPtr model_instance_ptr = bone_attachment.parent_entity;
if (!model_instance_ptr.isValid()) return;
@ -550,12 +534,12 @@ public:
return;
}
float original_scale = m_universe.getScale(bone_attachment.entity);
Transform bone_transform = {parent_pose->positions[idx], parent_pose->rotations[idx], 1.0f};
Transform relative_transform = { bone_attachment.relative_transform.pos, bone_attachment.relative_transform.rot, 1.0f};
const LocalRigidTransform bone_transform = {parent_pose->positions[idx], parent_pose->rotations[idx] };
const LocalRigidTransform relative_transform = { bone_attachment.relative_transform.pos, bone_attachment.relative_transform.rot };
Transform result = parent_entity_transform * bone_transform * relative_transform;
result.scale = original_scale;
m_universe.setTransform(bone_attachment.entity, result);
unlockPose(model_instance, false);*/
unlockPose(model_instance, false);
}
@ -567,9 +551,6 @@ public:
void updateRelativeMatrix(BoneAttachment& attachment)
{
// TODO
ASSERT(false);
/*
if (!attachment.parent_entity.isValid()) return;
if (attachment.bone_index < 0) return;
const EntityPtr model_instance_ptr = attachment.parent_entity;
@ -580,44 +561,36 @@ public:
if (!pose) return;
ASSERT(pose->is_absolute);
if (attachment.bone_index >= pose->count)
{
if (attachment.bone_index >= pose->count) {
unlockPose(model_instance, false);
return;
}
Transform bone_transform = {pose->positions[attachment.bone_index], pose->rotations[attachment.bone_index], 1.0f};
const LocalRigidTransform bone_transform = {pose->positions[attachment.bone_index], pose->rotations[attachment.bone_index]};
const EntityRef parent = (EntityRef)attachment.parent_entity;
Transform inv_parent_transform = m_universe.getTransform(parent) * bone_transform;
inv_parent_transform = inv_parent_transform.inverted();
Transform child_transform = m_universe.getTransform(attachment.entity);
Transform res = inv_parent_transform * child_transform;
attachment.relative_transform = {res.pos, res.rot};
unlockPose(model_instance, false);*/
const Transform child_transform = m_universe.getTransform(attachment.entity);
const Transform res = inv_parent_transform * child_transform;
attachment.relative_transform = {res.pos.toFloat(), res.rot};
unlockPose(model_instance, false);
}
Vec3 getBoneAttachmentPosition(EntityRef entity) override
{
// TODO
ASSERT(false);
return {};
//return m_bone_attachments[entity].relative_transform.pos;
return m_bone_attachments[entity].relative_transform.pos;
}
void setBoneAttachmentPosition(EntityRef entity, const Vec3& pos) override
{
// TODO
ASSERT(false);
/*
BoneAttachment& attachment = m_bone_attachments[entity];
attachment.relative_transform.pos = pos;
m_is_updating_attachments = true;
updateBoneAttachment(attachment);
m_is_updating_attachments = false;*/
m_is_updating_attachments = false;
}
@ -2147,8 +2120,8 @@ i32 size = 0;
scene->getRay(camera_entity, {x, y}, origin, dir);
RayCastModelHit hit = scene->castRay(origin, dir, INVALID_ENTITY);
LuaWrapper::push(L, hit.m_is_hit);
LuaWrapper::push(L, hit.m_is_hit ? hit.m_origin + hit.m_dir * hit.m_t : DVec3(0));
LuaWrapper::push(L, hit.is_hit);
LuaWrapper::push(L, hit.is_hit ? hit.origin + hit.dir * hit.t : DVec3(0));
return 2;
}
@ -2970,24 +2943,23 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
}
void addDebugFrustum(const Frustum& frustum, u32 color, float life) override
void addDebugFrustum(const ShiftedFrustum& frustum, u32 color, float life) override
{
/*addDebugLine(frustum.points[0], frustum.points[1], color, life);
addDebugLine(frustum.points[1], frustum.points[2], color, life);
addDebugLine(frustum.points[2], frustum.points[3], color, life);
addDebugLine(frustum.points[3], frustum.points[0], color, life);
const DVec3 o = frustum.origin;
addDebugLine(o + frustum.points[0], o + frustum.points[1], color, life);
addDebugLine(o + frustum.points[1], o + frustum.points[2], color, life);
addDebugLine(o + frustum.points[2], o + frustum.points[3], color, life);
addDebugLine(o + frustum.points[3], o + frustum.points[0], color, life);
addDebugLine(frustum.points[4], frustum.points[5], color, life);
addDebugLine(frustum.points[5], frustum.points[6], color, life);
addDebugLine(frustum.points[6], frustum.points[7], color, life);
addDebugLine(frustum.points[7], frustum.points[4], color, life);
addDebugLine(o + frustum.points[4], o + frustum.points[5], color, life);
addDebugLine(o + frustum.points[5], o + frustum.points[6], color, life);
addDebugLine(o + frustum.points[6], o + frustum.points[7], color, life);
addDebugLine(o + frustum.points[7], o + frustum.points[4], color, life);
addDebugLine(frustum.points[0], frustum.points[4], color, life);
addDebugLine(frustum.points[1], frustum.points[5], color, life);
addDebugLine(frustum.points[2], frustum.points[6], color, life);
addDebugLine(frustum.points[3], frustum.points[7], color, life);*/
// TODO
ASSERT(false);
addDebugLine(o + frustum.points[0], o + frustum.points[4], color, life);
addDebugLine(o + frustum.points[1], o + frustum.points[5], color, life);
addDebugLine(o + frustum.points[2], o + frustum.points[6], color, life);
addDebugLine(o + frustum.points[3], o + frustum.points[7], color, life);
}
@ -3072,71 +3044,64 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
RayCastModelHit castRayTerrain(EntityRef entity, const DVec3& origin, const Vec3& dir) override
{
RayCastModelHit hit;
hit.m_is_hit = false;
hit.is_hit = false;
auto iter = m_terrains.find(entity);
if (!iter.isValid()) return hit;
auto* terrain = iter.value();
Terrain* terrain = iter.value();
hit = terrain->castRay(origin, dir);
hit.m_component_type = TERRAIN_TYPE;
hit.m_entity = terrain->getEntity();
hit.component_type = TERRAIN_TYPE;
hit.entity = terrain->getEntity();
return hit;
}
RayCastModelHit castRay(const DVec3& origin, const Vec3& dir, EntityPtr ignored_model_instance) override
{
/*PROFILE_FUNCTION();
PROFILE_FUNCTION();
RayCastModelHit hit;
hit.m_is_hit = false;
hit.m_origin = origin;
hit.m_dir = dir;
float cur_dist = FLT_MAX;
Universe& universe = getUniverse();
for (int i = 0; i < m_model_instances.size(); ++i)
{
hit.is_hit = false;
hit.origin = origin;
hit.dir = dir;
double cur_dist = DBL_MAX;
const Universe& universe = getUniverse();
for (int i = 0; i < m_model_instances.size(); ++i) {
auto& r = m_model_instances[i];
if (ignored_model_instance.index == i || !r.model) continue;
if (!r.flags.isSet(ModelInstance::ENABLED)) continue;
const EntityRef entity = (EntityRef)r.entity;
const Vec3& pos = r.matrix.getTranslation();
const DVec3& pos = universe.getPosition(entity);
float scale = universe.getScale(entity);
float radius = r.model->getBoundingRadius() * scale;
float dist = (pos - origin).length();
const double dist = (pos - origin).length();
if (dist - radius > cur_dist) continue;
Vec3 intersection;
if (Math::getRaySphereIntersection(origin, dir, pos, radius, intersection))
{
RayCastModelHit new_hit = r.model->castRay(origin, dir, r.matrix, r.pose);
if (new_hit.m_is_hit && (!hit.m_is_hit || new_hit.m_t < hit.m_t))
{
new_hit.m_entity = entity;
new_hit.m_component_type = MODEL_INSTANCE_TYPE;
const Vec3 rel_pos = (origin - pos).toFloat();
if (Math::getRaySphereIntersection(rel_pos, dir, Vec3::ZERO, radius, intersection)) {
RayCastModelHit new_hit = r.model->castRay(rel_pos, dir, r.pose);
if (new_hit.is_hit && (!hit.is_hit || new_hit.t < hit.t)) {
new_hit.entity = entity;
new_hit.component_type = MODEL_INSTANCE_TYPE;
hit = new_hit;
hit.m_is_hit = true;
cur_dist = dir.length() * hit.m_t;
hit.is_hit = true;
cur_dist = dir.length() * hit.t;
}
}
}
for (auto* terrain : m_terrains)
{
for (auto* terrain : m_terrains) {
RayCastModelHit terrain_hit = terrain->castRay(origin, dir);
if (terrain_hit.m_is_hit && (!hit.m_is_hit || terrain_hit.m_t < hit.m_t))
{
terrain_hit.m_component_type = TERRAIN_TYPE;
terrain_hit.m_entity = terrain->getEntity();
terrain_hit.m_mesh = nullptr;
if (terrain_hit.is_hit && (!hit.is_hit || terrain_hit.t < hit.t)) {
terrain_hit.component_type = TERRAIN_TYPE;
terrain_hit.entity = terrain->getEntity();
terrain_hit.mesh = nullptr;
hit = terrain_hit;
}
}
return hit;*/
// TODO
//ASSERT(false);
return {};
return hit;
}

View file

@ -54,7 +54,7 @@ struct DecalInfo
Matrix mtx;
Matrix inv_mtx;
Material* material;
Vec3 position;
Transform transform;
float radius;
};
@ -169,8 +169,8 @@ public:
virtual struct Viewport getCameraViewport(EntityRef camera) const = 0;
virtual float getCameraLODMultiplier(float fov, bool is_ortho) const = 0;
virtual float getCameraLODMultiplier(EntityRef entity) const = 0;
virtual Frustum getCameraFrustum(EntityRef entity) const = 0;
virtual Frustum getCameraFrustum(EntityRef entity, const Vec2& a, const Vec2& b) const = 0;
virtual ShiftedFrustum getCameraFrustum(EntityRef entity) const = 0;
virtual ShiftedFrustum getCameraFrustum(EntityRef entity, const Vec2& a, const Vec2& b) const = 0;
virtual float getTime() const = 0;
virtual Engine& getEngine() const = 0;
virtual IAllocator& getAllocator() = 0;
@ -211,7 +211,7 @@ public:
u32 color,
float life) = 0;
virtual void addDebugSphere(const DVec3& center, float radius, u32 color, float life) = 0;
virtual void addDebugFrustum(const Frustum& frustum, u32 color, float life) = 0;
virtual void addDebugFrustum(const ShiftedFrustum& frustum, u32 color, float life) = 0;
virtual void addDebugCapsule(const DVec3& position,
float height,

View file

@ -811,7 +811,7 @@ bool getRayTriangleIntersection(const Vec3& local_origin, const Vec3& local_dir,
RayCastModelHit Terrain::castRay(const DVec3& origin, const Vec3& dir)
{
RayCastModelHit hit;
hit.m_is_hit = false;
hit.is_hit = false;
if (m_root)
{
Matrix mtx = m_scene.getUniverse().getRelativeMatrix(m_entity, origin);
@ -844,18 +844,18 @@ RayCastModelHit Terrain::castRay(const DVec3& origin, const Vec3& dir)
Vec3 p3(x, getHeight(x, z + m_scale.x), z + m_scale.x);
if (getRayTriangleIntersection(rel_origin, rel_dir, p0, p1, p2, t))
{
hit.m_is_hit = true;
hit.m_origin = origin;
hit.m_dir = dir;
hit.m_t = t;
hit.is_hit = true;
hit.origin = origin;
hit.dir = dir;
hit.t = t;
return hit;
}
if (getRayTriangleIntersection(rel_origin, rel_dir, p0, p2, p3, t))
{
hit.m_is_hit = true;
hit.m_origin = origin;
hit.m_dir = dir;
hit.m_t = t;
hit.is_hit = true;
hit.origin = origin;
hit.dir = dir;
hit.t = t;
return hit;
}
if (next_x < next_z)