mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-03 18:14:01 +00:00
Support h-flipping hair, minor hair cleanup, add Lua functions:
+ entity_exertHairSegmentForce + entity_setHairTextureFlip + entity_setHairWidth Sadly obj_fh() doesn't work on hairs for some reason and it just turns invisible
This commit is contained in:
parent
83e3739340
commit
9fd024dadd
3 changed files with 71 additions and 50 deletions
|
@ -29,6 +29,7 @@ Hair::Hair(int nodes, float segmentLength, float hairWidth) : RenderObject()
|
||||||
{
|
{
|
||||||
this->segmentLength = segmentLength;
|
this->segmentLength = segmentLength;
|
||||||
this->hairWidth = hairWidth;
|
this->hairWidth = hairWidth;
|
||||||
|
this->_hairfh = false;
|
||||||
|
|
||||||
cull = false;
|
cull = false;
|
||||||
|
|
||||||
|
@ -41,22 +42,12 @@ Hair::Hair(int nodes, float segmentLength, float hairWidth) : RenderObject()
|
||||||
if (perc < 0)
|
if (perc < 0)
|
||||||
perc = 0;
|
perc = 0;
|
||||||
hairNodes[i].percent = 1.0f-perc;
|
hairNodes[i].percent = 1.0f-perc;
|
||||||
hairNodes[i].position = hairNodes[i].originalPosition = hairNodes[i].defaultPosition = Vector(0, i*segmentLength, 0);
|
Vector p(0, i*segmentLength, 0);
|
||||||
|
hairNodes[i].position = p;
|
||||||
|
hairNodes[i].defaultPosition = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hair::exertWave(float dt)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hair::exertGravityWave(float dt)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hair::setHeadPosition(const Vector &vec)
|
void Hair::setHeadPosition(const Vector &vec)
|
||||||
{
|
{
|
||||||
hairNodes[0].position = vec;
|
hairNodes[0].position = vec;
|
||||||
|
@ -75,46 +66,29 @@ HairNode *Hair::getHairNode(int idx)
|
||||||
|
|
||||||
void Hair::onRender(const RenderState& rs) const
|
void Hair::onRender(const RenderState& rs) const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
glBegin(GL_QUAD_STRIP);
|
||||||
float texBits = 1.0f / (hairNodes.size()-1);
|
const float texBits = 1.0f / (hairNodes.size()-1);
|
||||||
|
const Vector mul = !_hairfh ? Vector(1, 1) : Vector(-1, -1);
|
||||||
|
|
||||||
Vector pl, pr;
|
Vector pl, pr;
|
||||||
for (size_t i = 0; i < hairNodes.size(); i++)
|
for (size_t i = 0; i < hairNodes.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (i != hairNodes.size()-1)
|
if (i != hairNodes.size()-1)
|
||||||
{
|
{
|
||||||
Vector diffVec = hairNodes[i+1].position - hairNodes[i].position;
|
Vector diffVec = hairNodes[i+1].position - hairNodes[i].position;
|
||||||
diffVec.setLength2D(hairWidth);
|
diffVec.setLength2D(hairWidth);
|
||||||
pl = diffVec.getPerpendicularLeft();
|
pl = diffVec.getPerpendicularLeft() * mul;
|
||||||
pr = diffVec.getPerpendicularRight();
|
pr = diffVec.getPerpendicularRight() * mul;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector p = hairNodes[i].position;
|
||||||
|
|
||||||
glTexCoord2f(0, texBits*i);
|
glTexCoord2f(0, texBits*i);
|
||||||
glVertex3f(hairNodes[i].position.x + pl.x, hairNodes[i].position.y + pl.y, 0);
|
glVertex3f(p.x + pl.x, p.y + pl.y, 0);
|
||||||
glTexCoord2f(1, texBits*i);
|
glTexCoord2f(1, texBits*i);
|
||||||
glVertex3f( hairNodes[i].position.x + pr.x, hairNodes[i].position.y + pr.y, 0);
|
glVertex3f(p.x + pr.x, p.y + pr.y, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hair::onUpdate(float dt)
|
|
||||||
{
|
|
||||||
RenderObject::onUpdate(dt);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hair::updatePositions()
|
void Hair::updatePositions()
|
||||||
|
@ -137,11 +111,7 @@ void Hair::updatePositions()
|
||||||
hairNodes[i].position = hairNodes[i-1].position + diff;
|
hairNodes[i].position = hairNodes[i-1].position + diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hair::returnToDefaultPositions(float dt)
|
void Hair::returnToDefaultPositions(float dt)
|
||||||
|
@ -162,23 +132,44 @@ void Hair::returnToDefaultPositions(float dt)
|
||||||
|
|
||||||
void Hair::exertForce(const Vector &force, float dt, int usePerc)
|
void Hair::exertForce(const Vector &force, float dt, int usePerc)
|
||||||
{
|
{
|
||||||
|
const Vector f = force * dt;
|
||||||
for (int i = hairNodes.size()-1; i >= 1; i--)
|
for (int i = hairNodes.size()-1; i >= 1; i--)
|
||||||
{
|
{
|
||||||
switch (usePerc)
|
switch (usePerc)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
hairNodes[i].position += force*dt*hairNodes[i].percent;
|
hairNodes[i].position += f * hairNodes[i].percent;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
hairNodes[i].position += force*dt*(1.0f-hairNodes[i].percent);
|
hairNodes[i].position += f * (1.0f-hairNodes[i].percent);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
hairNodes[i].position += force*dt;
|
hairNodes[i].position += f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hair::exertNodeForce(size_t i, const Vector& force, float dt, int usePerc)
|
||||||
|
{
|
||||||
|
const Vector f = force * dt;
|
||||||
|
if(i >= hairNodes.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (usePerc)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
hairNodes[i].position += f * hairNodes[i].percent;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
hairNodes[i].position += f * (1.0f-hairNodes[i].percent);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
default:
|
||||||
|
hairNodes[i].position += f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
struct HairNode
|
struct HairNode
|
||||||
{
|
{
|
||||||
HairNode() : percent(0), problem(false), angleDiff(0)
|
HairNode() : percent(0)
|
||||||
{}
|
{}
|
||||||
float percent; // percent of how much force is affected on this node
|
float percent; // percent of how much force is affected on this node
|
||||||
Vector position; // position of the hair node
|
Vector position; // position of the hair node
|
||||||
Vector defaultPosition; // default position of the hair node
|
Vector defaultPosition; // default position of the hair node
|
||||||
Vector originalPosition;
|
|
||||||
bool problem;
|
|
||||||
float angleDiff;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Hair : public RenderObject
|
class Hair : public RenderObject
|
||||||
|
@ -41,8 +38,10 @@ public:
|
||||||
Hair(int nodes=40, float segmentLength=3, float width=18);
|
Hair(int nodes=40, float segmentLength=3, float width=18);
|
||||||
|
|
||||||
void exertForce(const Vector &force, float dt, int usePerc=0);
|
void exertForce(const Vector &force, float dt, int usePerc=0);
|
||||||
|
void exertNodeForce(size_t idx, const Vector &force, float dt, int usePerc=0);
|
||||||
void updatePositions();
|
void updatePositions();
|
||||||
void returnToDefaultPositions(float dt);
|
void returnToDefaultPositions(float dt);
|
||||||
|
void setTextureFlip(bool flip) { _hairfh = flip; }
|
||||||
|
|
||||||
float hairWidth;
|
float hairWidth;
|
||||||
|
|
||||||
|
@ -55,8 +54,8 @@ public:
|
||||||
HairNode *getHairNode(int idx);
|
HairNode *getHairNode(int idx);
|
||||||
protected:
|
protected:
|
||||||
float segmentLength;
|
float segmentLength;
|
||||||
void onUpdate(float dt) OVERRIDE;
|
|
||||||
void onRender(const RenderState& rs) const OVERRIDE;
|
void onRender(const RenderState& rs) const OVERRIDE;
|
||||||
|
bool _hairfh;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8351,6 +8351,34 @@ luaFunc(entity_exertHairForce)
|
||||||
luaReturnNil();
|
luaReturnNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// entity idx x y dt
|
||||||
|
luaFunc(entity_exertHairSegmentForce)
|
||||||
|
{
|
||||||
|
ScriptedEntity *se = scriptedEntity(L);
|
||||||
|
if (se)
|
||||||
|
{
|
||||||
|
if (se->hair)
|
||||||
|
se->hair->exertNodeForce(lua_tointeger(L, 2), Vector(lua_tonumber(L, 3), lua_tonumber(L, 4)), lua_tonumber(L, 5), lua_tonumber(L, 6));
|
||||||
|
}
|
||||||
|
luaReturnNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
luaFunc(entity_setHairTextureFlip)
|
||||||
|
{
|
||||||
|
ScriptedEntity *se = scriptedEntity(L);
|
||||||
|
if (se && se->hair)
|
||||||
|
se->hair->setTextureFlip(getBool(L, 2));
|
||||||
|
luaReturnNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
luaFunc(entity_setHairWidth)
|
||||||
|
{
|
||||||
|
ScriptedEntity *se = scriptedEntity(L);
|
||||||
|
if (se && se->hair)
|
||||||
|
se->hair->hairWidth = lua_tonumber(L, 2);
|
||||||
|
luaReturnNil();
|
||||||
|
}
|
||||||
|
|
||||||
luaFunc(entity_initPart)
|
luaFunc(entity_initPart)
|
||||||
{
|
{
|
||||||
std::string partName(getString(L, 2));
|
std::string partName(getString(L, 2));
|
||||||
|
@ -10721,6 +10749,9 @@ static const struct {
|
||||||
luaRegister(entity_setHairHeadPosition),
|
luaRegister(entity_setHairHeadPosition),
|
||||||
luaRegister(entity_updateHair),
|
luaRegister(entity_updateHair),
|
||||||
luaRegister(entity_exertHairForce),
|
luaRegister(entity_exertHairForce),
|
||||||
|
luaRegister(entity_exertHairSegmentForce),
|
||||||
|
luaRegister(entity_setHairTextureFlip),
|
||||||
|
luaRegister(entity_setHairWidth),
|
||||||
|
|
||||||
luaRegister(entity_setName),
|
luaRegister(entity_setName),
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue