Correctly name functions, remove old code and fix bezier solver

This commit is contained in:
BeaR 2014-05-25 10:41:24 +02:00
parent f3ca79315e
commit 2b36ae2baa
4 changed files with 34 additions and 39 deletions

View file

@ -326,24 +326,7 @@ void CRenderTools::DrawUIRect4(const CUIRect *r, vec4 ColorTopLeft, vec4 ColorTo
DrawRoundRectExt4(r->x,r->y,r->w,r->h,ColorTopLeft,ColorTopRight,ColorBottomLeft,ColorBottomRight,Rounding*UI()->Scale(), Corners); DrawRoundRectExt4(r->x,r->y,r->w,r->h,ColorTopLeft,ColorTopRight,ColorBottomLeft,ColorBottomRight,Rounding*UI()->Scale(), Corners);
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
} }
/*
void CRenderTools::DrawCurve(const CAnimFCurve *pCurve, vec4 Color, float x, float y, float w, float h)
{
Graphics()->TextureClear();
Graphics()->QuadsBegin();
{
for(int i = 0; i < w; i++)
{
float a = float(i)/w;
float val = pCurve->Eval(a*100);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x+i-1.0f, y+val-1.0f, 2.0f, 2.0f);
Graphics()->QuadsDrawTL(&ItemQ, 1);
}
}
Graphics()->QuadsEnd();
}
*/
void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos) void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos)
{ {
vec2 Direction = Dir; vec2 Direction = Dir;

View file

@ -6,14 +6,14 @@
#include "render.h" #include "render.h"
void validateFCurve(vec2& p0, vec2& p1, vec2& p2, vec2& p3) void ValidateFCurve(const vec2& p0, vec2& p1, vec2& p2, const vec2& p3)
{ {
// validate the bezier curve // validate the bezier curve
p1.x = clamp(p1.x, p0.x, p3.x); p1.x = clamp(p1.x, p0.x, p3.x);
p2.x = clamp(p2.x, p0.x, p3.x); p2.x = clamp(p2.x, p0.x, p3.x);
} }
double cubicrt(double x) double CubicRoot(double x)
{ {
if(x == 0.0) if(x == 0.0)
return 0.0; return 0.0;
@ -23,7 +23,7 @@ double cubicrt(double x)
return exp(log(x)/3.0); return exp(log(x)/3.0);
} }
float solveBezier(float x, float p0, float p1, float p2, float p3) float SolveBezier(float x, float p0, float p1, float p2, float p3)
{ {
// check for valid f-curve // check for valid f-curve
// we only take care of monotonic bezier curves, so there has to be exactly 1 real solution // we only take care of monotonic bezier curves, so there has to be exactly 1 real solution
@ -42,21 +42,30 @@ float solveBezier(float x, float p0, float p1, float p2, float p3)
// a*t + b = 0 // a*t + b = 0
a = x1; a = x1;
b = x0; b = x0;
return -a/b;
if(a == 0.0)
return 0.0f;
else
return -b/a;
} }
else if(x3 == 0.0) else if(x3 == 0.0)
{ {
// quadratic // quadratic
// a*t*t + b*t +c = 0 // t*t + b*t +c = 0
a = x2; b = x1/x2;
b = x1; c = x0/x2;
c = x0;
if(c == 0.0) if(c == 0.0)
return 0.0f; return 0.0f;
double D = b*b - 4*a*c; double D = b*b - 4*c;
return (-b + sqrt(D))/(2*a);
t = (-b + sqrt(D))/2;
if(0.0 <= t && t <= 1.0001f)
return t;
else
return (-b - sqrt(D))/2;
} }
else else
{ {
@ -71,24 +80,24 @@ float solveBezier(float x, float p0, float p1, float p2, float p3)
// depressed form x^3 + px + q = 0 // depressed form x^3 + px + q = 0
// cardano's method // cardano's method
double p = b/3 - sub*sub; // = (b - a*a/3) / 3 double p = b/3 - a*a/9;
double q = (2*sub*sub*sub - sub*b + c) / 2; // = (2*a*a*/27 - a*b/3 + c) / 2 double q = (2*a*a*a/27 - a*b/3 + c)/2;
double D = q * q + p * p * p; double D = q*q + p*p*p;
if(D > 0.0) if(D > 0.0)
{ {
// only one 'real' solution // only one 'real' solution
double s = sqrt(D); double s = sqrt(D);
return cubicrt(s-q) - cubicrt(s+q) - sub; return CubicRoot(s-q) - CubicRoot(s+q) - sub;
} }
else if(D == 0.0) else if(D == 0.0)
{ {
// one single, one double solution or triple solution // one single, one double solution or triple solution
double s = cubicrt(-q); double s = CubicRoot(-q);
t = 2*s - sub; t = 2*s - sub;
if(0.0 <= t && t <= 1.000001f) if(0.0 <= t && t <= 1.0001f)
return t; return t;
else else
return (-s - sub); return (-s - sub);
@ -102,12 +111,12 @@ float solveBezier(float x, float p0, float p1, float p2, float p3)
t = s*cos(phi) - sub; t = s*cos(phi) - sub;
if(0.0 <= t && t <= 1.000001f) if(0.0 <= t && t <= 1.0001f)
return t; return t;
t = -s*cos(phi+pi/3) - sub; t = -s*cos(phi+pi/3) - sub;
if(0.0 <= t && t <= 1.000001f) if(0.0 <= t && t <= 1.0001f)
return t; return t;
else else
return -s*cos(phi-pi/3) - sub; return -s*cos(phi-pi/3) - sub;
@ -177,15 +186,17 @@ void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Cha
p2 = p3 - inTang; p2 = p3 - inTang;
// validate bezier curve // validate bezier curve
validateFCurve(p0, p1, p2, p3); ValidateFCurve(p0, p1, p2, p3);
// solve x(a) = time for a // solve x(a) = time for a
a = clamp(solveBezier(Time/1000.0f, p0.x, p1.x, p2.x, p3.x), 0.0f, 1.0f); a = clamp(SolveBezier(Time/1000.0f, p0.x, p1.x, p2.x, p3.x), 0.0f, 1.0f);
// value = y(t) // value = y(t)
pResult[c] = bezier(p0.y, p1.y, p2.y, p3.y, a); pResult[c] = bezier(p0.y, p1.y, p2.y, p3.y, a);
} }
return; return;
case CURVETYPE_LINEAR:
break;
} }
for(int c = 0; c < Channels; c++) for(int c = 0; c < Channels; c++)

View file

@ -1512,7 +1512,9 @@ void CEditor::DoQuadEnvelopes(const array<CQuad> &lQuads, IGraphics::CTextureHan
const int Steps = 15; const int Steps = 15;
for(int n = 1; n <= Steps; n++) for(int n = 1; n <= Steps; n++)
{ {
float a = (float)n/Steps; float a = n/(float)Steps;
// little offset to prevent looping due to fmod
float time = mix(apEnvelope[j]->m_lPoints[i].m_Time, apEnvelope[j]->m_lPoints[i+1].m_Time, a); float time = mix(apEnvelope[j]->m_lPoints[i].m_Time, apEnvelope[j]->m_lPoints[i+1].m_Time, a);
apEnvelope[j]->Eval(time/1000.0f - 0.000001f, aResults); apEnvelope[j]->Eval(time/1000.0f - 0.000001f, aResults);

View file

@ -11,7 +11,6 @@
#include <base/tl/algorithm.h> #include <base/tl/algorithm.h>
#include <base/tl/array.h> #include <base/tl/array.h>
#include <base/tl/sorted_array.h>
#include <base/tl/string.h> #include <base/tl/string.h>
#include <game/client/ui.h> #include <game/client/ui.h>