Merge pull request #111 from QuasarApp/dev

Next version
This commit is contained in:
Andrei Yankovich 2021-10-08 22:58:22 +03:00 committed by GitHub
commit 954e1bcac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 549 additions and 23 deletions

View File

@ -22,10 +22,14 @@ void GroupObject::render(unsigned int tbfMsec) {
for (ClasterItem* object: objects()) {
if (Localpropertys *props = getLocalpropertys(object->guiId())) {
if (!props->_rotation.isNull())
object->setRotation(_this->rotation() * props->_rotation);
object->setposition(_this->position() + props->_position);
QVector3D reCalcVectorPs = reCalcPos(props->_position,
_this->rotation().toEulerAngles());
object->setposition(_this->position() + reCalcVectorPs);
}
}
@ -48,6 +52,31 @@ void GroupObject::updateRotation(int id, const QQuaternion &roatation) {
_extrapropertys[id]._rotation = roatation;
}
const QVector3D GroupObject::reCalcPos(const QVector3D& pos, const QVector3D &eulerAngles) const
{
float alha = eulerAngles.z();
float beta = eulerAngles.y();
float gamma = eulerAngles.x();
float x = pos.x();
float y = pos.y();
float z = pos.z();
float newX = x*(qCos(alha)*qCos(beta)) +
y*(qCos(alha)*qSin(beta)*qSin(gamma) - qSin(alha)*qCos(gamma)) +
z*(qCos(alha)*qSin(beta)*qCos(gamma) + qSin(alha)*qSin(gamma));
float newY = x*(qSin(alha)*qCos(beta)) +
y*(qSin(alha)*qSin(beta)*qSin(gamma) + qCos(alha)*qCos(gamma)) +
z*(qSin(alha)*qSin(beta)*qCos(gamma) - qCos(alha)*qSin(gamma));
float newZ = x*(-qSin(beta)) +
y*(qCos(beta)*qSin(gamma)) +
z*(qCos(beta)*qCos(gamma));
return QVector3D({newX, newY, newZ});
}
QQuaternion *GroupObject::getLocalrotation(int id) {
if (_extrapropertys.contains(id)) {
return &_extrapropertys[id]._rotation;

View File

@ -123,6 +123,8 @@ protected:
private:
QHash<int, Localpropertys> _extrapropertys;
const QVector3D reCalcPos(const QVector3D& pos, const QVector3D& eulerAngles) const;
};
}
#endif // GROUPOBJECT_H

125
src/Core/Crawl/layout.cpp Normal file
View File

@ -0,0 +1,125 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "layout.h"
#include "clasteritem.h"
#include <QtMath>
namespace CRAWL {
Layout::Layout() {
}
void Layout::add(ClasterItem *object) {
Claster::add(object);
updatePosition();
}
void Layout::remove(ClasterItem *object) {
Claster::remove(object);
updatePosition();
}
void Layout::changeLayout(const LayoutType &fig) {
_shape = fig;
updatePosition();
}
void Layout::setDistance(int dist) {
_distance = dist;
updatePosition();
}
void Layout::updatePosition() {
switch (_shape) {
case CIRCLE:
drawCircle();
break;
case SQUARE:
drawSquare();
break;
case LINE:
drawLine();
break;
default:
break;
}
}
void Layout::drawCircle() {
if (objects().size() == 0) {
QuasarAppUtils::Params::log(QString("The number of objects is zero. Add object."), QuasarAppUtils::Error);
return;
}
float step = 360 / objects().size();
int temp = 0;
for (ClasterItem* object: objects()) {
float x = _distance * qCos(step*temp);
float y = _distance * qSin(step*temp);
GroupObject::updatePosition(object->guiId(), {x, y, 0});
temp++;
}
}
void Layout::drawSquare() {
if (objects().size() == 0) {
QuasarAppUtils::Params::log(QString("The number of objects is zero. Add object."), QuasarAppUtils::Error);
return;
}
int height = qFloor(qSqrt(objects().size()));
int width = qFloor(objects().size() / height);
int indObject = 0;
for (auto idObj = objects().keyBegin(); idObj != objects().keyEnd(); idObj++) {
float x = indObject % height;
float y = qCeil(indObject / height);
GroupObject::updatePosition(*idObj, {(x * _distance) - (height * _distance / 2),
(y * _distance) - (width * _distance / 2), 0});
indObject++;
}
}
void Layout::drawLine() {
if (objects().size() == 0) {
QuasarAppUtils::Params::log(QString("The number of objects is zero. Add object."), QuasarAppUtils::Error);
return;
}
float xObject = 0;
float height = objects().size() * _distance;
for (auto idObj = objects().keyBegin(); idObj != objects().keyEnd(); idObj++) {
GroupObject::updatePosition(*idObj, {(xObject * _distance) - (height/2 * _distance), 0, 0});
xObject++;
}
}
}

127
src/Core/Crawl/layout.h Normal file
View File

@ -0,0 +1,127 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef LAYOUT_H
#define LAYOUT_H
#include <Crawl/groupobject.h>
namespace CRAWL {
/**
* @brief The LayoutType enum Lists the shapes to convert the group object to.
*/
enum LayoutType {
/// The circle property calls the drawCircle method, which recalculates and updates
/// the coordinates of the passed object's positions.
CIRCLE,
/// The square property calls the drawSquare method, which updates the coordinates of
/// the objects' positions, giving them the shape of a square.
SQUARE,
/// The LINE property calls the drawLine method, which updates the coordinates of the
/// objects' positions, giving it a line shape.
LINE
};
/**
* @brief The Layout class The class that control position of group objects.
* ### Requried child classes: IWorldItem
*
* This class overloads the add() and remove() methods, which add objects to the cluster while updating positions according to the selected LayoutType.
* Has two public methods for setting the distance to the object and selecting the grouping of objects.
*
* ## Example of use
*
* ### For what this object uses
* This object is convenient to use if you want to create a cluster object directly, within which subobjects are grouped into a circle or square, depending on the selected property.
* For example : snake obstacle.
*
* ### Example of use
*
* 1. Create the GroupObjObstacle class.
*
* ```cpp
*
* class GroupObjObstacle: public CRAWL::Layout, public CRAWL::IWorldItem {
*
* // sets the distance to the object from the center.
* setDistance(20);
*
* // Set the property of grouping objects
* changeLayout(CRAWL::LayoutType::CIRCLE);
*
* for(int i(0); i < 20; i++) {
* add(new BoxItem);
* }
*
* };
* ```
*
* @note The added object must inherit from ClasterItem and have a child class required for overloading software renderers.
*
* All done. Now the added objects will be grouped into a circle shape.
*
* You can change the center-to-object distance and the shape of a group of objects using the setDistance and changeLayout methods.
*
* @note This class requried the GuiObject functions as a parent class.
* @note This class requires an overload of the render method; The implementation must call the render methods of the parent classes.
*
*/
class Layout: public GroupObject {
public:
Layout();
// Claster interface
public:
void add(ClasterItem *object);
void remove(ClasterItem *object);
/**
* @brief changeLayout This method defines the shape of the group object.
* @param fig This is the name of the figure to change the group object.
*/
void changeLayout(const LayoutType &fig);
/**
* @brief setDistance This method sets, depending on the shape selected, the radius for the circle or the indentation for the square.
* @param dist This is the radius or margin.
*/
void setDistance(int dist);
private:
/**
* @brief updatePosition This method updates the coordinates of the positions of all objects.
*/
void updatePosition();
/**
* @brief drawCircle This method updates the coordinates to a circle shape.
*/
void drawCircle();
/**
* @brief drawSquare This method updates the coordinates to a square shape.
*/
void drawSquare();
/**
* @brief drawLine This method updates the coordinates to a line shape.
*/
void drawLine();
int _distance;
LayoutType _shape;
};
}
#endif // LAYOUT_H

View File

@ -12,6 +12,7 @@
#include "abslvlworld.h"
#include <abslvlsnake.h>
#include "Crawl/iworlditem.h"
#include "groupobstaclered.h"
#include "Crawl/defaultlight.h"
@ -31,23 +32,23 @@ CRAWL::WorldRule *AbsLvlWorld::initWorldRules() {
return new CRAWL::WorldRule {
{0,
{
{registerObject<Baff>(), 10}, {registerObject<CRAWL::DefaultLight>(), 1}
}
},
{20,
{200,
{
{registerObject<ObstacleBlue>(), 10}, {registerObject<CRAWL::DefaultLight>(), 1}
}
},
{30,
{250,
{
{registerObject<ObstacleRed>(), 40}, {registerObject<CRAWL::DefaultLight>(), 1}
{registerObject<GroupObstacleRed>(), 1}, {registerObject<CRAWL::DefaultLight>(), 1}
}
}
},
// {30,
// {
// {registerObject<ObstacleRed>(), 40}, {registerObject<CRAWL::DefaultLight>(), 1}
// }
// }
};
}

View File

@ -0,0 +1,37 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "obstaclerebitem.h"
#include "groupobstaclered.h"
namespace AbstractLvl {
GroupObstacleRed::GroupObstacleRed(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
QQuaternion rotation =
QQuaternion::fromEulerAngles(QVector3D(0,0,90));
setDistance(7);
setRotation(rotation);
changeLayout(CRAWL::LayoutType::LINE);
for(int i(0); i < 10; i++) {
add(new ObstacleRebItem);
}
}
void GroupObstacleRed::render(unsigned int tbfMsec) {
Layout::render(tbfMsec);
IWorldItem::render(tbfMsec);
}
void GroupObstacleRed::init() {
}
}

View File

@ -0,0 +1,27 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef GROUPOBSTACLERED_H
#define GROUPOBSTACLERED_H
#include "Crawl/layout.h"
#include "Crawl/clasteritem.h"
namespace AbstractLvl {
class GroupObstacleRed: public CRAWL::Layout, public CRAWL::IWorldItem {
public:
GroupObstacleRed();
// IRender interface
public:
void render(unsigned int tbfMsec);
void init();
};
}
#endif // GROUPOBSTACLERED_H

View File

@ -0,0 +1,20 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "obstaclerebitem.h"
namespace AbstractLvl {
ObstacleRebItem::ObstacleRebItem() {
}
void ObstacleRebItem::render(unsigned int tbfMsec) {
}
}

View File

@ -0,0 +1,26 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef OBSTACLEREBITEM_H
#define OBSTACLEREBITEM_H
#include "obstaclered.h"
namespace AbstractLvl {
class ObstacleRebItem: public ObstacleRed {
public:
ObstacleRebItem();
// IRender interface
public:
void render(unsigned int tbfMsec);
};
}
#endif // OBSTACLEREBITEM_H

View File

@ -9,7 +9,7 @@
namespace AbstractLvl {
ObstacleRed::ObstacleRed() : IWorldItem(AUTO_CLASS_NAME) {
ObstacleRed::ObstacleRed() : CRAWL::ClasterItem(AUTO_CLASS_NAME) {
setMash("qrc:/mesh/meshes/ObstacleRed.mesh");
setSize({1,1,1});
setColor("#ff1927");

View File

@ -7,11 +7,11 @@
#ifndef OBJOBSTACLERED_H
#define OBJOBSTACLERED_H
#include "Crawl/iworlditem.h"
#include "Crawl/clasteritem.h"
namespace AbstractLvl {
class ObstacleRed: public CRAWL::IWorldItem {
class ObstacleRed: public CRAWL::ClasterItem {
public:
ObstacleRed();

View File

@ -11,7 +11,7 @@
namespace TestLvl {
Box::Box(): IWorldItem("Box") {
Box::Box(): ClasterItem("Box") {
setMash("qrc:/mesh/meshes/cube.mesh");
setSize({2,2,2});
setColor(QColor::fromRgb(rand()).name());

View File

@ -7,12 +7,12 @@
#ifndef BOX_H
#define BOX_H
#include "Crawl/iworlditem.h"
#include "Crawl/clasteritem.h"
namespace TestLvl {
class Box: public CRAWL::IWorldItem {
class Box: public CRAWL::ClasterItem {
public:
Box();

View File

@ -0,0 +1,22 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "boxitem.h"
namespace TestLvl {
BoxItem::BoxItem()
{
}
void BoxItem::render(unsigned int tbfMsec)
{
}
}

View File

@ -0,0 +1,25 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef BOXITEM_H
#define BOXITEM_H
#include "box.h"
namespace TestLvl {
class BoxItem: public Box {
public:
BoxItem();
// IRender interface
public:
void render(unsigned int tbfMsec);
};
}
#endif // BOXITEM_H

View File

@ -0,0 +1,38 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "boxitem.h"
#include "groupobjbox.h"
namespace TestLvl {
GroupObjBox::GroupObjBox(): CRAWL::IWorldItem("GroupObjBox") {
setDistance(20);
changeLayout(CRAWL::LayoutType::CIRCLE);
for(int i(0); i < 20; i++) {
add(new BoxItem);
}
}
void GroupObjBox::render(unsigned int tbfMsec)
{
Layout::render(tbfMsec);
IWorldItem::render(tbfMsec);
}
void GroupObjBox::init()
{
}
}

View File

@ -0,0 +1,29 @@
//#
//# Copyright (C) 2021-2021 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#ifndef GROUPOBJBOX_H
#define GROUPOBJBOX_H
#include "Crawl/layout.h"
#include "Crawl/clasteritem.h"
namespace TestLvl {
class GroupObjBox: public CRAWL::Layout, public CRAWL::IWorldItem {
public:
GroupObjBox();
// IRender interface
public:
void render(unsigned int tbfMsec);
void init();
};
}
#endif // GROUPOBJBOX_H

View File

@ -18,6 +18,7 @@
#include <Crawl/fire.h>
#include <Crawl/moon.h>
#include <Crawl/sun.h>
#include <groupobjbox.h>
namespace TestLvl {
@ -31,12 +32,18 @@ CRAWL::WorldRule *World::initWorldRules() {
using Day = CRAWL::Day<CRAWL::Sun, CRAWL::Moon>;
return new CRAWL::WorldRule {
{0, {{registerObject<Box>(), 1000},
{0, {{registerObject<Box>(), 100},
{registerObject<CRAWL::Fire>(), 10},
{registerObject<CRAWL::DynamicWint>(), 1},
{registerObject<Background>(), 1},
{registerObject<Day>(), 1}}}
{registerObject<Day>(), 1}}},
{300,
{
{registerObject<GroupObjBox>(),5}
}
},
};
}

View File

@ -16,4 +16,8 @@ Ground::Ground() : CRAWL::GroundClaster("JungelGroud") {
unsigned int Ground::itemsCount() const {
return 3;
}
int Ground::newObjectDistance() const {
return 150;
}
}

View File

@ -21,6 +21,10 @@ class Ground : public CRAWL::GroundClaster
public:
Ground();
unsigned int itemsCount() const override;
// GroundClaster interface
protected:
int newObjectDistance() const;
};
}

View File

@ -14,6 +14,7 @@ namespace JungleLvl {
class World : public CRAWL::IWorld {
Q_OBJECT
// IWorld interface
public:

View File

@ -73,14 +73,16 @@ void GroupObjectTest::testBehavior() const {
QVector3D localPosition = {10,0,0};
QQuaternion localRotation = QQuaternion::fromEulerAngles(0,5,0);
object.updatePosition(item.guiId(), localPosition);
object.updateRotation(item.guiId(), localRotation);
object.render(0);
// after invoke the render function all positions and rotations should be changed
QVERIFY(item.rotation() == (object.rotation() * localRotation));
object.updatePosition(item.guiId(), localPosition);
object.setRotation(QQuaternion::fromEulerAngles(0,0,0));
object.render(0);
// after invoke the render function all positions and rotations should be changed
QVERIFY(item.position() == (object.position() + localPosition));
QVERIFY(item.rotation() == (object.rotation() * localRotation));
object.remove(&item);