Skip to content

Commit

Permalink
Swim: start of point fish
Browse files Browse the repository at this point in the history
  • Loading branch information
neilmendoza committed Dec 12, 2013
1 parent 08d7a17 commit 8c76e8a
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void CloudsVisualSystemSwim::selfPostDraw()

//use render gui for display settings, like changing colors
void CloudsVisualSystemSwim::selfSetupRenderGui()
{
{
rdrGui->addToggle("regenerate", false);

rdrGui->addLabel("Flocking");
Expand All @@ -74,20 +74,29 @@ void CloudsVisualSystemSwim::selfSetupRenderGui()
rdrGui->addMinimalSlider("attractStrength", 0.f, 1.f, &creatures.attractStrength);
rdrGui->addMinimalSlider("maxDistFromCentre", 500.f, 4000.f, &creatures.maxDistFromCentre);

rdrGui->addLabel("Points");
rdrGui->addSpacer();
rdrGui->addIntSlider("numPointOne", 0, 1000, &creatures.numPointOne);
rdrGui->addSlider("huePointOne", 0.f, 1.f, &creatures.huePointOne);
rdrGui->addIntSlider("numPointTwo", 0, 1000, &creatures.numPointTwo);
rdrGui->addSlider("huePointTwo", 0.f, 1.f, &creatures.huePointTwo);
rdrGui->addIntSlider("numPointThree", 0, 1000, &creatures.numPointThree);
rdrGui->addSlider("huePointThree", 0.f, 1.f, &creatures.huePointThree);

rdrGui->addLabel("Jellies (see other menus)");
rdrGui->addSpacer();
rdrGui->addMinimalSlider("numJellyOne", 20, 300, &creatures.numJellyOne);
rdrGui->addMinimalSlider("numJellyTwo", 20, 300, &creatures.numJellyTwo);
rdrGui->addIntSlider("numJellyOne", 0, 300, &creatures.numJellyOne);
rdrGui->addIntSlider("numJellyTwo", 0, 300, &creatures.numJellyTwo);

rdrGui->addLabel("Fish One");
rdrGui->addSpacer();
rdrGui->addMinimalSlider("numGreyFish", 20, 300, &creatures.numGreyFish);
rdrGui->addIntSlider("numGreyFish", 0, 300, &creatures.numGreyFish);
rdrGui->addMinimalSlider("greySizeAverage", .1f, 3.f, &creatures.fishOneParams.sizeAverage);
rdrGui->addMinimalSlider("greySizeStdDeviation", 0.f, 1.f, &creatures.fishOneParams.sizeStdDeviation);

rdrGui->addLabel("Fish Two");
rdrGui->addSpacer();
rdrGui->addMinimalSlider("numYellowFish", 20, 300, &creatures.numYellowFish);
rdrGui->addIntSlider("numYellowFish", 0, 300, &creatures.numYellowFish);
rdrGui->addMinimalSlider("yellowSizeAverage", .1f, 3.f, &creatures.fishTwoParams.sizeAverage);
rdrGui->addMinimalSlider("yellowSizeStdDeviation", 0.f, 1.f, &creatures.fishTwoParams.sizeStdDeviation);

Expand Down
5 changes: 4 additions & 1 deletion CloudsLibrary/src/VisualSystems/Swim/vs_src/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ namespace itg
GEOMETRIC,
WOBBLY,
MODEL,
JELLY
JELLY,
POINT
};

typedef shared_ptr<Creature> Ptr;
Expand Down Expand Up @@ -92,6 +93,8 @@ namespace itg
bool getMagic() { return magic; }

static float randomGauss(float mean, float stdDev);

virtual ofFloatColor getColour() const = 0;

protected:
// forces
Expand Down
202 changes: 117 additions & 85 deletions CloudsLibrary/src/VisualSystems/Swim/vs_src/Creatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,59 +94,69 @@ namespace itg
JellyCreature::shader.load(dataPath + "shaders/jelly");

//generate();
pointCreatureMesh.setUsage(GL_DYNAMIC_DRAW);
pointCreatureMesh.setMode(OF_PRIMITIVE_POINTS);
}

void Creatures::generate()
{
creatures.clear();
creaturesByType.clear();

const float startArea = 1200.f;

// fish one
creaturesByType.push_back(vector<Creature::Ptr>());
for (int i = 0; i < round(numGreyFish); ++i)
addModelFish(numGreyFish, fishOneParams);
addModelFish(numYellowFish, fishTwoParams);

addPointFish(numPointOne, huePointOne);
addPointFish(numPointTwo, huePointTwo);
addPointFish(numPointThree, huePointThree);

// NB add jellies last as they are drawn with glDepthMask(GL_FALSE) to make additive blending
// work so depth isn't stored
addJellyFish(numJellyOne, jellyOneParams);
addJellyFish(numJellyTwo, jellyTwoParams);

for (unsigned i = 0; i < creatures.size(); ++i)
{
ModelCreature::Ptr modelCreature = ModelCreature::Ptr(new ModelCreature(fishOneParams));
creatures.push_back(modelCreature);
creatures.back()->setVelocity(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(-100, 100));
creaturesByType.back().push_back(creatures.back());
creatures[i]->setPosition(ofRandom(-startArea, startArea), ofRandom(-startArea, startArea), ofRandom(-startArea, 0));
creatures[i]->setOrientation(ofVec3f(ofRandom(-180.f, 180.f), ofRandom(-180.f, 180.f), ofRandom(-180.f, 180.f)));
}

// fish two
}

void Creatures::addPointFish(unsigned number, float hue)
{
creaturesByType.push_back(vector<Creature::Ptr>());
for (int i = 0; i < round(numYellowFish); ++i)
for (int i = 0; i < number; ++i)
{
ModelCreature::Ptr modelCreature = ModelCreature::Ptr(new ModelCreature(fishTwoParams));
creatures.push_back(modelCreature);
PointCreature::Ptr pointCreature = PointCreature::Ptr(new PointCreature(hue));
creatures.push_back(pointCreature);
creatures.back()->setVelocity(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(-100, 100));
creaturesByType.back().push_back(creatures.back());
}
// NB add jellies last as they are drawn with glDepthMask(GL_FALSE) to make additive blending
// work so depth isn't stored
// jelly one
}

void Creatures::addModelFish(unsigned number, const ModelParams& params)
{
creaturesByType.push_back(vector<Creature::Ptr>());
for (int i = 0; i < round(numJellyOne); ++i)
for (int i = 0; i < number; ++i)
{
creatures.push_back(JellyCreature::Ptr(new JellyCreature(jellyOneParams)));
creatures.back()->setVelocity(ofRandom(-50, 50), ofRandom(-50, 50), ofRandom(-50, 50));
ModelCreature::Ptr modelCreature = ModelCreature::Ptr(new ModelCreature(params));
creatures.push_back(modelCreature);
creatures.back()->setVelocity(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(-100, 100));
creaturesByType.back().push_back(creatures.back());
}

// jelly two
}

void Creatures::addJellyFish(unsigned number, const JellyParams& params)
{
creaturesByType.push_back(vector<Creature::Ptr>());
for (int i = 0; i < round(numJellyTwo); ++i)
for (int i = 0; i < number; ++i)
{
creatures.push_back(JellyCreature::Ptr(new JellyCreature(jellyTwoParams)));
creatures.push_back(JellyCreature::Ptr(new JellyCreature(params)));
creatures.back()->setVelocity(ofRandom(-50, 50), ofRandom(-50, 50), ofRandom(-50, 50));
creaturesByType.back().push_back(creatures.back());
}

for (unsigned i = 0; i < creatures.size(); ++i)
{
creatures[i]->setPosition(ofRandom(-startArea, startArea), ofRandom(-startArea, startArea), ofRandom(-startArea, 0));
creatures[i]->setOrientation(ofVec3f(ofRandom(-180.f, 180.f), ofRandom(-180.f, 180.f), ofRandom(-180.f, 180.f)));
}
}

void Creatures::update()
Expand All @@ -155,76 +165,78 @@ namespace itg

for (unsigned k = 0; k < creaturesByType.size(); ++k)
{
vector<ofVec3f> posns;
for (int i = 0; i < creaturesByType[k].size(); ++i)
{
creaturesByType[k][i]->zeroAccumulated();
creaturesByType[k][i]->setMagic(false);
// make nn search so that it has an interface that can be implemented
posns.push_back(creaturesByType[k][i]->getPosition());
}
nn.buildIndex(posns);

// zero accumulated forces and then add forces
// from fish fish interaction
for (int i = 0; i < creaturesByType[k].size(); ++i)
if (!creaturesByType[k].empty())
{
const int numClosest = 8;
vector<float> dists2;
vector<NNIndex> indices;
nn.findNClosestPoints(creaturesByType[k][i]->getPosition(), numClosest, indices, dists2);
vector<ofVec3f> posns;
for (int i = 0; i < creaturesByType[k].size(); ++i)
{
creaturesByType[k][i]->zeroAccumulated();
creaturesByType[k][i]->setMagic(false);
// make nn search so that it has an interface that can be implemented
posns.push_back(creaturesByType[k][i]->getPosition());
}
nn.buildIndex(posns);

for (int j = 0; j < indices.size(); ++j)
// zero accumulated forces and then add forces
// from fish fish interaction
for (int i = 0; i < creaturesByType[k].size(); ++i)
{
if (indices[j] != i)
const int numClosest = 8;
vector<float> dists2;
vector<NNIndex> indices;
nn.findNClosestPoints(creaturesByType[k][i]->getPosition(), numClosest, indices, dists2);

for (int j = 0; j < indices.size(); ++j)
{
Creature::Ptr creature = creaturesByType[k][indices[j]];
//if (creature->getType() == creaturesByType[k][i]->getType())
if (indices[j] != i)
{
// towards creature i
ofVec3f dir = creaturesByType[k][i]->getPosition() - creature->getPosition();

if( dists2[j] < zoneRadiusSq )
Creature::Ptr creature = creaturesByType[k][indices[j]];
//if (creature->getType() == creaturesByType[k][i]->getType())
{
// Neighbor is in the zone
float percent = dists2[j]/zoneRadiusSq;
// towards creature i
ofVec3f dir = creaturesByType[k][i]->getPosition() - creature->getPosition();

if( percent < alignmentLower )
if( dists2[j] < zoneRadiusSq )
{
// Separation
float F = ( alignmentLower/percent - 1.0f ) * repelStrength;//repelStrength;
dir = dir.normalized() * F;
creaturesByType[k][i]->accumulate(dir);
}
else if( percent < alignmentUpper )
{
// Alignment
float threshDelta = alignmentUpper - alignmentLower;
float adjustedPercent = ( percent - alignmentLower )/threshDelta;
float F = ( 1.0 - ( cos( adjustedPercent * TWO_PI ) * -0.5f + 0.5f ) ) * alignStrength;// * alignStrength;
ofVec3f force = creature->getNormalisedVelocity() * F;
creaturesByType[k][i]->accumulate(force);
// Neighbor is in the zone
float percent = dists2[j]/zoneRadiusSq;

}
else
{
// Cohesion
float threshDelta = 1.0f - alignmentUpper;
float adjustedPercent = ( percent - alignmentUpper )/threshDelta;
float F = ( 1.0 - ( cos( adjustedPercent * TWO_PI ) * -0.5f + 0.5f ) ) * attractStrength;// * attractStrength;

dir.normalize();
dir *= F;
ofVec3f force = -dir;
creaturesByType[k][i]->accumulate(force);
if( percent < alignmentLower )
{
// Separation
float F = ( alignmentLower/percent - 1.0f ) * repelStrength;//repelStrength;
dir = dir.normalized() * F;
creaturesByType[k][i]->accumulate(dir);
}
else if( percent < alignmentUpper )
{
// Alignment
float threshDelta = alignmentUpper - alignmentLower;
float adjustedPercent = ( percent - alignmentLower )/threshDelta;
float F = ( 1.0 - ( cos( adjustedPercent * TWO_PI ) * -0.5f + 0.5f ) ) * alignStrength;// * alignStrength;
ofVec3f force = creature->getNormalisedVelocity() * F;
creaturesByType[k][i]->accumulate(force);

}
else
{
// Cohesion
float threshDelta = 1.0f - alignmentUpper;
float adjustedPercent = ( percent - alignmentUpper )/threshDelta;
float F = ( 1.0 - ( cos( adjustedPercent * TWO_PI ) * -0.5f + 0.5f ) ) * attractStrength;// * attractStrength;

dir.normalize();
dir *= F;
ofVec3f force = -dir;
creaturesByType[k][i]->accumulate(force);
}
}
}
}
}
}
}
}


for (int i = 0; i < creatures.size(); ++i)
{
Expand Down Expand Up @@ -259,18 +271,38 @@ namespace itg
creatures[i]->slerp(creatures[i]->getPosition() - creatures[i]->getNormalisedVelocity(), ofVec3f(0, 1, 0));

creatures[i]->update();

}

pointCreatureMesh.clear();
for (unsigned i = 0; i < creaturesByType.size(); ++i)
{
for (unsigned j = 0; j < creaturesByType[i].size(); ++j)
{
if (creaturesByType[i][j]->getType() != Creature::POINT) break;
pointCreatureMesh.addVertex(creaturesByType[i][j]->getPosition());
pointCreatureMesh.addColor(creaturesByType[i][j]->getColour());
}
}
}

void Creatures::draw()
{
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_DEPTH_TEST);
for (unsigned i = 0; i < creaturesByType.size(); ++i)
{
for (unsigned j = 0; j < creaturesByType[i].size(); ++j)
{
if (creaturesByType[i][j]->getType() == Creature::POINT) break;
creaturesByType[i][j]->draw();
}
}
pointCreatureMesh.draw();
/*
for (int i = 0; i < creatures.size(); ++i)
{
creatures[i]->draw();
}
}*/
glPopAttrib();
}
}
19 changes: 15 additions & 4 deletions CloudsLibrary/src/VisualSystems/Swim/vs_src/Creatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ofxNearestNeighbour.h"
#include "ModelCreature.h"
#include "JellyCreature.h"
#include "PointCreature.h"

namespace itg
{
Expand All @@ -55,18 +56,28 @@ namespace itg
float repelStrength, attractStrength, alignStrength;
float maxDistFromCentre;

// float to make work with ofxUI
float numJellyOne, numJellyTwo;
// jelly gui
int numJellyOne, numJellyTwo;
JellyParams jellyOneParams, jellyTwoParams;

// fish gui
int numGreyFish, numYellowFish;
ModelParams fishOneParams, fishTwoParams;
float numGreyFish, numYellowFish;

// point gui
int numPointOne, numPointTwo, numPointThree;
float huePointOne, huePointTwo, huePointThree;

void generate();

private:
void addPointFish(unsigned number, float hue);
void addModelFish(unsigned number, const ModelParams& params);
void addJellyFish(unsigned number, const JellyParams& params);

vector<Creature::Ptr> creatures;
vector<vector<Creature::Ptr> > creaturesByType;

ofxNearestNeighbour3D nn;
ofVboMesh pointCreatureMesh;
};
}
2 changes: 2 additions & 0 deletions CloudsLibrary/src/VisualSystems/Swim/vs_src/JellyCreature.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace itg

void setShaderUniforms();

ofFloatColor getColour() const { return bodyColour; }

//void setFrequency(const float frequency) { this->frequency = frequency; }

private:
Expand Down
2 changes: 2 additions & 0 deletions CloudsLibrary/src/VisualSystems/Swim/vs_src/ModelCreature.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace itg

void customDraw();

ofFloatColor getColour() const { return colour; }

private:
static vector<ofxAssimpModelLoader> fishModels;
//static vector<ofImage> fishTextures;
Expand Down
Loading

0 comments on commit 8c76e8a

Please sign in to comment.