1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-03 10:04: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:
fgenesis 2023-10-24 23:05:33 +02:00
parent 83e3739340
commit 9fd024dadd
3 changed files with 71 additions and 50 deletions

View file

@ -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;
}
}

View file

@ -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

View file

@ -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),