diff --git a/Geome3Dash/Geome3Dash.vcxproj b/Geome3Dash/Geome3Dash.vcxproj
index 4b741f09..b0d8302b 100644
--- a/Geome3Dash/Geome3Dash.vcxproj
+++ b/Geome3Dash/Geome3Dash.vcxproj
@@ -102,7 +102,8 @@
-
+
+
NotUsing
@@ -158,6 +159,13 @@
+
+
+
+
+
+
+
@@ -201,7 +209,8 @@
-
+
+
@@ -227,6 +236,13 @@
+
+
+
+
+
+
+
diff --git a/Geome3Dash/Geome3Dash.vcxproj.filters b/Geome3Dash/Geome3Dash.vcxproj.filters
index d57dc4cf..398fb126 100644
--- a/Geome3Dash/Geome3Dash.vcxproj.filters
+++ b/Geome3Dash/Geome3Dash.vcxproj.filters
@@ -237,12 +237,36 @@
Source Files
-
+
Source Files
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
@@ -440,12 +464,36 @@
Header Files
-
+
Header Files
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
diff --git a/Geome3Dash/src/GameObjectModel.cpp b/Geome3Dash/src/GameObjectModel.cpp
index cc248cca..f7a8256d 100644
--- a/Geome3Dash/src/GameObjectModel.cpp
+++ b/Geome3Dash/src/GameObjectModel.cpp
@@ -1,125 +1,9 @@
#include "pch.h"
#include "GameObjectModel.h"
-#include "game/playing/G3DPlayLayer.h"
namespace g3d
{
- void BezierCameraPlayerObjectModelTransformer::transform(GameObjectModel* gom)
- {
- if (auto pom = dynamic_cast(gom))
- {
- auto playerPos = pom->getPosition();
- auto newR = pom->getRotation();
- auto playerYaw = newR.y;
- auto playerYawR = -glm::radians(playerYaw);
- const auto playerCameraOffset = playLayer3d->playerCameraOffset;
- const auto playerCameraYawOffset = playLayer3d->playerCameraYawOffset;
- const auto playerCameraPitchOffset = playLayer3d->playerCameraPitchOffset;
-
- glm::vec3 rotatedOffset =
- {
- playerCameraOffset.x * std::cos(playerYawR) - playerCameraOffset.z * std::sin(playerYawR),
- playerCameraOffset.y,
- playerCameraOffset.x * std::sin(playerYawR) + playerCameraOffset.z * std::cos(playerYawR)
- };
-
- playLayer3d->camera.setPosition(playerPos + rotatedOffset);
- // Clamp pitch to prevent flipping
- playLayer3d->camera.setYaw(playerCameraYawOffset - playerYaw);
- auto pitch = std::clamp(static_cast(playerCameraPitchOffset), -89.0f, 89.0f);
- playLayer3d->camera.setPitch(pitch);
- }
- }
-
- void FadeGameObjectModelTransformer::transform(GameObjectModel* gom)
- {
- auto obj = gom->getGameObject();
- auto distance = std::abs(gameLayer->m_player1->m_position.x - obj->getPositionX());
- if (distance > maxRender) {
- gom->setVisible(false);
- gom->setOpacity(0);
- }
- else if (distance > startFade) {
- auto scale = gom->getScale();
- double tNormal = (distance - startFade) / (maxRender - startFade);
- gom->setScale(ease::easeNormal(easing, tNormal, scale, target));
- }
- }
-
- void BezierGameObjectModelTransformer::transform(GameObjectModel* gom)
- {
- auto bCoordinate = BezierManager::transformIntoBezierCoordinate(
- bezier,
- gom->getPositionX(), gom->getPositionY(), gom->getPositionZ(),
- bezierSegmentCount, bezierSegmentMultiplier);
- gom->setPosition(bCoordinate.position);
- gom->setRotationY(360 - bCoordinate.rotation);
- }
-
- void PlayerObjectModel::update()
- {
- model = cube;
- if (playerObject->m_isShip) {
- model = ship;
- }
- else if (playerObject->m_isBall) {
- model = ball;
- }
- else if (playerObject->m_isBird) {
- model = bird;
- }
- else if (playerObject->m_isDart) {
- model = dart;
- }
- else if (playerObject->m_isRobot) {
- model = robot;
- }
- else if (playerObject->m_isSpider) {
- model = spider;
- }
- else if (playerObject->m_isSwing) {
- model = swing;
- }
- this->setPositionX(playerObject->m_position.x * 0.05);
- this->setPositionY(playerObject->m_position.y * 0.05);
- this->setPositionZ(20.f);
- this->setScale(glm::vec3(0.75) * glm::vec3(playerObject->getScale()));
- this->setScaleY(std::abs(this->getScaleY()) * (playerObject->m_isUpsideDown ? -1.f : 1.f));
- this->setRotationZ(360 - playerObject->getRotation());
- }
-
- void PlayerObjectModel::loadPlayerModels()
- {
- loadPlayerModel(&cube, "cube", GameManager::get()->getPlayerFrame());
- loadPlayerModel(&ship, "ship", GameManager::get()->getPlayerShip());
- loadPlayerModel(&ball, "ball", GameManager::get()->getPlayerBall());
- loadPlayerModel(&bird, "bird", GameManager::get()->getPlayerBird());
- loadPlayerModel(&dart, "dart", GameManager::get()->getPlayerDart());
- loadPlayerModel(&robot, "robot", GameManager::get()->getPlayerRobot());
- loadPlayerModel(&spider, "spider", GameManager::get()->getPlayerSpider());
- loadPlayerModel(&swing, "swing", GameManager::get()->getPlayerSwing());
- model = cube;
- }
-
- std::filesystem::path PlayerObjectModel::getPlayerModelPath(const std::string& type, const int id)
- {
- return BlockModelStorage::get()->getBP() / "player" / type / std::to_string(id) / "model.obj";
- }
-
- std::filesystem::path PlayerObjectModel::getFixedPlayerModelPath(const std::string& type, const int id)
- {
- const auto path = getPlayerModelPath(type, id);
- return std::filesystem::exists(path)
- ? path
- : getPlayerModelPath(type, 0);
- }
-
- void PlayerObjectModel::loadPlayerModel(sus3d::Model** model, const std::string& type, const int id)
- {
- *model = BlockModelStorage::get()->loadAndParseMtl(getFixedPlayerModelPath(type, id));
- }
-
void GameObjectModel::update()
{
this->setPosition(glm::vec3(
@@ -151,6 +35,7 @@ namespace g3d
this->applyTransformation();
//if (!this->getVisible()) { return; }
+ if (this->opacity == 0.f || this->scale == glm::vec3(0.f)) { return; }
auto tScale = model->getScale();
auto tPos = model->getPosition();
diff --git a/Geome3Dash/src/GameObjectModel.h b/Geome3Dash/src/GameObjectModel.h
index 23b428bb..ebd7bc9e 100644
--- a/Geome3Dash/src/GameObjectModel.h
+++ b/Geome3Dash/src/GameObjectModel.h
@@ -4,23 +4,15 @@
#include "engine/sus3d/Mesh.h"
#include "engine/sus3d/Scene.h"
-#include "BezierManager.h"
#include "BlockModelStorage.h"
-#include "helper/Easing.h"
+#include "transformer/GameObjectModelTransformer.h"
class GameObject;
namespace g3d
{
class G3DPlayLayer;
- class GameObjectModel;
- class GameObjectModelTransformer
- {
- public:
- virtual void transform(GameObjectModel* gom) = 0;
- virtual ~GameObjectModelTransformer() {}
- };
class GameObjectModel : public sus3d::ModelProtocol
{
@@ -61,121 +53,4 @@ namespace g3d
for (auto& transformer : transformers) { /*delete transformer;*/ }
}
};
-
- class PlayerObjectModel : public GameObjectModel
- {
- protected:
- sus3d::Model* cube;
- sus3d::Model* ship;
- sus3d::Model* ball;
- sus3d::Model* bird;
- sus3d::Model* dart;
- sus3d::Model* robot;
- sus3d::Model* spider;
- sus3d::Model* swing;
- PlayerObject* playerObject;
- public:
- virtual void update() override;
-
- std::filesystem::path getPlayerModelPath(const std::string& type, const int id);
- std::filesystem::path getFixedPlayerModelPath(const std::string& type, const int id);
- void loadPlayerModel(sus3d::Model** model, const std::string& type, const int id);
- void loadPlayerModels();
-
- PlayerObjectModel() {}
-
- PlayerObjectModel(
- PlayerObject* obj,
- const std::vector& transformers)
- : GameObjectModel(obj, transformers)
- , playerObject(obj)
- {
- loadPlayerModels();
- }
-
- virtual ~PlayerObjectModel() = default;
- };
-
- class DefaultGameObjectModelTransformer : public GameObjectModelTransformer
- {
- public:
- virtual void transform(GameObjectModel* gom) override {};
- virtual ~DefaultGameObjectModelTransformer() = default;
- };
-
- class BezierGameObjectModelTransformer : public GameObjectModelTransformer
- {
- protected:
- CubicBezier bezier;
- double bezierSegmentMultiplier;
- int bezierSegmentCount;
- public:
- virtual void transform(GameObjectModel* gom) override;
- BezierGameObjectModelTransformer(
- const CubicBezier& bezier,
- const double bezierSegmentMultiplier,
- const int bezierSegmentCount)
- : bezier(bezier)
- , bezierSegmentMultiplier(bezierSegmentMultiplier)
- , bezierSegmentCount(bezierSegmentCount)
- {
-
- }
- virtual ~BezierGameObjectModelTransformer() = default;
- };
-
- class FadeGameObjectModelTransformer : public GameObjectModelTransformer
- {
- protected:
- GJBaseGameLayer* gameLayer;
- double maxRender;
- double startFade;
- ease::Base* easing;
- glm::vec3 target;
- public:
- double getMaxRender() { return maxRender; }
- virtual void transform(GameObjectModel* gom) override;
- FadeGameObjectModelTransformer(
- GJBaseGameLayer* layer,
- double maxR,
- double startF,
- ease::Base* easeFunc,
- const glm::vec3& tgt)
- : gameLayer(layer)
- , maxRender(maxR)
- , startFade(startF)
- , easing(easeFunc)
- , target(tgt)
- {
-
- }
-
- virtual ~FadeGameObjectModelTransformer() = default;
- };
-
- class AnimationGameObjectModelTransformer : public GameObjectModelTransformer
- {
- public:
- virtual void transform(GameObjectModel* gom) override
- {
- switch (gom->getGameObject()->m_objectID)
- {
- // do animations
- }
- };
- virtual ~AnimationGameObjectModelTransformer() = default;
- };
-
- class BezierCameraPlayerObjectModelTransformer : public GameObjectModelTransformer
- {
- public:
- G3DPlayLayer* playLayer3d;
- virtual void transform(GameObjectModel* gom) override;
- BezierCameraPlayerObjectModelTransformer(G3DPlayLayer* playLayer3d)
- : playLayer3d(playLayer3d)
- {
-
- }
- virtual ~BezierCameraPlayerObjectModelTransformer() = default;
- };
}
\ No newline at end of file
diff --git a/Geome3Dash/src/PlayerObjectModel.cpp b/Geome3Dash/src/PlayerObjectModel.cpp
new file mode 100644
index 00000000..2eaebc6c
--- /dev/null
+++ b/Geome3Dash/src/PlayerObjectModel.cpp
@@ -0,0 +1,69 @@
+#include "pch.h"
+
+#include "PlayerObjectModel.h"
+
+namespace g3d
+{
+ void PlayerObjectModel::update()
+ {
+ model = cube;
+ if (playerObject->m_isShip) {
+ model = ship;
+ }
+ else if (playerObject->m_isBall) {
+ model = ball;
+ }
+ else if (playerObject->m_isBird) {
+ model = bird;
+ }
+ else if (playerObject->m_isDart) {
+ model = dart;
+ }
+ else if (playerObject->m_isRobot) {
+ model = robot;
+ }
+ else if (playerObject->m_isSpider) {
+ model = spider;
+ }
+ else if (playerObject->m_isSwing) {
+ model = swing;
+ }
+ this->setPositionX(playerObject->m_position.x * 0.05);
+ this->setPositionY(playerObject->m_position.y * 0.05);
+ this->setPositionZ(20.f);
+ this->setScale(glm::vec3(0.75) * glm::vec3(playerObject->getScale()));
+ this->setScaleY(std::abs(this->getScaleY()) * (playerObject->m_isUpsideDown ? -1.f : 1.f));
+ this->setRotationZ(360 - playerObject->getRotation());
+ }
+
+ void PlayerObjectModel::loadPlayerModels()
+ {
+ loadPlayerModel(&cube, "cube", GameManager::get()->getPlayerFrame());
+ loadPlayerModel(&ship, "ship", GameManager::get()->getPlayerShip());
+ loadPlayerModel(&ball, "ball", GameManager::get()->getPlayerBall());
+ loadPlayerModel(&bird, "bird", GameManager::get()->getPlayerBird());
+ loadPlayerModel(&dart, "dart", GameManager::get()->getPlayerDart());
+ loadPlayerModel(&robot, "robot", GameManager::get()->getPlayerRobot());
+ loadPlayerModel(&spider, "spider", GameManager::get()->getPlayerSpider());
+ loadPlayerModel(&swing, "swing", GameManager::get()->getPlayerSwing());
+ model = cube;
+ }
+
+ std::filesystem::path PlayerObjectModel::getPlayerModelPath(const std::string& type, const int id)
+ {
+ return BlockModelStorage::get()->getBP() / "player" / type / std::to_string(id) / "model.obj";
+ }
+
+ std::filesystem::path PlayerObjectModel::getFixedPlayerModelPath(const std::string& type, const int id)
+ {
+ const auto path = getPlayerModelPath(type, id);
+ return std::filesystem::exists(path)
+ ? path
+ : getPlayerModelPath(type, 0);
+ }
+
+ void PlayerObjectModel::loadPlayerModel(sus3d::Model** model, const std::string& type, const int id)
+ {
+ *model = BlockModelStorage::get()->loadAndParseMtl(getFixedPlayerModelPath(type, id));
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/PlayerObjectModel.h b/Geome3Dash/src/PlayerObjectModel.h
new file mode 100644
index 00000000..8c8de70f
--- /dev/null
+++ b/Geome3Dash/src/PlayerObjectModel.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "GameObjectModel.h"
+
+class GameObject;
+
+namespace g3d
+{
+ class PlayerObjectModel : public GameObjectModel
+ {
+ protected:
+ sus3d::Model* cube;
+ sus3d::Model* ship;
+ sus3d::Model* ball;
+ sus3d::Model* bird;
+ sus3d::Model* dart;
+ sus3d::Model* robot;
+ sus3d::Model* spider;
+ sus3d::Model* swing;
+ PlayerObject* playerObject;
+ public:
+ virtual void update() override;
+
+ std::filesystem::path getPlayerModelPath(const std::string& type, const int id);
+ std::filesystem::path getFixedPlayerModelPath(const std::string& type, const int id);
+ void loadPlayerModel(sus3d::Model** model, const std::string& type, const int id);
+ void loadPlayerModels();
+
+ PlayerObjectModel() {}
+
+ PlayerObjectModel(
+ PlayerObject* obj,
+ const std::vector& transformers)
+ : GameObjectModel(obj, transformers)
+ , playerObject(obj)
+ {
+ loadPlayerModels();
+ }
+
+ virtual ~PlayerObjectModel() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/component/G3DBaseNode.h b/Geome3Dash/src/game/component/G3DBaseNode.h
index bcb0761c..46226b2c 100644
--- a/Geome3Dash/src/game/component/G3DBaseNode.h
+++ b/Geome3Dash/src/game/component/G3DBaseNode.h
@@ -14,6 +14,7 @@ namespace g3d
class G3DBaseNode : public CCNode
{
friend class G3DCurveEditorLayer;
+ friend class G3DCurveEditorPopup;
protected:
virtual bool init() override;
GLuint framebuffer, texture, renderbuffer;
@@ -48,8 +49,6 @@ namespace g3d
~G3DBaseNode();
static G3DBaseNode* create();
-
-
template
T* loadAndAddModel(const std::filesystem::path& filePath)
{
@@ -57,7 +56,5 @@ namespace g3d
if (model) { models.push_back(model); }
return model;
}
-
-
};
}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/editor/G3DCurveEditorLayer.cpp b/Geome3Dash/src/game/editor/G3DCurveEditorLayer.cpp
deleted file mode 100644
index d63072f3..00000000
--- a/Geome3Dash/src/game/editor/G3DCurveEditorLayer.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-#include "pch.h"
-
-#include "G3DCurveEditorLayer.h"
-
-#include "helper/spline/Curve.h"
-#include "helper/spline/Spline.h"
-#include "helper/OpenGLStateHelper.h"
-#include "game/component/G3DBaseNode.h"
-
-#include "engine/sus3d/Mesh.h"
-#include "engine/sus3d/Shader.h"
-#include "engine/sus3d/Shaders.h"
-
-#include "BlockModelStorage.h"
-
-namespace g3d
-{
- void G3DCurveEditorLayer::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int mods) {
- if (!this->isVisible()) return;
- if (button == GLFW_MOUSE_BUTTON_LEFT) {
- if (action == GLFW_PRESS) {
- isRightClicking = true;
- isRightClickingGetPos = false;
- }
- else if (action == GLFW_RELEASE) {
- isRightClicking = false;
- }
- }
- }
-
- void G3DCurveEditorLayer::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) {
- if (!this->isVisible()) return;
- if (isRightClicking) {
- if (!isRightClickingGetPos) {
- lastMouseX = static_cast(x);
- lastMouseY = static_cast(y);
- isRightClickingGetPos = true;
- }
- else {
- float deltaX = static_cast(x) - lastMouseX;
- float deltaY = static_cast(y) - lastMouseY;
- if (isPressingShift) {
-
-
- auto glView = CCDirector::sharedDirector()->m_pobOpenGLView;
- int mouseX = static_cast(glView->m_fMouseX);
- int mouseY = glView->getFrameSize().height - static_cast(glView->m_fMouseY);
-
- OpenGLStateHelper::saveState();
- glEnable(GL_DEPTH_TEST);
-
- glBindFramebuffer(GL_FRAMEBUFFER, layer3d->framebuffer);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-
- layer3d->getObjectIDByMousePositionShader->use();
-
- auto renderFunction = [&](int segmentIndex, glm::vec3 position) {
- pointModel->setScale(glm::vec3(0.07));
- pointModel->setPosition(position);
- glm::mat4 model = pointModel->prepareModelMatrix();
- layer3d->getObjectIDByMousePositionShader->setMat4("model", model);
- layer3d->getObjectIDByMousePositionShader->setMat4("view", layer3d->camera.getViewMat());
- layer3d->getObjectIDByMousePositionShader->setMat4("projection", layer3d->camera.getProjectionMat());
- glm::vec3 uniqueColor = layer3d->generateUniqueColor(5, segmentIndex);
- layer3d->getObjectIDByMousePositionShader->setVec3("color", uniqueColor);
-
- for (auto mesh : pointModel->meshes)
- mesh->render(layer3d->getObjectIDByMousePositionShader);
- };
-
- auto points = spline->getAllPoints();
-
- for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) {
-
- renderFunction(pointIndex, points[pointIndex]);
-
- }
-
- glFlush();
- glDisable(GL_DEPTH_TEST);
-
- GLubyte pixelColor[3];
- glReadPixels(mouseX, mouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- OpenGLStateHelper::pushState();
-
- auto ids = layer3d->getObjectAndMeshIDFromColor(pixelColor);
- if (ids.second != -1) { selected = ids.second; }
-
- std::cout << fmt::format("({}, {})", ids.first, ids.second) << '\n';
-
- glm::vec3 newPosition = points[selected];
-
- glm::vec3 tangent = glm::normalize(glm::cross(layer3d->camera.getUp(), layer3d->camera.getFront()));
- glm::vec3 bionormal = glm::normalize(glm::cross(layer3d->camera.getFront(), tangent));
-
- newPosition -= tangent * (deltaX * 0.01f);
- newPosition -= bionormal * (deltaY * 0.01f);
-
- spline->editPointSymmetricCenterFix(selected, newPosition);
-
- }
- else if (isPressingControl) {
- float sensitivity = 0.032f;
- layer3d->camera.setPosition(layer3d->camera.getPosition() + layer3d->camera.getUp() * deltaY * sensitivity);
- layer3d->camera.setPosition(layer3d->camera.getPosition() + glm::normalize(glm::cross(layer3d->camera.getFront(), layer3d->camera.getUp())) * deltaX * -sensitivity);
- }
- else {
- float sensitivity = 0.05f;
- float yaw = layer3d->camera.getYaw() - deltaX * sensitivity;
- float pitch = layer3d->camera.getPitch() - deltaY * sensitivity;
- pitch = std::clamp(pitch, -89.0f, 89.0f);
- layer3d->camera.setYaw(yaw);
- layer3d->camera.setPitch(pitch);
- }
- lastMouseX = static_cast(x);
- lastMouseY = static_cast(y);
- }
- }
- else {
- selected = -1;
- }
- }
-
- void G3DCurveEditorLayer::updateLevel() {
- levelLength = 0;
- CCObject* obj;
- CCARRAY_FOREACH(lel->m_objects, obj) {
- auto block = static_cast(obj);
-
- levelLength = std::max(block->getPositionX(), levelLength);
- }
- }
-
- bool G3DCurveEditorLayer::init(LevelEditorLayer* lel) {
- if (!CCLayer::init()) return false;
- this->setVisible(false);
-
- this->setTouchEnabled(true);
- this->setTouchPriority(-600);
- //CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 50, true);
- geode::cocos::handleTouchPriority(this, true);
- this->setZOrder(101);
-
- this->lel = lel;
-
- spline = new Spline();
- spline->addSegment(new Curve(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(3.0f, 0.0f, 0.0f)));
-
- auto size = CCDirector::sharedDirector()->getWinSize();
-
- bg = CCSprite::create("GJ_gradientBG.png");
- bg->setScaleX(size.width / bg->getContentSize().width);
- bg->setScaleY(size.height / bg->getContentSize().height);
- bg->setColor({ 0, 75, 110 });
- bg->setZOrder(-5);
- bg->setPosition(size / 2);
- this->addChild(bg);
-
- auto uiMenu = CCMenu::create();
- uiMenu->setPosition(0, 0);
- this->addChild(uiMenu);
- auto backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
- backBtnSprite->setScale(0.7);
- auto backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, this, menu_selector(G3DCurveEditorLayer::hide));
- backBtn->setPosition(20, size.height - 20);
- uiMenu->addChild(backBtn);
-
- auto addCurveSprite = CCSprite::createWithSpriteFrameName("GJ_plainBtn_001.png");
- addCurveSprite->setScale(0.7);
- auto addCurveLabel = CCLabelBMFont::create("+", "bigFont.fnt", 80.f);
- addCurveLabel->setScale(1.2);
- addCurveLabel->setPosition(addCurveSprite->getContentSize() / 2 - ccp(0, -4.f));
- addCurveSprite->addChild(addCurveLabel);
- auto addCurveBtn = CCMenuItemSpriteExtra::create(addCurveSprite, this, menu_selector(G3DCurveEditorLayer::onAddSegment));
- addCurveBtn->setPosition(60, size.height - 20);
- uiMenu->addChild(addCurveBtn);
-
- auto removeCurveSprite = CCSprite::createWithSpriteFrameName("GJ_plainBtn_001.png");
- removeCurveSprite->setScale(0.7);
- auto removeCurveLabel = CCLabelBMFont::create("-", "bigFont.fnt", 80.f);
- removeCurveLabel->setScale(1.2);
- removeCurveLabel->setPosition(removeCurveSprite->getContentSize() / 2 - ccp(0, -4.f));
- removeCurveSprite->addChild(removeCurveLabel);
- auto removeCurveBtn = CCMenuItemSpriteExtra::create(removeCurveSprite, this, menu_selector(G3DCurveEditorLayer::onRemoveSegment));
- removeCurveBtn->setPosition(100, size.height - 20);
- uiMenu->addChild(removeCurveBtn);
-
- layer3d = G3DBaseNode::create();
- layer3d->camera.setPosition(glm::vec3(0, 0, 15));
- layer3d->light.setPosition(glm::vec3(0, 50, 1000));
- layer3d->setZOrder(10);
-
- setKeyboardEnabled(true);
-
- auto bms = BlockModelStorage::get();
- pointModel = bms->getModel(bms->getBP() / "editor" / "model" / "point.obj");
- pointModel->setScale(glm::vec3(0.2f));
- layer3d->models.push_back(pointModel);
-
- this->addChild(layer3d);
-
- return true;
- }
-
-
-
- void G3DCurveEditorLayer::onAddSegment(CCObject*)
- {
- auto p1 = spline->segments.back()->p2;
- auto m1 = spline->segments.back()->p2 * 2.f - spline->segments.back()->m2;
- auto m2 = spline->segments.back()->p2 * 2.f - spline->segments.back()->m1;
- auto p2 = spline->segments.back()->p2 * 2.f - spline->segments.back()->p1;
-
- spline->addSegment(new Curve(p1, m1, m2, p2));
- }
-
-
- void G3DCurveEditorLayer::onRemoveSegment(CCObject*) {
- if (spline->segments.size() > 1)
- spline->removeLastSegment();
- }
-
- void G3DCurveEditorLayer::draw() {
- if (!this->isVisible()) return;
-
- if (!isRightClicking) {
- spline->updateParameterList();
- }
-
- auto shader = layer3d->shaderProgram;
-
- OpenGLStateHelper::saveState();
- for (auto segment : spline->segments) {
- pointModel->meshes[0]->setCustomKa(glm::vec3(1, 0, 0));
- pointModel->setScale(glm::vec3(0.07));
- pointModel->setPosition(segment->p1);
- pointModel->render(shader, layer3d->camera.getViewMat(), layer3d->light.getPosition(), layer3d->light.getColor(), layer3d->camera.getPosition(), layer3d->camera.getProjectionMat());
- pointModel->setPosition(segment->p2);
- pointModel->render(shader, layer3d->camera.getViewMat(), layer3d->light.getPosition(), layer3d->light.getColor(), layer3d->camera.getPosition(), layer3d->camera.getProjectionMat());
-
- pointModel->meshes[0]->setCustomKa(glm::vec3(0, 1, 0));
- pointModel->setScale(glm::vec3(0.05));
- pointModel->setPosition(segment->m1);
- pointModel->render(shader, layer3d->camera.getViewMat(), layer3d->light.getPosition(), layer3d->light.getColor(), layer3d->camera.getPosition(), layer3d->camera.getProjectionMat());
- pointModel->setPosition(segment->m2);
- pointModel->render(shader, layer3d->camera.getViewMat(), layer3d->light.getPosition(), layer3d->light.getColor(), layer3d->camera.getPosition(), layer3d->camera.getProjectionMat());
- }
-
-
- for (float i = 0; i < 3; i += 0.005) {
- pointModel->setPosition(spline->get(i));
- pointModel->meshes[0]->setCustomKa(glm::vec3(0.5, 0.5, 0.5));
- pointModel->setScale(glm::vec3(0.001));
- pointModel->render(shader, layer3d->camera.getViewMat(), layer3d->light.getPosition(), layer3d->light.getColor(), layer3d->camera.getPosition(), layer3d->camera.getProjectionMat());
- }
-
- float lengthScaleFactor = spline->length(10000) / levelLength;
-
-
- CCObject* obj;
- CCARRAY_FOREACH(lel->m_objects, obj) {
- auto block = static_cast(obj);
-
- auto data = spline->findClosestByLength(block->getPositionX() * lengthScaleFactor);
-
- auto pos = data.value;
- auto normal = glm::normalize(spline->normal(data.t));
- auto tangent = glm::normalize(spline->tangent(data.t));
-
- glm::vec3 side(1.f, 0.f, 0.f);
- float normalDeltaAngle = glm::radians(block->getRotation());
-
- glm::quat firstRotationQuat = glm::angleAxis(normalDeltaAngle, side);
-
- glm::vec3 binormal = glm::normalize(glm::cross(normal, tangent));
- glm::vec3 adjustedNormal = glm::normalize(glm::cross(tangent, binormal));
-
- glm::mat3 rotationMatrix(
- binormal,
- adjustedNormal,
- tangent);
-
- glm::quat rotationQuat = glm::quat_cast(rotationMatrix);
- glm::vec3 eulerDegrees = glm::degrees(glm::eulerAngles(rotationQuat * firstRotationQuat));
-
- auto bms = BlockModelStorage::get();
- if (auto blockModel = bms->getBlockModel(block->m_objectID))
- {
- blockModel->setPosition(pos + (normal * lengthScaleFactor * (block->getPositionY() - 110)));
- blockModel->setRotation(eulerDegrees);
- blockModel->setScale(glm::vec3(0.5 * (block->m_startFlipX ? -1 : 1) * lengthScaleFactor * 30, 0.5 * (block->m_startFlipY ? -1 : 1) * lengthScaleFactor * 30 * block->getScaleY(), 0.5 * lengthScaleFactor * 30 * block->getScaleX()));
- blockModel->render(
- layer3d->shaderProgram,
- layer3d->camera.getViewMat(),
- layer3d->light.getPosition(),
- layer3d->light.getColor(),
- layer3d->camera.getPosition(),
- layer3d->camera.getProjectionMat());
- }
- }
-
- OpenGLStateHelper::pushState();
- }
-
- void G3DCurveEditorLayer::scrollWheel(float y, float x) {
- float zoomSensitivity = -0.0328f;
- layer3d->camera.setPosition(layer3d->camera.getPosition() + layer3d->camera.getFront() * y * zoomSensitivity);
- }
-
- void G3DCurveEditorLayer::onKey(enumKeyCodes key, bool pressed, bool holding) {
- switch (key) {
- case KEY_Control:
- isPressingControl = pressed;
- break;
- case KEY_Shift:
- isPressingShift = pressed;
- break;
- }
- }
-
- G3DCurveEditorLayer* G3DCurveEditorLayer::create(LevelEditorLayer* lel) {
- auto ret = new G3DCurveEditorLayer();
- if (ret && ret->init(lel)) {
- ret->autorelease();
- return ret;
- }
- delete ret;
- return nullptr;
- }
-}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/editor/G3DCurveEditorLoader.cpp b/Geome3Dash/src/game/editor/G3DCurveEditorLoader.cpp
new file mode 100644
index 00000000..1d538ff0
--- /dev/null
+++ b/Geome3Dash/src/game/editor/G3DCurveEditorLoader.cpp
@@ -0,0 +1,100 @@
+#include "pch.h"
+
+#include "G3DCurveEditorLoader.h"
+#include "G3DCurveEditorPopup.h"
+
+#include "helper/spline/Curve.h"
+#include "helper/spline/Spline.h"
+#include "helper/OpenGLStateHelper.h"
+#include "game/component/G3DBaseNode.h"
+
+#include "engine/sus3d/Mesh.h"
+#include "engine/sus3d/Shader.h"
+#include "engine/sus3d/Shaders.h"
+
+#include "BlockModelStorage.h"
+
+namespace g3d
+{
+ void G3DCurveEditorLoader::updateLevel() {
+ levelLength = 0;
+
+ CCObject* obj;
+ CCARRAY_FOREACH(lel->m_objects, obj) {
+ auto block = static_cast(obj);
+
+ levelLength = std::max(block->getPositionX(), levelLength);
+ }
+
+ lengthScaleFactor = spline->length(10000) / levelLength;
+ }
+
+ bool G3DCurveEditorLoader::init(LevelEditorLayer* lel, Spline* defaultSpline) {
+ if (!CCNode::init()) return false;
+
+ this->lel = lel;
+
+ if (defaultSpline) {
+ spline = defaultSpline;
+ }
+ else {
+ spline = new Spline();
+ spline->addSegment(new Curve(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(3.0f, 0.0f, 0.0f)));
+ }
+
+ layer3d = G3DBaseNode::create();
+ layer3d->camera.setPosition(glm::vec3(0, 0, 15));
+ layer3d->light.setPosition(glm::vec3(0, 50, 1000));
+ layer3d->setZOrder(10);
+ layer3d->retain(); //sus
+
+ auto bms = BlockModelStorage::get();
+
+ blockShaderProgram = bms->getBlockSP();
+
+ pointModel = bms->getModel(bms->getBP() / "editor" / "model" / "sphere.obj");
+
+ updateLevel();
+ spline->updateParameterList();
+
+ return true;
+ }
+
+
+
+ void G3DCurveEditorLoader::addSegment() {
+ auto p1 = spline->segments.back()->p2;
+ auto m1 = spline->segments.back()->p2 * 2.f - spline->segments.back()->m2;
+ auto m2 = spline->segments.back()->p2 * 2.f - spline->segments.back()->m1;
+ auto p2 = spline->segments.back()->p2 * 2.f - spline->segments.back()->p1;
+
+ spline->addSegment(new Curve(p1, m1, m2, p2));
+
+ updateLevel();
+ }
+
+
+ void G3DCurveEditorLoader::removeSegment() {
+ if (spline->segments.size() > 1) {
+ spline->removeLastSegment();
+ updateLevel();
+ }
+ }
+
+ void G3DCurveEditorLoader::show() {
+ updateLevel();
+ G3DCurveEditorPopup::create(this)->show();
+ }
+
+
+ G3DCurveEditorLoader* G3DCurveEditorLoader::create(LevelEditorLayer* lel, Spline* defaultSpline) {
+ auto ret = new G3DCurveEditorLoader();
+ if (ret && ret->init(lel, defaultSpline)) {
+ ret->autorelease();
+ return ret;
+ }
+
+ delete ret;
+ return nullptr;
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/editor/G3DCurveEditorLoader.h b/Geome3Dash/src/game/editor/G3DCurveEditorLoader.h
new file mode 100644
index 00000000..eb7c52a4
--- /dev/null
+++ b/Geome3Dash/src/game/editor/G3DCurveEditorLoader.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "delegate/CustomKeyboard.h"
+#include "delegate/CustomMouse.h"
+#include "delegate/CustomTouch.h"
+
+namespace sus3d
+{
+ class Model;
+ class ShaderProgram;
+}
+
+namespace g3d
+{
+ class G3DBaseNode;
+ class Spline;
+
+ class G3DCurveEditorLoader : public CCNode {
+ G3DBaseNode* layer3d;
+ sus3d::Model* pointModel;
+ LevelEditorLayer* lel;
+ sus3d::ShaderProgram* blockShaderProgram;
+
+ float levelLength = 0;
+ float lengthScaleFactor;
+
+ virtual bool init(LevelEditorLayer* lel, Spline* defaultSpline);
+
+ void updateLevel();
+
+ void addSegment();
+ void removeSegment();
+
+ public:
+ Spline* spline;
+ void show();
+
+ static G3DCurveEditorLoader* create(LevelEditorLayer* lel, Spline* defaultSpline = nullptr);
+
+ friend class KeyframeEditorLayer;
+ friend class G3DCurveEditorPopup;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/editor/G3DCurveEditorPopup.cpp b/Geome3Dash/src/game/editor/G3DCurveEditorPopup.cpp
new file mode 100644
index 00000000..5507ec57
--- /dev/null
+++ b/Geome3Dash/src/game/editor/G3DCurveEditorPopup.cpp
@@ -0,0 +1,308 @@
+#include "pch.h"
+
+#include "G3DCurveEditorPopup.h"
+#include "G3DCurveEditorLoader.h"
+
+#include "helper/spline/Curve.h"
+#include "helper/spline/Spline.h"
+#include "helper/OpenGLStateHelper.h"
+#include "game/component/G3DBaseNode.h"
+
+#include "engine/sus3d/Mesh.h"
+#include "engine/sus3d/Shader.h"
+#include "engine/sus3d/Shaders.h"
+
+#include "BlockModelStorage.h"
+
+namespace g3d
+{
+
+ void G3DCurveEditorPopup::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int mods) {
+ if (!this->isVisible()) return;
+ if (button == GLFW_MOUSE_BUTTON_LEFT) {
+ if (action == GLFW_PRESS) {
+ isRightClicking = true;
+ isRightClickingGetPos = false;
+ }
+ else if (action == GLFW_RELEASE) {
+ isRightClicking = false;
+ }
+ }
+ }
+
+ void G3DCurveEditorPopup::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) {
+ if (!this->isVisible()) return;
+ if (isRightClicking) {
+ if (!isRightClickingGetPos) {
+ lastMouseX = static_cast(x);
+ lastMouseY = static_cast(y);
+ isRightClickingGetPos = true;
+ }
+ else {
+ float deltaX = static_cast(x) - lastMouseX;
+ float deltaY = static_cast(y) - lastMouseY;
+ if (isPressingShift) {
+
+
+ auto glView = CCDirector::sharedDirector()->m_pobOpenGLView;
+ int mouseX = static_cast(glView->m_fMouseX);
+ int mouseY = glView->getFrameSize().height - static_cast(glView->m_fMouseY);
+
+ OpenGLStateHelper::saveState();
+ glEnable(GL_DEPTH_TEST);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, cel->layer3d->framebuffer);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+ cel->layer3d->getObjectIDByMousePositionShader->use();
+
+ auto renderFunction = [&](int segmentIndex, glm::vec3 position) {
+ cel->pointModel->setScale(glm::vec3(0.07));
+ cel->pointModel->setPosition(position);
+ glm::mat4 model = cel->pointModel->prepareModelMatrix();
+ cel->layer3d->getObjectIDByMousePositionShader->setMat4("model", model);
+ cel->layer3d->getObjectIDByMousePositionShader->setMat4("view", cel->layer3d->camera.getViewMat());
+ cel->layer3d->getObjectIDByMousePositionShader->setMat4("projection", cel->layer3d->camera.getProjectionMat());
+ glm::vec3 uniqueColor = cel->layer3d->generateUniqueColor(5, segmentIndex);
+ cel->layer3d->getObjectIDByMousePositionShader->setVec3("color", uniqueColor);
+
+ for (auto mesh : cel->pointModel->meshes)
+ mesh->render(cel->layer3d->getObjectIDByMousePositionShader);
+ };
+
+ auto points = cel->spline->getAllPoints();
+
+ for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) {
+
+ renderFunction(pointIndex, points[pointIndex]);
+
+ }
+
+ glFlush();
+ glDisable(GL_DEPTH_TEST);
+
+ GLubyte pixelColor[3];
+ glReadPixels(mouseX, mouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ OpenGLStateHelper::pushState();
+
+ auto ids = cel->layer3d->getObjectAndMeshIDFromColor(pixelColor);
+
+ std::cout << ids.first << " " << ids.second << std::endl;
+ if (ids.second != -1) {
+ selected = ids.second;
+ }
+
+ glm::vec3 newPosition = points[selected];
+
+ glm::vec3 tangent = glm::normalize(glm::cross(cel->layer3d->camera.getUp(), cel->layer3d->camera.getFront()));
+ glm::vec3 bionormal = glm::normalize(glm::cross(cel->layer3d->camera.getFront(), tangent));
+
+ newPosition -= tangent * (deltaX * 0.01f);
+ newPosition -= bionormal * (deltaY * 0.01f);
+
+ cel->spline->editPointSymmetricCenterFix(selected, newPosition);
+
+ }
+ else if (isPressingControl) {
+ float sensitivity = 0.032f;
+
+ auto front = cel->layer3d->camera.getFront();
+ auto up = cel->layer3d->camera.getUp();
+ auto side = glm::normalize(glm::cross(front, up));
+
+ auto localUp = glm::normalize(glm::cross(side, front));
+
+ cel->layer3d->camera.setPosition(
+ cel->layer3d->camera.getPosition() +
+ deltaY * sensitivity * localUp +
+ deltaX * -sensitivity * side
+ );
+
+ //cel->layer3d->camera.setPosition(cel->layer3d->camera.getPosition() + cel->layer3d->camera.getUp() * deltaY * sensitivity);
+ //cel->layer3d->camera.setPosition(cel->layer3d->camera.getPosition() + glm::normalize(glm::cross(cel->layer3d->camera.getFront(), cel->layer3d->camera.getUp())) * deltaX * -sensitivity);
+ }
+ else {
+ float sensitivity = 0.05f;
+ float yaw = cel->layer3d->camera.getYaw() - deltaX * sensitivity;
+ float pitch = cel->layer3d->camera.getPitch() - deltaY * sensitivity;
+ pitch = std::clamp(pitch, -89.0f, 89.0f);
+ cel->layer3d->camera.setYaw(yaw);
+ cel->layer3d->camera.setPitch(pitch);
+ }
+ lastMouseX = static_cast(x);
+ lastMouseY = static_cast(y);
+ }
+ }
+ else {
+ selected = -1;
+ }
+ }
+
+
+
+ void G3DCurveEditorPopup::scrollWheel(float y, float x) {
+ float zoomSensitivity = -0.0328f;
+ cel->layer3d->camera.setPosition(cel->layer3d->camera.getPosition() + cel->layer3d->camera.getFront() * y * zoomSensitivity);
+ }
+
+ void G3DCurveEditorPopup::onKey(enumKeyCodes key, bool pressed, bool holding) {
+ switch (key) {
+ case KEY_Control:
+ isPressingControl = pressed;
+ break;
+ case KEY_Shift:
+ isPressingShift = pressed;
+ break;
+ }
+ }
+
+ void G3DCurveEditorPopup::onClose(CCObject* obj) {
+ this->setMouseEnabled(false);
+ Popup::onClose(obj);
+ }
+
+ bool G3DCurveEditorPopup::setup(G3DCurveEditorLoader* cel) {
+ this->setMouseEnabled(true);
+ this->cel = cel;
+
+ this->m_bgSprite->removeFromParent();
+ this->m_closeBtn->removeFromParent();
+
+ auto size = CCDirector::sharedDirector()->getWinSize();
+
+ auto bg = CCSprite::create("GJ_gradientBG.png");
+ bg->setScaleX(size.width / bg->getContentSize().width);
+ bg->setScaleY(size.height / bg->getContentSize().height);
+ bg->setColor({ 0, 75, 110 });
+ bg->setZOrder(-5);
+ bg->setPosition(size / 2);
+ this->addChild(bg);
+
+ this->m_buttonMenu->setPosition(size / 2);
+ auto backBtnSprite = CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png");
+ backBtnSprite->setScale(0.7);
+ auto backBtn = CCMenuItemSpriteExtra::create(backBtnSprite, this, menu_selector(G3DCurveEditorPopup::onClose));
+ backBtn->setPosition(20, size.height - 20);
+ this->m_buttonMenu->addChild(backBtn);
+
+ auto addCurveSprite = CCSprite::createWithSpriteFrameName("GJ_plainBtn_001.png");
+ addCurveSprite->setScale(0.7);
+ auto addCurveLabel = CCLabelBMFont::create("+", "bigFont.fnt", 80.f);
+ addCurveLabel->setScale(1.2);
+ addCurveLabel->setPosition(addCurveSprite->getContentSize() / 2 - ccp(0, -4.f));
+ addCurveSprite->addChild(addCurveLabel);
+ auto addCurveBtn = CCMenuItemSpriteExtra::create(addCurveSprite, this, menu_selector(G3DCurveEditorPopup::onAddSegment));
+ addCurveBtn->setPosition(60, size.height - 20);
+ this->m_buttonMenu->addChild(addCurveBtn);
+
+ auto removeCurveSprite = CCSprite::createWithSpriteFrameName("GJ_plainBtn_001.png");
+ removeCurveSprite->setScale(0.7);
+ auto removeCurveLabel = CCLabelBMFont::create("-", "bigFont.fnt", 80.f);
+ removeCurveLabel->setScale(1.2);
+ removeCurveLabel->setPosition(removeCurveSprite->getContentSize() / 2 - ccp(0, -4.f));
+ removeCurveSprite->addChild(removeCurveLabel);
+ auto removeCurveBtn = CCMenuItemSpriteExtra::create(removeCurveSprite, this, menu_selector(G3DCurveEditorPopup::onRemoveSegment));
+ removeCurveBtn->setPosition(100, size.height - 20);
+ this->m_buttonMenu->addChild(removeCurveBtn);
+
+ return true;
+ }
+
+ void G3DCurveEditorPopup::onAddSegment(CCObject*) {
+ cel->addSegment();
+ }
+
+ void G3DCurveEditorPopup::onRemoveSegment(CCObject*) {
+ cel->removeSegment();
+ }
+
+ void G3DCurveEditorPopup::draw() {
+
+ if (!isRightClicking) {
+ cel->spline->updateParameterList();
+ }
+ auto shaderProgram = BlockModelStorage::get()->getBlockSP();
+
+ OpenGLStateHelper::saveState();
+ for (auto segment : cel->spline->segments) {
+ cel->pointModel->meshes[0]->setCustomKa(glm::vec3(1, 0, 0));
+ cel->pointModel->setScale(glm::vec3(0.07));
+ cel->pointModel->setPosition(segment->p1);
+ cel->pointModel->render(shaderProgram, cel->layer3d->camera.getViewMat(), cel->layer3d->light.getPosition(), cel->layer3d->light.getColor(), cel->layer3d->camera.getPosition(), cel->layer3d->camera.getProjectionMat());
+ cel->pointModel->setPosition(segment->p2);
+ cel->pointModel->render(shaderProgram, cel->layer3d->camera.getViewMat(), cel->layer3d->light.getPosition(), cel->layer3d->light.getColor(), cel->layer3d->camera.getPosition(), cel->layer3d->camera.getProjectionMat());
+
+ cel->pointModel->meshes[0]->setCustomKa(glm::vec3(0, 1, 0));
+ cel->pointModel->setScale(glm::vec3(0.05));
+ cel->pointModel->setPosition(segment->m1);
+ cel->pointModel->render(shaderProgram, cel->layer3d->camera.getViewMat(), cel->layer3d->light.getPosition(), cel->layer3d->light.getColor(), cel->layer3d->camera.getPosition(), cel->layer3d->camera.getProjectionMat());
+ cel->pointModel->setPosition(segment->m2);
+ cel->pointModel->render(shaderProgram, cel->layer3d->camera.getViewMat(), cel->layer3d->light.getPosition(), cel->layer3d->light.getColor(), cel->layer3d->camera.getPosition(), cel->layer3d->camera.getProjectionMat());
+ }
+
+
+ for (float i = 0; i < 3; i += 0.005) {
+ cel->pointModel->setPosition(cel->spline->get(i));
+ cel->pointModel->meshes[0]->setCustomKa(glm::vec3(0.5, 0.5, 0.5));
+ cel->pointModel->setScale(glm::vec3(0.001));
+ cel->pointModel->render(shaderProgram, cel->layer3d->camera.getViewMat(), cel->layer3d->light.getPosition(), cel->layer3d->light.getColor(), cel->layer3d->camera.getPosition(), cel->layer3d->camera.getProjectionMat());
+ }
+
+
+ CCObject* obj;
+ CCARRAY_FOREACH(cel->lel->m_objects, obj) {
+ auto block = static_cast(obj);
+
+ auto data = cel->spline->findClosestByLength(block->getPositionX() * cel->lengthScaleFactor);
+
+ auto pos = data.value;
+ auto normal = glm::normalize(cel->spline->normal(data.t));
+ auto tangent = glm::normalize(cel->spline->tangent(data.t));
+
+ glm::vec3 side(1.f, 0.f, 0.f);
+ float normalDeltaAngle = glm::radians(block->getRotation());
+
+ glm::quat firstRotationQuat = glm::angleAxis(normalDeltaAngle, side);
+
+
+
+ glm::vec3 binormal = glm::normalize(glm::cross(normal, tangent));
+ glm::vec3 adjustedNormal = glm::normalize(glm::cross(tangent, binormal));
+
+
+ glm::mat3 rotationMatrix(
+ binormal,
+ adjustedNormal,
+ tangent
+ );
+
+ glm::quat rotationQuat = glm::quat_cast(rotationMatrix);
+ glm::vec3 eulerDegrees = glm::degrees(glm::eulerAngles(rotationQuat * firstRotationQuat));
+
+
+
+ BlockModelStorage::get()->tryRenderBlock(
+ block->m_objectID,
+ &cel->layer3d->camera,
+ &cel->layer3d->light);
+ }
+
+
+ OpenGLStateHelper::pushState();
+ }
+
+ G3DCurveEditorPopup* G3DCurveEditorPopup::create(G3DCurveEditorLoader* cel) {
+ auto ret = new G3DCurveEditorPopup();
+ auto size = CCDirector::sharedDirector()->getWinSize();
+ if (ret->initAnchored(size.width, size.height, cel)) {
+ ret->autorelease();
+ return ret;
+ }
+
+ delete ret;
+ return nullptr;
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/editor/G3DCurveEditorLayer.h b/Geome3Dash/src/game/editor/G3DCurveEditorPopup.h
similarity index 55%
rename from Geome3Dash/src/game/editor/G3DCurveEditorLayer.h
rename to Geome3Dash/src/game/editor/G3DCurveEditorPopup.h
index 9b734dab..dfef1281 100644
--- a/Geome3Dash/src/game/editor/G3DCurveEditorLayer.h
+++ b/Geome3Dash/src/game/editor/G3DCurveEditorPopup.h
@@ -15,20 +15,16 @@ namespace g3d
class G3DBaseNode;
class Spline;
- class G3DCurveEditorLayer
- : public CCLayer
+ class G3DCurveEditorLoader;
+
+ class G3DCurveEditorPopup
+ : public geode::Popup
, public CustomKeyboardDelegate
, public CustomMouseDelegate
, public CustomTouchDelegate
{
- G3DBaseNode* layer3d;
- sus3d::Model* pointModel;
-
- LevelEditorLayer* lel;
-
- CCSprite* bg;
-
- float levelLength = 0;
+ protected:
+ G3DCurveEditorLoader* cel;
int selected = -1;
@@ -44,35 +40,15 @@ namespace g3d
virtual void scrollWheel(float y, float x);
virtual void onKey(enumKeyCodes key, bool pressed, bool holding);
- virtual bool init(LevelEditorLayer* lel);
- virtual void draw();
+ bool setup(G3DCurveEditorLoader* cel) override;
- void updateLevel();
+ void draw() override;
void onAddSegment(CCObject*);
void onRemoveSegment(CCObject*);
+ void onClose(CCObject* obj);
public:
- Spline* spline;
- void show() {
-
- CCObject* obj;
- CCARRAY_FOREACH(lel->getChildren(), obj) {
- auto node = static_cast(obj);
- node->setVisible(0);
- }
- this->setVisible(1);
- updateLevel();
- }
- void hide(CCObject*) {
- CCObject* obj;
- CCARRAY_FOREACH(lel->getChildren(), obj) {
- auto node = static_cast(obj);
- node->setVisible(1);
- }
- this->setVisible(0);
- }
-
- static G3DCurveEditorLayer* create(LevelEditorLayer* lel);
+ static G3DCurveEditorPopup* create(G3DCurveEditorLoader* cel);
};
}
\ No newline at end of file
diff --git a/Geome3Dash/src/game/playing/G3DPlayLayer.h b/Geome3Dash/src/game/playing/G3DPlayLayer.h
index fb24cc05..4a3b178a 100644
--- a/Geome3Dash/src/game/playing/G3DPlayLayer.h
+++ b/Geome3Dash/src/game/playing/G3DPlayLayer.h
@@ -18,10 +18,15 @@
#include "helper/OpenGLStateHelper.h"
#include "helper/BezierHelper.h"
+#include "transformer/AnimationGameObjectModelTransformer.h"
+#include "transformer/BezierCameraPlayerObjectModelTransformer.h"
+#include "transformer/BezierGameObjectModelTransformer.h"
+#include "transformer/FadeGameObjectModelTransformer.h"
+
#include "CameraAction.h"
#include "BezierManager.h"
#include "CocosShaderProgram.h"
-#include "GameObjectModel.h"
+#include "PlayerObjectModel.h"
namespace g3d
{
diff --git a/Geome3Dash/src/hook/LevelEditorLayer.cpp b/Geome3Dash/src/hook/LevelEditorLayer.cpp
index 109b04de..ed9bc1d1 100644
--- a/Geome3Dash/src/hook/LevelEditorLayer.cpp
+++ b/Geome3Dash/src/hook/LevelEditorLayer.cpp
@@ -1,13 +1,15 @@
#include "pch.h"
#include "game/editor/G3DEditorPopup.h"
-#include "game/editor/G3DCurveEditorLayer.h"
+#include "game/editor/G3DCurveEditorLoader.h"
+#include "helper/spline/Spline.h"
+#include "helper/spline/Curve.h"
namespace g3d
{
class $modify(LevelEditorLayerG3D, LevelEditorLayer)
{
struct Fields {
- G3DCurveEditorLayer* curveEditorLayer = nullptr;
+ G3DCurveEditorLoader* curveEditorLayer = nullptr;
};
//std::optional getFrameName(CCSprite* sprite)
@@ -77,7 +79,11 @@ namespace g3d
auto menu2 = CCMenuItemSpriteExtra::create(sprite2, this, menu_selector(LevelEditorLayerG3D::onSplineEditor));
addG3DMenu(1, "PATH", settingsButton, settingsMenu, menu2, sprite2);
- m_fields->curveEditorLayer = G3DCurveEditorLayer::create(this);
+ // testing
+ auto spline = new Spline();
+ spline->addSegment(new Curve(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(3.0f, 0.0f, 0.0f)));
+
+ m_fields->curveEditorLayer = G3DCurveEditorLoader::create(this, spline);
this->addChild(m_fields->curveEditorLayer);
return true;
diff --git a/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.cpp b/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.cpp
new file mode 100644
index 00000000..816f8c16
--- /dev/null
+++ b/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.cpp
@@ -0,0 +1,15 @@
+#include "pch.h"
+
+#include "AnimationGameObjectModelTransformer.h"
+#include "GameObjectModel.h"
+
+namespace g3d
+{
+ void AnimationGameObjectModelTransformer::transform(GameObjectModel* gom)
+ {
+ switch (gom->getGameObject()->m_objectID)
+ {
+ // do animations
+ }
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.h b/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.h
new file mode 100644
index 00000000..b1052703
--- /dev/null
+++ b/Geome3Dash/src/transformer/AnimationGameObjectModelTransformer.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "GameObjectModelTransformer.h"
+
+namespace g3d
+{
+ class AnimationGameObjectModelTransformer : public GameObjectModelTransformer
+ {
+ public:
+ virtual void transform(GameObjectModel* gom) override;
+ virtual ~AnimationGameObjectModelTransformer() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.cpp b/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.cpp
new file mode 100644
index 00000000..7d658a0f
--- /dev/null
+++ b/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.cpp
@@ -0,0 +1,34 @@
+#include "pch.h"
+
+#include "BezierCameraPlayerObjectModelTransformer.h"
+#include "game/playing/G3DPlayLayer.h"
+
+namespace g3d
+{
+ void BezierCameraPlayerObjectModelTransformer::transform(GameObjectModel* gom)
+ {
+ if (auto pom = dynamic_cast(gom))
+ {
+ auto playerPos = pom->getPosition();
+ auto newR = pom->getRotation();
+ auto playerYaw = newR.y;
+ auto playerYawR = -glm::radians(playerYaw);
+ const auto playerCameraOffset = playLayer3d->playerCameraOffset;
+ const auto playerCameraYawOffset = playLayer3d->playerCameraYawOffset;
+ const auto playerCameraPitchOffset = playLayer3d->playerCameraPitchOffset;
+
+ glm::vec3 rotatedOffset =
+ {
+ playerCameraOffset.x * std::cos(playerYawR) - playerCameraOffset.z * std::sin(playerYawR),
+ playerCameraOffset.y,
+ playerCameraOffset.x * std::sin(playerYawR) + playerCameraOffset.z * std::cos(playerYawR)
+ };
+
+ playLayer3d->camera.setPosition(playerPos + rotatedOffset);
+ // Clamp pitch to prevent flipping
+ playLayer3d->camera.setYaw(playerCameraYawOffset - playerYaw);
+ auto pitch = std::clamp(static_cast(playerCameraPitchOffset), -89.0f, 89.0f);
+ playLayer3d->camera.setPitch(pitch);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.h b/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.h
new file mode 100644
index 00000000..0d1f0f64
--- /dev/null
+++ b/Geome3Dash/src/transformer/BezierCameraPlayerObjectModelTransformer.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "GameObjectModelTransformer.h"
+
+namespace g3d
+{
+ class G3DPlayLayer;
+ class BezierCameraPlayerObjectModelTransformer : public GameObjectModelTransformer
+ {
+ public:
+ G3DPlayLayer* playLayer3d;
+ virtual void transform(GameObjectModel* gom) override;
+ BezierCameraPlayerObjectModelTransformer(G3DPlayLayer* playLayer3d)
+ : playLayer3d(playLayer3d)
+ {
+
+ }
+ virtual ~BezierCameraPlayerObjectModelTransformer() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.cpp b/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.cpp
new file mode 100644
index 00000000..9a5b63fc
--- /dev/null
+++ b/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.cpp
@@ -0,0 +1,17 @@
+#include "pch.h"
+
+#include "BezierGameObjectModelTransformer.h"
+#include "GameObjectModel.h"
+
+namespace g3d
+{
+ void BezierGameObjectModelTransformer::transform(GameObjectModel* gom)
+ {
+ auto bCoordinate = BezierManager::transformIntoBezierCoordinate(
+ bezier,
+ gom->getPositionX(), gom->getPositionY(), gom->getPositionZ(),
+ bezierSegmentCount, bezierSegmentMultiplier);
+ gom->setPosition(bCoordinate.position);
+ gom->setRotationY(360 - bCoordinate.rotation);
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.h b/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.h
new file mode 100644
index 00000000..732a30fc
--- /dev/null
+++ b/Geome3Dash/src/transformer/BezierGameObjectModelTransformer.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "GameObjectModelTransformer.h"
+#include "BezierManager.h"
+
+namespace g3d
+{
+ class BezierGameObjectModelTransformer : public GameObjectModelTransformer
+ {
+ protected:
+ CubicBezier bezier;
+ double bezierSegmentMultiplier;
+ int bezierSegmentCount;
+ public:
+ virtual void transform(GameObjectModel* gom) override;
+ BezierGameObjectModelTransformer(
+ const CubicBezier& bezier,
+ const double bezierSegmentMultiplier,
+ const int bezierSegmentCount)
+ : bezier(bezier)
+ , bezierSegmentMultiplier(bezierSegmentMultiplier)
+ , bezierSegmentCount(bezierSegmentCount)
+ {
+
+ }
+ virtual ~BezierGameObjectModelTransformer() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.cpp b/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.cpp
new file mode 100644
index 00000000..09ff75b1
--- /dev/null
+++ b/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.cpp
@@ -0,0 +1,9 @@
+#include "pch.h"
+
+#include "DefaultGameObjectModelTransformer.h"
+#include "GameObjectModel.h"
+
+namespace g3d
+{
+
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.h b/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.h
new file mode 100644
index 00000000..30f3b28c
--- /dev/null
+++ b/Geome3Dash/src/transformer/DefaultGameObjectModelTransformer.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "GameObjectModelTransformer.h"
+
+namespace g3d
+{
+ class DefaultGameObjectModelTransformer : public GameObjectModelTransformer
+ {
+ public:
+ virtual void transform(GameObjectModel* gom) override {};
+ virtual ~DefaultGameObjectModelTransformer() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.cpp b/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.cpp
new file mode 100644
index 00000000..fe22e7e4
--- /dev/null
+++ b/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.cpp
@@ -0,0 +1,22 @@
+#include "pch.h"
+
+#include "FadeGameObjectModelTransformer.h"
+#include "GameObjectModel.h"
+
+namespace g3d
+{
+ void FadeGameObjectModelTransformer::transform(GameObjectModel* gom)
+ {
+ auto obj = gom->getGameObject();
+ auto distance = std::abs(gameLayer->m_player1->m_position.x - obj->getPositionX());
+ if (distance > maxRender) {
+ gom->setVisible(false);
+ gom->setOpacity(0);
+ }
+ else if (distance > startFade) {
+ auto scale = gom->getScale();
+ double tNormal = (distance - startFade) / (maxRender - startFade);
+ gom->setScale(ease::easeNormal(easing, tNormal, scale, target));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.h b/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.h
new file mode 100644
index 00000000..a3214bee
--- /dev/null
+++ b/Geome3Dash/src/transformer/FadeGameObjectModelTransformer.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "GameObjectModelTransformer.h"
+
+#include "helper/Easing.h"
+
+namespace g3d
+{
+ class FadeGameObjectModelTransformer : public GameObjectModelTransformer
+ {
+ protected:
+ GJBaseGameLayer* gameLayer;
+ double maxRender;
+ double startFade;
+ ease::Base* easing;
+ glm::vec3 target;
+ public:
+ double getMaxRender() { return maxRender; }
+ virtual void transform(GameObjectModel* gom) override;
+ FadeGameObjectModelTransformer(
+ GJBaseGameLayer* layer,
+ double maxR,
+ double startF,
+ ease::Base* easeFunc,
+ const glm::vec3& tgt)
+ : gameLayer(layer)
+ , maxRender(maxR)
+ , startFade(startF)
+ , easing(easeFunc)
+ , target(tgt)
+ {
+
+ }
+
+ virtual ~FadeGameObjectModelTransformer() = default;
+ };
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/GameObjectModelTransformer.cpp b/Geome3Dash/src/transformer/GameObjectModelTransformer.cpp
new file mode 100644
index 00000000..4ccbd6e1
--- /dev/null
+++ b/Geome3Dash/src/transformer/GameObjectModelTransformer.cpp
@@ -0,0 +1,9 @@
+#include "pch.h"
+
+#include "GameObjectModelTransformer.h"
+#include "GameObjectModel.h"
+
+namespace g3d
+{
+
+}
\ No newline at end of file
diff --git a/Geome3Dash/src/transformer/GameObjectModelTransformer.h b/Geome3Dash/src/transformer/GameObjectModelTransformer.h
new file mode 100644
index 00000000..582d3923
--- /dev/null
+++ b/Geome3Dash/src/transformer/GameObjectModelTransformer.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace g3d
+{
+ class GameObjectModel;
+ class GameObjectModelTransformer
+ {
+ public:
+ virtual void transform(GameObjectModel* gom) = 0;
+ virtual ~GameObjectModelTransformer() {}
+ };
+}
\ No newline at end of file