Trivial Solutions The LoseThos 64-bit PC Operating System File:/LT/Demo/Graphics/Camp.CPZ This, and all LoseThos files, are public domain. Do whatever you like. God is watching; God is just; God is never out-done in generosity. He talks! LoseThos code compiles with the 64-bit LoseThos compiler/assembler I wrote. Boot the LoseThos CD and you can compile it. Not in Kansas anymore! Click here for preliminary compiler information you need. //This uses fixed-point. #define CO_PERSON 1 #define CO_TENT 2 class CObj { I64 x,y,z; I64 dx,dy,dz; I64 type; }; #define MAX_PEOPLE 1024 #define TENT_RATIO 40 #define MAX_TENTS (MAX_PEOPLE/TENT_RATIO+1) <1>/* Graphics Not Rendered in HTML */ <2>/* Graphics Not Rendered in HTML */ <3>/* Graphics Not Rendered in HTML */ U8 *people_img[4]={<2>,<1>,<3>,<1>}; <4>/* Graphics Not Rendered in HTML */ U8 *tent_img=<4>; <5>/* Graphics Not Rendered in HTML */ I64 num_objs; CObj objs[MAX_PEOPLE+MAX_TENTS]; CObj camp_view_point; #define CAMP_WIDTH 600 #define CAMP_SCALE 300 #define CAMP_Z_CLIP 10 U0 CTransform(GrBitMap *base,I64 *x,I64 *y,I64 *z) { *x-=camp_view_point.x; *y-=camp_view_point.y; *z-=camp_view_point.z; GrRot(base->r,x,y,z); *x = *x *-CAMP_SCALE/ *z; *y = *y *-CAMP_SCALE/ *z; *x=base->x+*x; *y=base->y-*y; *z=base->z-*z; } I64 mp_done_flags; I64 cx,cy,*r1; //could put these in a record and pass in F64 frame; I32 *depth_buf; U0 MPDrawMeeting(TaskStruct *task) { GrBitMap *base=GrAlias(gr_refreshed_base,task); F64 s; U8 *img,*img1,*img2; I64 i,x,y,z,*r2,*old_r=base->r, lo= Gs->num *num_objs/mp_cnt, hi=(Gs->num+1)*num_objs/mp_cnt; base->flags|=BMF_TRANSFORMATION; base->depth_buf=depth_buf; base->x=cx; base->y=cy; base->z=0; base->transform=&GrTransform; for (i=lo;i<hi;i++) { GrSetRotMat(base,r1); base->x=cx; base->y=cy; base->z=0; x=objs[i].x.i32[1]; y=objs[i].y.i32[1]; z=objs[i].z.i32[1]; CTransform(base,&x,&y,&z); if (z>CAMP_Z_CLIP) { s=0.5*ToF64(CAMP_SCALE)/z; if (objs[i].type==CO_PERSON) { img1=people_img[(i+ToI64(frame))&3]; img2=people_img[(i+ToI64(frame)+1)&3]; img=GrElemsInterpolate(img1,img2,frame%1.0); } else img=tent_img; r2=GrScaleMat(old_r,s); GrSetRotMat(base,r2); GrElemsPlot3b(base,x,y,z,img); Free(r2); if (objs[i].type==CO_PERSON) Free(img); } } base->r=old_r; base->depth_buf=NULL; GrDel(base); LBts(&mp_done_flags,Gs->num); } U0 DrawMeeting(TaskStruct *task) { GrBitMap *base=GrAlias(gr_refreshed_base,task); static BoolI8 calf=FALSE,determined=FALSE; //"tP" is a function holding time since boot, less pauses. I64 i,x,y,z,*r2,*old_r; F64 s; frame=4.0*Saw(tP(task),0.5); cx=task->win_pixel_width/2; cy=task->win_pixel_height/2; camp_view_point.x=0; camp_view_point.y=200-100*Sin(tP(task)); camp_view_point.z=20+100*Cos(tP(task)); GrAllocDepthBuf(base); depth_buf=base->depth_buf; base->flags|=BMF_TRANSFORMATION; r1=GrRotX(30.0*pi/180.0,task); old_r=base->r; base->pen_width=2; base->transform=&CTransform; base->x=cx; base->y=cy; base->z=0; GrSetRotMat(base,r1); x=0;y=0;z=-16*CAMP_WIDTH; base->transform(base,&x,&y,&z); base->color=LTCYAN; GrRect(base,0,0,task->win_pixel_width,y); base->color=BLACK; GrLine3(base,-32*CAMP_WIDTH,0,-16*CAMP_WIDTH,32*CAMP_WIDTH,0,-16*CAMP_WIDTH); GrLine3(base,-CAMP_WIDTH/2,0,0 ,CAMP_WIDTH/2,0,0); GrLine3(base,-CAMP_WIDTH/2,0,-CAMP_WIDTH,CAMP_WIDTH/2,0,-CAMP_WIDTH); GrLine3(base,-CAMP_WIDTH/2,0,0,-CAMP_WIDTH/2,0,-CAMP_WIDTH); GrLine3(base, CAMP_WIDTH/2,0,0, CAMP_WIDTH/2,0,-CAMP_WIDTH); base->transform=&GrTransform; if (tP(task)%10<5) { calf=FALSE; determined=FALSE; } else { if (!determined) { determined=TRUE; if (RandU16<MAX_U16/2) calf=TRUE; } } if (calf) { x=0; y=0; z=-CAMP_WIDTH/2; CTransform(base,&x,&y,&z); s=0.5*ToF64(CAMP_SCALE)/z; r2=GrScaleMat(old_r,s,task); GrSetRotMat(base,r2); GrElemsPlot3b(base,x,y,z,<5>); Free(r2); } mp_done_flags=0; for (i=1;i<mp_cnt;i++) MPJob(&MPDrawMeeting,task,1<<MPCf_FREE_ON_COMPLETE,1<<i); MPDrawMeeting(task); GrSetRotMat(base,old_r); if (calf && Blink(4.0,tP(task))) { base->color=YELLOW; GrPutS(base,cx-(15*FONT_WIDTH)/2,cy-3*FONT_HEIGHT,"!!Golden Calf!!"); } while (mp_done_flags!=1<<mp_cnt-1) Yield; GrDel(base); Free(r1); } #define MAX_SPEED 2<<32 U0 AnimateTask(U64 dummy=0) { nounusedwarn dummy; I64 i,x,z,dx,dz; F64 d; while (TRUE) { WinSync; for (i=0;i<num_objs;i++) if (objs[i].type==CO_PERSON) { if (tP(Fs->parent_task)%10<5) { objs[i].dx+=RandI32; objs[i].dz+=RandI32; } else { //Form circle x=CAMP_WIDTH/4*Cos((1.0+1.0/TENT_RATIO)*i*pi*2/num_objs); z=CAMP_WIDTH/4*Sin((1.0+1.0/TENT_RATIO)*i*pi*2/num_objs)-CAMP_WIDTH/2; dx=x-objs[i].x.i32[1]; dz=z-objs[i].z.i32[1]; d=Sqrt(SqrI64(dx)+SqrI64(dz)); objs[i].dx=MAX_SPEED*(dx/d); objs[i].dz=MAX_SPEED*(dz/d); } objs[i].dx=LimitI64(objs[i].dx,-MAX_SPEED,MAX_SPEED); objs[i].dy=LimitI64(objs[i].dy,-MAX_SPEED,MAX_SPEED); objs[i].dz=LimitI64(objs[i].dz,-MAX_SPEED,MAX_SPEED); objs[i].x+=objs[i].dx; objs[i].y+=objs[i].dy; objs[i].z+=objs[i].dz; if (objs[i].x.i32[1]<-CAMP_WIDTH>>1) { objs[i].x=-CAMP_WIDTH>>1<<32; objs[i].dx=-objs[i].dx; } if (objs[i].x.i32[1]>CAMP_WIDTH>>1) { objs[i].x=CAMP_WIDTH>>1<<32; objs[i].dx=-objs[i].dx; } if (objs[i].z.i32[1]<-CAMP_WIDTH) { objs[i].z=-CAMP_WIDTH<<32; objs[i].dz=-objs[i].dz; } if (objs[i].z.i32[1]>0) { objs[i].z=0; objs[i].dz=-objs[i].dz; } } Sleep(20); } } U0 Camp(I64 num_people=100) { I64 i,j=0,num_tents; if (num_people>MAX_PEOPLE) num_people=MAX_PEOPLE; MemSet(objs,0,sizeof(objs)); for (i=0;i<num_people;i++) { objs[j].x=(RandU32%CAMP_WIDTH-CAMP_WIDTH>>1)<<32; objs[j].y=0; objs[j].z=-(RandU32%CAMP_WIDTH)<<32; objs[j].type=CO_PERSON; j++; } num_tents=(num_people+TENT_RATIO-1)/TENT_RATIO; for (i=0;i<num_tents;i++) { objs[j].x=(RandU32%CAMP_WIDTH-CAMP_WIDTH>>1)<<32; objs[j].y=0; objs[j].z=-(RandU32%CAMP_WIDTH)<<32; objs[j].type=CO_TENT; j++; } num_objs=j; LtfBottom; LtfClear; SettingsPush(Fs,TSF_SAME_SONG); //See SettingsPush try { WordStat(OFF); Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",Fs); Fs->update_win=&DrawMeeting; WinSync; //The old update clobbers text_attr Fs->text_attr=LTGREEN<<4+WHITE; //bk/fg GetChar; } catch CatchAll; SettingsPop(Fs,TSF_SAME_SONG); } //This is so I can use this file stand alone //or as a component of a program. #if IncludeDepth<2 Camp; #endif