001 #ifndef SKELETAL 002 #define SKELETAL 003 #include "_2d.HC"; 004 class CBone:CQue { 005 U64 ident; 006 C2DObject *obj; 007 //Bone takes rotation from rot 008 #define BONE_M_NORMAL 0 009 //Bone points to point_x,point_y motherfucker(point_rot_off is added to rot) 010 #define BONE_M_POINT_TO 1 011 I64 mode; 012 #define BONE_F_FLIP 1 013 I64 flags; 014 F64 x,y,z,length; 015 F64 point_x,point_y,point_rot_off; 016 F64 rot; 017 CQue child_bones; 018 }; 019 CBone *BoneNew(C2DObject *obj,CTask *mem_task=NULL) { 020 CBone *b=CAlloc(sizeof CBone,mem_task); 021 b->ident='Bone'; 022 b->obj=obj; 023 QueInit(&b->child_bones); 024 return b; 025 } 026 U0 BoneSetFlip(CBone *bone,Bool on=TRUE) { 027 if(!on) {bone->obj->flipped=TRUE;bone->flags|=BONE_F_FLIP;} 028 else {bone->flags&=~BONE_F_FLIP;bone->obj->flipped=FALSE;} 029 CBone *head=&bone->child_bones,*cur; 030 for(cur=head->next;cur!=head;cur=cur->next) 031 BoneSetFlip(cur,on); 032 } 033 F64 FlipAngle(F64 a) { 034 return (pi-a)+pi; 035 } 036 U0 BoneUpdate(CBone *bone,CBone *parent=NULL) { 037 CBone *head,*cur; 038 F64 dist,ang,flip=1; 039 if(parent&&parent->flags&BONE_F_FLIP) 040 flip=-1; 041 if(!parent) { 042 bone->obj->x=bone->x; 043 bone->obj->y=bone->y; 044 bone->obj->rot=bone->rot; 045 bone->obj->flipped=!!(bone->flags&BONE_F_FLIP); 046 } else { 047 switch(bone->mode) { 048 start: 049 bone->obj->x=parent->obj->x; 050 bone->obj->y=parent->obj->y; 051 dist=Sqrt(Sqr(bone->x)+Sqr(bone->y)); 052 ang=Arg(flip*bone->x,bone->y); 053 bone->obj->x+=dist*Cos(parent->obj->rot+ang); 054 bone->obj->y+=dist*Sin(parent->obj->rot+ang); 055 case BONE_M_NORMAL: 056 if(!(bone->flags&BONE_F_FLIP)) 057 bone->obj->rot=bone->rot+parent->obj->rot; 058 else 059 bone->obj->rot=FlipAngle(bone->rot)+parent->obj->rot; 060 break; 061 case BONE_M_POINT_TO: 062 if(!(bone->flags&BONE_F_FLIP)) 063 bone->obj->rot=Arg(bone->point_x-bone->obj->x,bone->point_y-bone->obj->y)+bone->point_rot_off; 064 else 065 bone->obj->rot=FlipAngle(Arg(-(bone->point_x-bone->obj->x),bone->point_y-bone->obj->y)+bone->point_rot_off); 066 break; 067 end:; 068 } 069 } 070 head=&bone->child_bones; 071 for(cur=head->next;cur!=head;cur=cur->next) { 072 BoneUpdate(cur,bone); 073 } 074 } 075 #if __CMD_LINE__ 076 C2DWorld *w=C2DWorldNew(BLACK); 077 CDC *rect1=DCNew(200,50); 078 CDC *rect2=DCNew(100,50); 079 DCFill(rect1,YELLOW); 080 DCFill(rect2,CYAN); 081 CDC *sq=DCNew(50,50); 082 DCFill(sq,RED); 083 C2DObject *arm=C2DObjectNewFromDC(rect1); 084 C2DObject *arm2=C2DObjectNewFromDC(rect2); 085 C2DObject *hand=C2DObjectNewFromDC(sq); 086 C2DObjectMoveCenter(arm,0,25); 087 C2DObjectMoveCenter(arm2,0,25); 088 C2DObjectMoveCenter(hand,0,0); 089 CBone *arm_bone=BoneNew(arm); 090 CBone *arm_bone2=BoneNew(arm2); 091 arm_bone->x=0,arm_bone->y=0; 092 arm_bone2->x=200,arm_bone2->y=25; 093 CBone *hand_bone=BoneNew(hand); 094 hand_bone->x=100; 095 hand_bone->y=0; 096 QueIns(arm_bone2,&arm_bone->child_bones); 097 QueIns(hand_bone,&arm_bone2->child_bones); 098 AddObjectToWorld(arm,w); 099 AddObjectToWorld(arm2,w); 100 AddObjectToWorld(hand,w); 101 //Recursive 102 103 U0 DrawIt(CTask *t,CDC *dc) { 104 DrawWorld(Fs,w); 105 GrBlot(dc,0,0,w->scrn); 106 } 107 FlushMsgs; 108 WinMax; 109 U0 Foo() { 110 Fs->draw_it=&DrawIt; 111 while(!ScanKey) { 112 arm_bone->x=GR_WIDTH/2; 113 arm_bone->y=GR_HEIGHT/2; 114 arm_bone->rot=tS; 115 arm_bone2->rot=tS*3; 116 arm_bone2->mode=BONE_M_POINT_TO; 117 arm_bone->point_x=0; 118 arm_bone->point_y=0; 119 BoneUpdate(arm_bone); 120 BoneSetFlip(arm_bone,Blink(.5)); 121 Refresh; 122 } 123 Exit; 124 }; 125 Foo; 126 #endif 127 #endif