Skip to content

Commit

Permalink
Clouds should now properly work with the new iron
Browse files Browse the repository at this point in the history
The blending between the cloud groups isn't that great but at least
they are kinda blending.
  • Loading branch information
hhyyrylainen committed Feb 15, 2019
1 parent 9c2904e commit 437b92f
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 74 deletions.
149 changes: 82 additions & 67 deletions src/microbe_stage/compound_cloud_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,12 @@ void
if(x >= m_density1.size() || y >= m_density1[0].size())
throw std::runtime_error(
"CompoundCloudComponent coordinates out of range");
if(compound != NULL_COMPOUND) {
switch(getSlotForCompound(compound)) {
case SLOT::FIRST: m_density1[x][y] += dens; break;
case SLOT::SECOND: m_density2[x][y] += dens; break;
case SLOT::THIRD: m_density3[x][y] += dens; break;
case SLOT::FOURTH: m_density4[x][y] += dens; break;
}

switch(getSlotForCompound(compound)) {
case SLOT::FIRST: m_density1[x][y] += dens; break;
case SLOT::SECOND: m_density2[x][y] += dens; break;
case SLOT::THIRD: m_density3[x][y] += dens; break;
case SLOT::FOURTH: m_density4[x][y] += dens; break;
}
}

Expand All @@ -175,41 +174,39 @@ int
size_t y,
float rate)
{
if(compound != NULL_COMPOUND) {
switch(getSlotForCompound(compound)) {
case SLOT::FIRST: {
int amountToGive = static_cast<int>(m_density1[x][y] * rate);
m_density1[x][y] -= amountToGive;
if(m_density1[x][y] < 1)
m_density1[x][y] = 0;

return amountToGive;
}
case SLOT::SECOND: {
int amountToGive = static_cast<int>(m_density2[x][y] * rate);
m_density2[x][y] -= amountToGive;
if(m_density2[x][y] < 1)
m_density2[x][y] = 0;
switch(getSlotForCompound(compound)) {
case SLOT::FIRST: {
int amountToGive = static_cast<int>(m_density1[x][y] * rate);
m_density1[x][y] -= amountToGive;
if(m_density1[x][y] < 1)
m_density1[x][y] = 0;

return amountToGive;
}
case SLOT::SECOND: {
int amountToGive = static_cast<int>(m_density2[x][y] * rate);
m_density2[x][y] -= amountToGive;
if(m_density2[x][y] < 1)
m_density2[x][y] = 0;

return amountToGive;
}
case SLOT::THIRD: {
int amountToGive = static_cast<int>(m_density3[x][y] * rate);
m_density3[x][y] -= amountToGive;
if(m_density3[x][y] < 1)
m_density3[x][y] = 0;
return amountToGive;
}
case SLOT::THIRD: {
int amountToGive = static_cast<int>(m_density3[x][y] * rate);
m_density3[x][y] -= amountToGive;
if(m_density3[x][y] < 1)
m_density3[x][y] = 0;

return amountToGive;
}
case SLOT::FOURTH: {
int amountToGive = static_cast<int>(m_density4[x][y] * rate);
m_density4[x][y] -= amountToGive;
if(m_density4[x][y] < 1)
m_density4[x][y] = 0;
return amountToGive;
}
case SLOT::FOURTH: {
int amountToGive = static_cast<int>(m_density4[x][y] * rate);
m_density4[x][y] -= amountToGive;
if(m_density4[x][y] < 1)
m_density4[x][y] = 0;

return amountToGive;
}
}
return amountToGive;
}
}

LEVIATHAN_ASSERT(false, "Shouldn't get here");
Expand All @@ -222,26 +219,25 @@ int
size_t y,
float rate)
{
if(compound != NULL_COMPOUND) {
switch(getSlotForCompound(compound)) {
case SLOT::FIRST: {
int amountToGive = static_cast<int>(m_density1[x][y] * rate);
return amountToGive;
}
case SLOT::SECOND: {
int amountToGive = static_cast<int>(m_density2[x][y] * rate);
return amountToGive;
}
case SLOT::THIRD: {
int amountToGive = static_cast<int>(m_density3[x][y] * rate);
return amountToGive;
}
case SLOT::FOURTH: {
int amountToGive = static_cast<int>(m_density4[x][y] * rate);
return amountToGive;
}
}
switch(getSlotForCompound(compound)) {
case SLOT::FIRST: {
int amountToGive = static_cast<int>(m_density1[x][y] * rate);
return amountToGive;
}
case SLOT::SECOND: {
int amountToGive = static_cast<int>(m_density2[x][y] * rate);
return amountToGive;
}
case SLOT::THIRD: {
int amountToGive = static_cast<int>(m_density3[x][y] * rate);
return amountToGive;
}
case SLOT::FOURTH: {
int amountToGive = static_cast<int>(m_density4[x][y] * rate);
return amountToGive;
}
}

LEVIATHAN_ASSERT(false, "Shouldn't get here");
return -1;
}
Expand Down Expand Up @@ -435,7 +431,6 @@ void
doSpawnCycle(world, Float3(0, 0, 0));
}

//! \brief Places specified amount of compound at position
bool
CompoundCloudSystem::addCloud(CompoundId compound,
float density,
Expand Down Expand Up @@ -472,7 +467,6 @@ bool
return false;
}

//! \param rate should be less than one.
float
CompoundCloudSystem::takeCompound(CompoundId compound,
const Float3& worldPosition,
Expand Down Expand Up @@ -507,7 +501,6 @@ float
return 0;
}

//! \param rate should be less than one.
float
CompoundCloudSystem::amountAvailable(CompoundId compound,
const Float3& worldPosition,
Expand Down Expand Up @@ -1022,6 +1015,8 @@ void
// The perlin noise texture needs to be tileable. We can't do tricks with
// the cloud's position

// Even though we ask for the RGBA format the actual order of pixels when
// locked for writing is something completely different
cloud.m_texture = Ogre::TextureManager::getSingleton().createManual(
cloud.m_textureName, "Generated", Ogre::TEX_TYPE_2D,
CLOUD_SIMULATION_WIDTH, CLOUD_SIMULATION_HEIGHT, 0, Ogre::PF_BYTE_RGBA,
Expand Down Expand Up @@ -1150,16 +1145,36 @@ void
// This is probably branch predictor friendly to move each bunch of pixels
// separately

// First channel
if(cloud.m_compoundId1 != NULL_COMPOUND)
fillCloudChannel(cloud.m_density1, 0, rowBytes, pDest);
// Second
// Due to Ogre making the pixelbox lock however it wants the order is
// actually: Ogre::PF_A8R8G8B8
if(pixelBox.format != Ogre::PF_A8R8G8B8) {
LOG_INFO(
"Pixel format: " + Ogre::PixelUtil::getFormatName(pixelBox.format));
LEVIATHAN_ASSERT(false,
"Ogre created texture write lock with unexpected pixel order");
}

// Even with that pixel format the actual channel indexes are:
// so PF_B8G8R8A8 for some reason
// R - 2
// G - 1
// B - 0
// A - 3

if(cloud.m_compoundId1 == NULL_COMPOUND)
LEVIATHAN_ASSERT(false, "cloud with not even the first compound");

// First density. R goes to channel 2 (see above for the mapping)
fillCloudChannel(cloud.m_density1, 2, rowBytes, pDest);

// Second. G - 1
if(cloud.m_compoundId2 != NULL_COMPOUND)
fillCloudChannel(cloud.m_density2, 1, rowBytes, pDest);
// Etc.
// Etc. B - 0
if(cloud.m_compoundId3 != NULL_COMPOUND)
fillCloudChannel(cloud.m_density3, 2, rowBytes, pDest);
fillCloudChannel(cloud.m_density3, 0, rowBytes, pDest);

// A - 3
if(cloud.m_compoundId4 != NULL_COMPOUND)
fillCloudChannel(cloud.m_density4, 3, rowBytes, pDest);

Expand Down
8 changes: 4 additions & 4 deletions src/microbe_stage/compound_cloud_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ class CompoundCloudComponent : public Leviathan::Component {
//! The color of the compound cloud.
//! Every used channel must have alpha of 1. The others have alpha 0 so that
//! they don't need to be worried about affecting the resulting colours
Ogre::Vector4 m_color1;
Ogre::Vector4 m_color2;
Ogre::Vector4 m_color3;
Ogre::Vector4 m_color4;
Ogre::Vector4 m_color1 = Ogre::Vector4(0, 0, 0, 0);
Ogre::Vector4 m_color2 = Ogre::Vector4(0, 0, 0, 0);
Ogre::Vector4 m_color3 = Ogre::Vector4(0, 0, 0, 0);
Ogre::Vector4 m_color4 = Ogre::Vector4(0, 0, 0, 0);

//! \brief The compound id.
//! \note NULL_COMPOUND means that this cloud doesn't have that slot filled
Expand Down
82 changes: 79 additions & 3 deletions test/test_clouds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,6 @@ TEST_CASE_METHOD(CloudManagerTestsFixture,
multiCloudPositionCheckHelper(
clouds, playerPos->Members._Position, cloudFirstTypes);

// SECTION("Moving CLOUD_WIDTH/2 units") {}

SECTION("Moving 1000 units")
{
constexpr auto PLAYER_MOVE_AMOUNT = 1000;
Expand All @@ -544,6 +542,84 @@ TEST_CASE_METHOD(CloudManagerTestsFixture,
multiCloudPositionCheckHelper(
clouds, playerPos->Members._Position, cloudFirstTypes);
}
}

TEST_CASE_METHOD(CloudManagerTestsFixture,
"Cloud manager puts spawned cloud in right entity with 5 compound types",
"[microbe]")
{
// This test assumes
static_assert(CLOUDS_IN_ONE == 4, "this test assumes this");

const std::vector<Compound> types{
Compound{1, "a", true, true, false, Ogre::ColourValue(0, 1, 2, 1)},
Compound{2, "b", true, true, false, Ogre::ColourValue(3, 4, 5, 1)},
Compound{3, "c", true, true, false, Ogre::ColourValue(6, 7, 8, 1)},
Compound{4, "d", true, true, false, Ogre::ColourValue(9, 10, 11, 1)},
Compound{5, "e", true, true, false, Ogre::ColourValue(12, 13, 14, 1)}};

std::array<CompoundId, 2> cloudFirstTypes;
cloudFirstTypes[0] = types[0].id;
cloudFirstTypes[1] = types[4].id;

setCloudsAndRunInitial(types);

// Find the cloud entities
const auto clouds = findClouds();

CHECK(clouds.size() == 18);

CompoundCloudComponent* cloudGroup1AtOrigin = nullptr;
CompoundCloudComponent* cloudGroup2AtOrigin = nullptr;

for(auto* cloud : clouds) {

if(cloud->getPosition() != Float3(0, 0, 0))
continue;

if(cloudFirstTypes[0] == cloud->getCompoundId1()) {

CHECK(!cloudGroup1AtOrigin);
cloudGroup1AtOrigin = cloud;

} else if(cloudFirstTypes[1] == cloud->getCompoundId1()) {

CHECK(!cloudGroup2AtOrigin);
cloudGroup2AtOrigin = cloud;
}
}

REQUIRE(cloudGroup1AtOrigin);
REQUIRE(cloudGroup2AtOrigin);

const auto centerCoords = CompoundCloudSystem::convertWorldToCloudLocal(
Float3(0, 0, 0), Float3(0, 0, 0));

// Spawn clouds one by one and make sure they went to the right place
world.GetCompoundCloudSystem().addCloud(3, 10, Float3(0, 0, 0));

CHECK(cloudGroup1AtOrigin->amountAvailable(3, std::get<0>(centerCoords),
std::get<1>(centerCoords), 1) == 10);


world.GetCompoundCloudSystem().addCloud(4, 12, Float3(0, 0, 0));

CHECK(cloudGroup1AtOrigin->amountAvailable(4, std::get<0>(centerCoords),
std::get<1>(centerCoords), 1) == 12);

world.GetCompoundCloudSystem().addCloud(1, 13, Float3(0, 0, 0));

CHECK(cloudGroup1AtOrigin->amountAvailable(1, std::get<0>(centerCoords),
std::get<1>(centerCoords), 1) == 13);

world.GetCompoundCloudSystem().addCloud(2, 14, Float3(0, 0, 0));

CHECK(cloudGroup1AtOrigin->amountAvailable(2, std::get<0>(centerCoords),
std::get<1>(centerCoords), 1) == 14);

// Second group
world.GetCompoundCloudSystem().addCloud(5, 15, Float3(0, 0, 0));

// SECTION("Moving CLOUD_WIDTH * 1.5 units") {}
CHECK(cloudGroup2AtOrigin->amountAvailable(5, std::get<0>(centerCoords),
std::get<1>(centerCoords), 1) == 15);
}

0 comments on commit 437b92f

Please sign in to comment.