|
|
|
@@ -5,115 +5,132 @@ |
|
|
|
|
|
|
|
#include "sww/app.h" |
|
|
|
#include "sww/color.h" |
|
|
|
#include "sww/cstl_vector.h" |
|
|
|
#include "sww/fps_helper.h" |
|
|
|
#include "sww/rate_helper.h" |
|
|
|
#include "sww/renderer.h" |
|
|
|
#include "sww/util.h" |
|
|
|
#include "sww/vmath.h" |
|
|
|
#include "sww/window.h" |
|
|
|
#include "sww/cstl_vector.h" |
|
|
|
|
|
|
|
#define MAX_SCENE 1 |
|
|
|
|
|
|
|
typedef void (*SceneFunc)(swwWindow *); |
|
|
|
typedef void (*SceneFunc)(swwWindow*); |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
int w; |
|
|
|
int h; |
|
|
|
int scene; |
|
|
|
swwRenderer *renderer; |
|
|
|
SceneFunc fs[MAX_SCENE]; |
|
|
|
typedef struct |
|
|
|
{ |
|
|
|
int w; |
|
|
|
int h; |
|
|
|
int scene; |
|
|
|
swwRenderer* renderer; |
|
|
|
SceneFunc fs[MAX_SCENE]; |
|
|
|
} UserData; |
|
|
|
|
|
|
|
void OnKey(swwWindow *o, swwKeycode key, int pressed) { |
|
|
|
UserData *ud = swwWindow_GetUserData(o); |
|
|
|
if (pressed) { |
|
|
|
switch (key) { |
|
|
|
case swwKeycode_ESCAPE: { |
|
|
|
swwApp_PostQuitEvent(); |
|
|
|
} break; |
|
|
|
case swwKeycode_W: { |
|
|
|
ud->scene = (ud->scene + 1) % MAX_SCENE; |
|
|
|
} break; |
|
|
|
case swwKeycode_S: { |
|
|
|
ud->scene--; |
|
|
|
if (ud->scene < 0) { |
|
|
|
ud->scene = MAX_SCENE - 1; |
|
|
|
} |
|
|
|
} break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
void OnKey(swwWindow* o, swwKeycode key, int pressed) |
|
|
|
{ |
|
|
|
UserData* ud = swwWindow_GetUserData(o); |
|
|
|
if (pressed) { |
|
|
|
switch (key) { |
|
|
|
case swwKeycode_ESCAPE: { |
|
|
|
swwApp_PostQuitEvent(); |
|
|
|
} break; |
|
|
|
case swwKeycode_W: { |
|
|
|
ud->scene = (ud->scene + 1) % MAX_SCENE; |
|
|
|
} break; |
|
|
|
case swwKeycode_S: { |
|
|
|
ud->scene--; |
|
|
|
if (ud->scene < 0) { |
|
|
|
ud->scene = MAX_SCENE - 1; |
|
|
|
} |
|
|
|
} break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void OnButton(swwWindow *o, swwButton btn, int pressed) { |
|
|
|
if (btn == swwButton_L && pressed) { |
|
|
|
} else if (btn == swwButton_R && pressed) { |
|
|
|
// Save to bmp file |
|
|
|
UserData *ud = swwWindow_GetUserData(o); |
|
|
|
uint32_t buf_size = swwUtil_BmpBufferSize(ud->w, ud->h, 1); |
|
|
|
uint8_t *buf = (uint8_t *)malloc(buf_size); |
|
|
|
uint8_t *wbuf = swwRenderer_LockBuffer(ud->renderer); |
|
|
|
FILE *fp = NULL; |
|
|
|
swwUtil_SaveBufferToBmpBuffer(buf, buf_size, wbuf, ud->w, ud->h, 1); |
|
|
|
fp = fopen("output.bmp", "wb+"); |
|
|
|
fwrite(buf, 1, buf_size, fp); |
|
|
|
fclose(fp); |
|
|
|
free(buf); |
|
|
|
} |
|
|
|
void OnButton(swwWindow* o, swwButton btn, int pressed) |
|
|
|
{ |
|
|
|
if (btn == swwButton_L && pressed) { |
|
|
|
} else if (btn == swwButton_R && pressed) { |
|
|
|
// Save to bmp file |
|
|
|
UserData* ud = swwWindow_GetUserData(o); |
|
|
|
uint32_t buf_size = swwUtil_BmpBufferSize(ud->w, ud->h, 1); |
|
|
|
uint8_t* buf = (uint8_t*)malloc(buf_size); |
|
|
|
uint8_t* wbuf = swwRenderer_LockBuffer(ud->renderer); |
|
|
|
FILE* fp = NULL; |
|
|
|
swwUtil_SaveBufferToBmpBuffer(buf, buf_size, wbuf, ud->w, ud->h, 1); |
|
|
|
fp = fopen("output.bmp", "wb+"); |
|
|
|
fwrite(buf, 1, buf_size, fp); |
|
|
|
fclose(fp); |
|
|
|
free(buf); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void OnScroll(swwWindow *o, float offset) {} |
|
|
|
void OnScroll(swwWindow* o, float offset) |
|
|
|
{} |
|
|
|
|
|
|
|
CSTLVector(Point2fVector, Point2f); |
|
|
|
CSTLVector(FloatVector, float); |
|
|
|
|
|
|
|
typedef struct |
|
|
|
{ |
|
|
|
Point2fVector joints; |
|
|
|
int link_size; // Space between joints |
|
|
|
Point2fVector joints; |
|
|
|
int link_size; // Space between joints |
|
|
|
|
|
|
|
// Only used in non-FABRIK resolution |
|
|
|
FloatVector angles; |
|
|
|
float angle_constraint; // Max angle diff between two adjacent joints, higher = loose, lower = rigid |
|
|
|
// Only used in non-FABRIK resolution |
|
|
|
FloatVector angles; |
|
|
|
float angle_constraint; // Max angle diff between two adjacent joints, higher = loose, lower = |
|
|
|
// rigid |
|
|
|
} Chain; |
|
|
|
|
|
|
|
#define Chain_Construct(origin, joint_count, link_size) Chain_ConstructWithAngleConstraint(origin, joint_count, link_size, 2 * M_PI) |
|
|
|
|
|
|
|
void Chain_ConstructWithAngleConstraint(Chain *o, Point2f origin, int joint_count, int link_size, float angleConstraint) { |
|
|
|
o->link_size = link_size; |
|
|
|
o->angle_constraint = angle_constraint; |
|
|
|
Point2fVector_Construct(&o->joints, 16); // Assumed to be >= 2, otherwise it wouldn't be much of a chain |
|
|
|
FloatVector_Construct(&o->angles, 16); |
|
|
|
#define Chain_Construct(origin, joint_count, link_size) \ |
|
|
|
Chain_ConstructWithAngleConstraint(origin, joint_count, link_size, 2 * M_PI) |
|
|
|
|
|
|
|
Point2fVector_PushBack(&o->joints, origin); |
|
|
|
FloatVector_PushBack(&o->angles, 0.f); |
|
|
|
void Chain_ConstructWithAngleConstraint(Chain* o, Point2f origin, int joint_count, int link_size, |
|
|
|
float angleConstraint) |
|
|
|
{ |
|
|
|
o->link_size = link_size; |
|
|
|
o->angle_constraint = angle_constraint; |
|
|
|
Point2fVector_Construct(&o->joints, |
|
|
|
16); // Assumed to be >= 2, otherwise it wouldn't be much of a chain |
|
|
|
FloatVector_Construct(&o->angles, 16); |
|
|
|
|
|
|
|
int i = 1; |
|
|
|
for (; i < joint_count; i++) { |
|
|
|
Point2fVector_PushBack(&o->joints, Vector2f_Add(Point2fVector_At(&o->joints, i - 1), (Vector2f){0, o->link_size})); |
|
|
|
Point2fVector_PushBack(&o->joints, origin); |
|
|
|
FloatVector_PushBack(&o->angles, 0.f); |
|
|
|
} |
|
|
|
|
|
|
|
int i = 1; |
|
|
|
for (; i < joint_count; i++) { |
|
|
|
Point2fVector_PushBack(&o->joints, Vector2f_Add(Point2fVector_At(&o->joints, i - 1), |
|
|
|
(Vector2f){0, o->link_size})); |
|
|
|
FloatVector_PushBack(&o->angles, 0.f); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Chain_Destruct(Chain *o) |
|
|
|
void Chain_Destruct(Chain* o) |
|
|
|
{ |
|
|
|
Point2fVector_Destruct(&o->joints); |
|
|
|
FloatVector_Destruct(&o->angles); |
|
|
|
Point2fVector_Destruct(&o->joints); |
|
|
|
FloatVector_Destruct(&o->angles); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
void Chain_Resolve(Chain *o, Point2f pos) { |
|
|
|
angles.set(0, Vector2f_Sub(pos, joints.get(0)).heading()); |
|
|
|
joints.set(0, pos); |
|
|
|
for (int i = 1; i < joints.size(); i++) { |
|
|
|
float curAngle = PVector.sub(joints.get(i - 1), joints.get(i)).heading(); |
|
|
|
angles.set(i, constrainAngle(curAngle, angles.get(i - 1), angleConstraint)); |
|
|
|
joints.set(i, PVector.sub(joints.get(i - 1), PVector.fromAngle(angles.get(i)).setMag(linkSize))); |
|
|
|
} |
|
|
|
void Chain_Resolve(Chain* o, Point2f pos) |
|
|
|
{ |
|
|
|
Vector_Set(&o->angles, 0, Vector2f_Heading(Vector2f_Sub(pos, Vector_At(&o->joints, 0)))); |
|
|
|
Vector_Set(&o->joints, 0, pos); |
|
|
|
|
|
|
|
int i = 1; |
|
|
|
for (; i < Vector_Size(&o->joints); i++) { |
|
|
|
float cur_angle = |
|
|
|
Vechtor2f_Heading(Vector2f_Sub(Vector_At(&o->joints, i - 1), Vector_At(&o->joints, i))); |
|
|
|
Vector_Set(&o->angles, i, |
|
|
|
constrainAngle(cur_angle, Vector_At(&o->angles, i - 1), o->angle_constraint)); |
|
|
|
Vector_Set(&o->joints, i, |
|
|
|
Vector2f_Sub(Vector_At(&o->joints, i - 1), |
|
|
|
Vector2f_FromAngle(Vector_At(&o->angles., i)).setMag(linkSize))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
void Chain_FabrikResolve(Chain *o, PVector pos, PVector anchor) { |
|
|
|
// Forward pass |
|
|
|
joints.set(0, pos); |
|
|
|
@@ -145,55 +162,52 @@ void display() { |
|
|
|
*/ |
|
|
|
|
|
|
|
/* Chain */ |
|
|
|
void Scene1(swwWindow *o) { |
|
|
|
UserData *ud = swwWindow_GetUserData(o); |
|
|
|
void Scene1(swwWindow* o) |
|
|
|
{ |
|
|
|
UserData* ud = swwWindow_GetUserData(o); |
|
|
|
|
|
|
|
int h = ud->h; |
|
|
|
int w = ud->w; |
|
|
|
int h = ud->h; |
|
|
|
int w = ud->w; |
|
|
|
} |
|
|
|
|
|
|
|
int main() { |
|
|
|
const uint32_t w = 512; |
|
|
|
const uint32_t h = 512; |
|
|
|
swwWindowCallback callback = {OnKey, OnButton, OnScroll}; |
|
|
|
swwFpsHelper fps; |
|
|
|
swwRateHelper rh; |
|
|
|
|
|
|
|
swwApp_Initialize(); |
|
|
|
|
|
|
|
UserData ud = {w, |
|
|
|
h, |
|
|
|
0, |
|
|
|
NULL, |
|
|
|
{Scene1}}; |
|
|
|
|
|
|
|
swwWindow *window = swwWindow_Create("SWW Proc Animation", w, h); |
|
|
|
ud.renderer = swwRenderer_CreateAttachWindow(window, kSoftwareRenderer); |
|
|
|
swwWindow_SetUserData(window, &ud); |
|
|
|
|
|
|
|
swwWindow_SetCallback(window, &callback); |
|
|
|
swwRenderer_EnablePerfMonitor(ud.renderer, 1); |
|
|
|
swwFpsHelper_Construct(&fps, 1.f); |
|
|
|
|
|
|
|
swwRateHelper_Construct(&rh, 30.f); |
|
|
|
while (!swwApp_ShouldExit()) { |
|
|
|
swwRenderer_ClearWhite(ud.renderer); |
|
|
|
ud.fs[ud.scene](window); |
|
|
|
swwRenderer_Present(ud.renderer); |
|
|
|
|
|
|
|
swwApp_PollEvent(); |
|
|
|
swwRateHelper_Sleep(&rh); |
|
|
|
|
|
|
|
if (swwFpsHelper_Update(&fps, ud.renderer)) { |
|
|
|
printf("FPS: %s \r", swwFpsHelper_Get(&fps)); |
|
|
|
fflush(stdout); |
|
|
|
int main() |
|
|
|
{ |
|
|
|
const uint32_t w = 512; |
|
|
|
const uint32_t h = 512; |
|
|
|
swwWindowCallback callback = {OnKey, OnButton, OnScroll}; |
|
|
|
swwFpsHelper fps; |
|
|
|
swwRateHelper rh; |
|
|
|
|
|
|
|
swwApp_Initialize(); |
|
|
|
|
|
|
|
UserData ud = {w, h, 0, NULL, {Scene1}}; |
|
|
|
|
|
|
|
swwWindow* window = swwWindow_Create("SWW Proc Animation", w, h); |
|
|
|
ud.renderer = swwRenderer_CreateAttachWindow(window, kSoftwareRenderer); |
|
|
|
swwWindow_SetUserData(window, &ud); |
|
|
|
|
|
|
|
swwWindow_SetCallback(window, &callback); |
|
|
|
swwRenderer_EnablePerfMonitor(ud.renderer, 1); |
|
|
|
swwFpsHelper_Construct(&fps, 1.f); |
|
|
|
|
|
|
|
swwRateHelper_Construct(&rh, 30.f); |
|
|
|
while (!swwApp_ShouldExit()) { |
|
|
|
swwRenderer_ClearWhite(ud.renderer); |
|
|
|
ud.fs[ud.scene](window); |
|
|
|
swwRenderer_Present(ud.renderer); |
|
|
|
|
|
|
|
swwApp_PollEvent(); |
|
|
|
swwRateHelper_Sleep(&rh); |
|
|
|
|
|
|
|
if (swwFpsHelper_Update(&fps, ud.renderer)) { |
|
|
|
printf("FPS: %s \r", swwFpsHelper_Get(&fps)); |
|
|
|
fflush(stdout); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
swwRenderer_Destroy(ud.renderer); |
|
|
|
swwWindow_Destroy(window); |
|
|
|
swwApp_Cleanup(); |
|
|
|
swwRenderer_Destroy(ud.renderer); |
|
|
|
swwWindow_Destroy(window); |
|
|
|
swwApp_Cleanup(); |
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|