void consume_line() { int i,j; if(cline[1] == 0x47) { // Calculate the data points. All transfers complete. calc_point(); } if(cline[1] == 0x43) { // This is a start event. Clear the matrix. if(cline[2] & 0x80) { for(i=0; i < 30; i++) for(j=0; j < 40; j++) matrix[i][j] = 0; } // Write the line into the matrix. for(i=0; i < 40; i++) matrix[cline[2] & 0x1F][i] = cline[i+3]; } // printf("Received %d bytes\n", cidx-1); /* for(i=0; i < cidx; i++) printf("%2.2X ",cline[i]); printf("\n"); */ cidx = 0; }
IC void get_q_box( Fbox &xf, float c, float alpha, float radius ) { Fvector src_pt, tgt_pt; calc_point (tgt_pt,radius,0,alpha); src_pt.set (0,tgt_pt.y,0); xf.invalidate (); xf.modify (src_pt); xf.modify (tgt_pt); xf.grow (c); }
bool hgeGUIRange::MouseLButton(bool bDown) { bPressed=bDown; if(bPressed) { nfirst=calc_point(mx, my); nlast=nfirst; return true; } return false; }
bool hgeGUIRange::MouseMove(float x, float y) { mx=x; my=y; if(bPressed) { nlast=calc_point(mx, my); return true; } return false; }
ICF BOOL test_point(xrXRC& xrc, const Fmatrix& xform, const Fmatrix33& mat, const Fvector& ext, float radius, float angle) { Fvector pt; calc_point (pt,radius,VIEWPORT_NEAR/2,angle); xform.transform_tiny(pt); CDB::RESULT* it =xrc.r_begin(); CDB::RESULT* end=xrc.r_end (); for (; it!=end; it++) { CDB::RESULT& O = *it; if (GMLib.GetMaterialByIdx(O.material)->Flags.is(SGameMtl::flPassable)) continue; if (CDB::TestBBoxTri(mat,pt,ext,O.verts,FALSE)) return TRUE; } return FALSE; }
int calc_detail(t_detail *detail, t_color *color, t_camera *camera, double *vector) { if (detail == NULL || color == NULL || camera == NULL || vector == NULL) return (EXIT_FAILURE); calc_point(camera->position, vector, detail->position, detail->k); calc_color(color, detail); calc_normal(camera, detail, vector, detail->normal); calc_perturbation(detail->object, detail->position, detail->normal); if ((detail->object->image_bump != NULL && detail->object->image_bump->type == B_BUMP) || (detail->object->perlin != NULL && (detail->object->perlin->apply == APP_BUMP || detail->object->perlin->apply == APP_BUMP_TEXT))) texture_bump_mapping(detail, detail->normal); else if (detail->object->image_bump != NULL && detail->object->image_bump->type == B_NORMAL) texture_normal_mapping(detail, detail->normal); return (EXIT_SUCCESS); }
void CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if(mstate_real & mcClimb&&cam_active!=eacFreeLook) camUpdateLadder(dt); Fvector point={0,CameraHeight(),0}, dangle={0,0,0}; Fmatrix xform,xformR; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) { if (!fis_zero(r_torso_tgt_roll)){ Fvector src_pt,tgt_pt; float radius = point.y*0.5f; float alpha = r_torso_tgt_roll/2.f; float dZ = ((PI_DIV_2-((PI+alpha)/2))); calc_point (tgt_pt,radius,0,alpha); src_pt.set (0,tgt_pt.y,0); // init valid angle float valid_angle = alpha; // xform with roll xformR.setXYZ (-r_torso.pitch,r_torso.yaw,-dZ); Fmatrix33 mat; mat.i = xformR.i; mat.j = xformR.j; mat.k = xformR.k; // get viewport params float w,h; float c = viewport_near(w,h); w/=2.f;h/=2.f; // find tris Fbox box; box.invalidate (); box.modify (src_pt); box.modify (tgt_pt); box.grow (c); // query Fvector bc,bd ; Fbox xf ; xf.xform (box,xform) ; xf.get_CD (bc,bd) ; xrXRC xrc ; xrc.box_options (0) ; xrc.box_query (Level().ObjectSpace.GetStaticModel(), bc, bd) ; u32 tri_count = xrc.r_count(); if (tri_count) { float da = 0.f; BOOL bIntersect = FALSE; Fvector ext = {w,h,VIEWPORT_NEAR/2}; if (test_point(xrc,xform,mat,ext,radius,alpha)){ da = PI/1000.f; if (!fis_zero(r_torso.roll)) da *= r_torso.roll/_abs(r_torso.roll); float angle = 0.f; for (; _abs(angle)<_abs(alpha); angle+=da) if (test_point(xrc,xform,mat,ext,radius,angle)) { bIntersect=TRUE; break; } valid_angle = bIntersect?angle:alpha; } } r_torso.roll = valid_angle*2.f; r_torso_tgt_roll = r_torso.roll; } else { r_torso_tgt_roll = 0.f; r_torso.roll = 0.f; } } if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); if(eacFirstEye == cam_active) { // CCameraBase* C = cameras[eacFirstEye]; xrXRC xrc ; xrc.box_options (0) ; xrc.box_query (Level().ObjectSpace.GetStaticModel(), point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR) ); u32 tri_count = xrc.r_count(); if (tri_count) { _viewport_near = 0.01f; } else { xr_vector<ISpatial*> ISpatialResult; g_SpatialSpacePhysic->q_box(ISpatialResult, 0, STYPE_PHYSIC, point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR)); for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++) { CPHShell* pCPHS= smart_cast<CPHShell*>(ISpatialResult[o_it]); if (pCPHS) { _viewport_near = 0.01f; break; } } } } /* { CCameraBase* C = cameras[eacFirstEye]; float oobox_size = 2*VIEWPORT_NEAR; Fmatrix _rot; _rot.k = C->vDirection; _rot.c = C->vPosition; _rot.i.crossproduct (C->vNormal, _rot.k); _rot.j.crossproduct (_rot.k, _rot.i); Fvector vbox; vbox.set (oobox_size, oobox_size, oobox_size); Level().debug_renderer().draw_aabb (C->vPosition, 0.05f, 0.051f, 0.05f, D3DCOLOR_XRGB(0,255,0)); Level().debug_renderer().draw_obb (_rot, Fvector().div(vbox,2.0f), D3DCOLOR_XRGB(255,0,0)); dMatrix3 d_rot; PHDynamicData::FMXtoDMX (_rot, d_rot); CPHActivationShape activation_shape; activation_shape.Create (point, vbox, this); dBodySetRotation (activation_shape.ODEBody(), d_rot); CPHCollideValidator::SetDynamicNotCollide(activation_shape); activation_shape.Activate (vbox,1,1.f,0.0F); point.set (activation_shape.Position()); activation_shape.Destroy (); } */ C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if( psActorFlags.test(AF_PSP) ) { Cameras().Update (C); }else { Cameras().Update (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; if (Level().CurrentEntity() == this) { Level().Cameras().Update (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }
int main(int argc, char** argv) { const float A[] = { 1, 1, 0, 1 };//状态转移矩阵 IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 );//创建显示所用的图像 CvKalman* kalman = cvCreateKalman( 2, 1, 0 );//创建cvKalman数据结构,状态向量为2维,观测向量为1维,无激励输入维 CvMat* state = cvCreateMat( 2, 1, CV_32FC1 ); //(phi, delta_phi) 定义了状态变量 CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 );// 创建两行一列CV_32FC1的单通道浮点型矩阵 CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 ); //定义观测变量 CvRNG rng = cvRNG(-1);//初始化一个随机序列函数 char code = -1; cvZero( measurement );//观测变量矩阵置零 cvNamedWindow( "Kalman", 1 ); for(;;) { //用均匀分布或者正态分布的随机数填充输出数组state cvRandArr( &rng, state, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) );//状态state memcpy( kalman->transition_matrix->data.fl, A, sizeof(A));//初始化状态转移F矩阵 //cvSetIdentity()用法:把数组中除了行数与列数相等以外的所有元素的值都设置为0;行数与列数相等的元素的值都设置为1 //我们将(第一个前假象阶段的)后验状态初始化为一个随机值 cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );//观测矩阵H cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) );//过程噪声Q cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) );//观测噪声R cvSetIdentity( kalman->error_cov_post, cvRealScalar(1));//后验误差协方差 cvRandArr( &rng, kalman->state_post, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) );//校正状态 //在时机动态系统上开始预测 for(;;) { #define calc_point(angle) \ cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \ cvRound(img->height/2 - img->width/3*sin(angle))) float state_angle = state->data.fl[0]; CvPoint state_pt = calc_point(state_angle); const CvMat* prediction = cvKalmanPredict( kalman, 0 );//计算下一个时间点的预期值,激励项输入为0 float predict_angle = prediction->data.fl[0]; CvPoint predict_pt = calc_point(predict_angle); float measurement_angle; CvPoint measurement_pt; cvRandArr( &rng, measurement, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(sqrt(kalman->measurement_noise_cov->data.fl[0])) ); /* generate measurement */ cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement ); //cvMatMulAdd(src1,src2,src3,dst)就是实现dist=src1*src2+src3; measurement_angle = measurement->data.fl[0]; measurement_pt = calc_point(measurement_angle); //调用Kalman滤波器并赋予其最新的测量值,接下来就是产生过程噪声,然后对状态乘以传递矩阵F完成一次迭代并加上我们产生的过程噪声 /* plot points */ #define draw_cross( center, color, d ) \ cvLine( img, cvPoint( center.x - d, center.y - d ), \ cvPoint( center.x + d, center.y + d ), color, 1, CV_AA, 0); \ cvLine( img, cvPoint( center.x + d, center.y - d ), \ cvPoint( center.x - d, center.y + d ), color, 1, CV_AA, 0 ) cvZero( img ); //使用上面宏定义的函数 draw_cross( state_pt, CV_RGB(255,255,255), 3 );//白色,状态点 draw_cross( measurement_pt, CV_RGB(255,0,0), 3 );//红色,测量点 draw_cross( predict_pt, CV_RGB(0,255,0), 3 );//绿色,估计点 cvLine( img, state_pt, measurement_pt, CV_RGB(255,0,0), 3, CV_AA, 0 ); cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, CV_AA, 0 ); cvKalmanCorrect( kalman, measurement );//校正新的测量值 cvRandArr( &rng, process_noise, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(sqrt(kalman->process_noise_cov->data.fl[0])));//设置正态分布过程噪声 cvMatMulAdd( kalman->transition_matrix, state, process_noise, state ); cvShowImage( "Kalman", img ); //当按键按下时,开始新的循环,初始矩阵可能会改变,所以移动速率会改变 code = (char) cvWaitKey( 100 ); if( code > 0 ) break; } if( code == 27 || code == 'q' || code == 'Q' ) break; } cvDestroyWindow("Kalman"); return 0; }
void CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) ) camUpdateLadder(dt); on_weapon_shot_update(); float y_shift =0; if( GamePersistent().GameType() != eGameIDSingle && ik_cam_shift && character_physics_support() && character_physics_support()->ik_controller() ) { y_shift = character_physics_support()->ik_controller()->Shift(); float cam_smooth_k = 1.f; if(_abs(y_shift-current_ik_cam_shift)>ik_cam_shift_tolerance) { cam_smooth_k = 1.f - ik_cam_shift_speed * dt/0.01f; } if(_abs(y_shift)<ik_cam_shift_tolerance/2.f) cam_smooth_k = 1.f - ik_cam_shift_speed * 1.f/0.01f * dt; clamp( cam_smooth_k, 0.f, 1.f ); current_ik_cam_shift = cam_smooth_k * current_ik_cam_shift + y_shift * ( 1.f - cam_smooth_k ); } else current_ik_cam_shift = 0; Fvector point = {0,CameraHeight() + current_ik_cam_shift,0}; Fvector dangle = {0,0,0}; Fmatrix xform; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) cam_Lookout( xform, point.y ); if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if (Level().CurrentEntity() == this) { collide_camera( *cameras[eacFirstEye], _viewport_near, this ); } if( psActorFlags.test(AF_PSP) ) { Cameras().UpdateFromCamera (C); }else { Cameras().UpdateFromCamera (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; #ifdef DEBUG if( dbg_draw_camera_collision ) { dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near ); dbg_draw_viewport( Cameras(), _viewport_near ); } #endif if (Level().CurrentEntity() == this) { Level().Cameras().UpdateFromCamera (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }
ICF void calc_gl_point(Fvector& pt, const Fmatrix& xform, float radius, float angle ) { calc_point (pt,radius,VIEWPORT_NEAR/2,angle); xform.transform_tiny(pt); }
void CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) ) camUpdateLadder(dt); on_weapon_shot_update(); // Alex ADD: smooth crouch fix if (!CurrentHeight)CurrentHeight = CameraHeight(); float HeightInterpolationSpeed = 9.f; if (CurrentHeight != CameraHeight() && !Device.dwPrecacheFrame) { CurrentHeight = (CurrentHeight * (1.0f - HeightInterpolationSpeed*dt)) + (CameraHeight() * HeightInterpolationSpeed*dt); } Fvector point = { 0, CurrentHeight, 0 }; //Fvector point = {0,CameraHeight(),0}; Fvector dangle = {0,0,0}; Fmatrix xform; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) cam_Lookout( xform, point.y ); if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if (Level().CurrentEntity() == this) collide_camera( *cameras[eacFirstEye], _viewport_near ); if( psActorFlags.test(AF_PSP) ) { Cameras().UpdateFromCamera (C); }else { Cameras().UpdateFromCamera (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; #ifdef DEBUG if( dbg_draw_camera_collision ) { dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near ); dbg_draw_viewport( Cameras(), _viewport_near ); } #endif if (Level().CurrentEntity() == this) { Level().Cameras().UpdateFromCamera (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }
int main(int argc, char** argv) { /* A matrix data */ const float A[] = { 1, 1, 0, 1 }; IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); CvKalman* kalman = cvCreateKalman( 2, 1, 0 ); /* state is (phi, delta_phi) - angle and angle increment */ CvMat* state = cvCreateMat( 2, 1, CV_32FC1 ); CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 ); /* only phi (angle) is measured */ CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 ); CvRandState rng; int code = -1; cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI ); cvZero( measurement ); cvNamedWindow( "Kalman", 1 ); for(;;) { cvRandSetRange( &rng, 0, 0.1, 0 ); rng.disttype = CV_RAND_NORMAL; cvRand( &rng, state ); memcpy( kalman->transition_matrix->data.fl, A, sizeof(A)); cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) ); cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) ); cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) ); cvSetIdentity( kalman->error_cov_post, cvRealScalar(1)); /* choose random initial state */ cvRand( &rng, kalman->state_post ); rng.disttype = CV_RAND_NORMAL; for(;;) { #define calc_point(angle) \ cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \ cvRound(img->height/2 - img->width/3*sin(angle))) float state_angle = state->data.fl[0]; CvPoint state_pt = calc_point(state_angle); /* predict point position */ const CvMat* prediction = cvKalmanPredict( kalman, 0 ); float predict_angle = prediction->data.fl[0]; CvPoint predict_pt = calc_point(predict_angle); float measurement_angle; CvPoint measurement_pt; cvRandSetRange( &rng, 0, sqrt(kalman->measurement_noise_cov->data.fl[0]), 0 ); cvRand( &rng, measurement ); /* generate measurement */ cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement ); measurement_angle = measurement->data.fl[0]; measurement_pt = calc_point(measurement_angle); /* plot points */ #define draw_cross( center, color, d ) \ cvLine( img, cvPoint( center.x - d, center.y - d ), \ cvPoint( center.x + d, center.y + d ), \ color, 1, 0 ); \ cvLine( img, cvPoint( center.x + d, center.y - d ), \ cvPoint( center.x - d, center.y + d ), \ color, 1, 0 ) cvZero( img ); draw_cross( state_pt, CV_RGB(255,255,255), 3 ); draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ); draw_cross( predict_pt, CV_RGB(0,255,0), 3 ); cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 ); /* adjust Kalman filter state */ cvKalmanCorrect( kalman, measurement ); cvRandSetRange( &rng, 0, sqrt(kalman->process_noise_cov->data.fl[0]), 0 ); cvRand( &rng, process_noise ); cvMatMulAdd( kalman->transition_matrix, state, process_noise, state ); cvShowImage( "Kalman", img ); code = cvWaitKey( 100 ); if( code > 0 ) /* break current simulation by pressing a key */ break; } if( code == 27 ) /* exit by ESCAPE */ break; } return 0; }
void myKeyHandler(unsigned char ch, int x, int y) { int i; static int subdiv=0; struct point_t *slice; struct point_t *linecur; struct point_t *cur; struct point_t *new_points; struct slice_t *cur_slice,*cur2_slice; struct point_t *cur2; struct point_t points[5]; double a,b,c; GLfloat v1[3],v2[3],v3[3]; double deginc; // struct slice_t *cur_slice; switch(ch) { case 'q': endSubdiv(0); break; case 'z': mode=(~mode)&1; printf("%s\n",mode?"3D mode":"2D mode"); switch(mode) { case 0: resetCamera(); break; case 1: reset3DCamera(); break; } break; case 'k': /* test phong stuff */ cur_slice = slices; cur2_slice = slices->n; //while(cur_slice!=NULL) { cur = cur_slice->line; cur2 = cur2_slice->line; //while(cur->n!=NULL) { /* right vertex */ add_vec(&(cur->nx),&(cur->n->nx),&(points[0].nx)); normalize(&(points[0].nx)); sub_vec(&(cur->n->x),&(cur->x),v1); v1[0] /= 2; v1[1] /= 2; v1[2] /= 2; add_vec(&(cur->x),v1,&(points[0].x)); /* top vertex */ add_vec(&(cur->nx),&(cur2->nx),&(points[1].nx)); normalize(&(points[1].nx)); sub_vec(&(cur2->x),&(cur->x),v1); v1[0] /= 2; v1[1] /= 2; v1[2] /= 2; add_vec(&(cur->x),v1,&(points[1].x)); /* left vertex */ add_vec(&(cur2->nx),&(cur2->n->nx),&(points[2].nx)); normalize(&(points[2].nx)); sub_vec(&(cur2->n->x),&(cur2->x),v1); v1[0] /= 2; v1[1] /= 2; v1[2] /= 2; add_vec(&(cur2->x),v1,&(points[2].x)); /* bottom vertex */ add_vec(&(cur2->n->nx),&(cur->n->nx),&(points[3].nx)); normalize(&(points[3].nx)); sub_vec(&(cur->n->x),&(cur2->n->x),v1); v1[0] /= 2; v1[1] /= 2; v1[2] /= 2; add_vec(&(cur2->n->x),v1,&(points[3].x)); /* center vertex */ add_vec(&(points[0].nx),&(points[1].nx),v1); add_vec(&(points[2].nx),&(points[3].nx),v2); add_vec(v1,v2,&(points[4].nx)); normalize(&(points[4].nx)); sub_vec(&(points[3].x),&(cur2->n->x),v1); sub_vec(&(points[2].x),&(cur2->n->x),v2); add_vec(v1,v2,v3); normalize(v3); a=sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]); b=sqrt(v2[0]*v2[0]+v2[1]*v2[1]+v2[2]*v2[2]); c=sqrt(a*a+b*b); v3[0] *= c; v3[1] *= c; v3[2] *= c; add_vec(&(cur2->n->x),v3,&(points[4].x)); printf("v2[0]=%f,v2[1]=%f,v2[2]=%f\nv3[0]=%f,v3[1]=%f,v3[2]=%f\n",v2[0],v2[1],v2[2],v3[0],v3[1],v3[2]); for(i=0; i<5; i++) printf("points[%d]->x=%f,points[%d]->y=%f,points[%d]->z=%f\n", i,points[i].x,i,points[i].y,i,points[i].z); printf("cur->x=%f,cur->y=%f,cur->z=%f\ncur->n->x=%f,cur->n->y=%f,cur->n->z=%f\n", cur->x,cur->y,cur->z,cur->n->x,cur->n->y,cur->n->z); printf("cur2->x=%f,cur2->y=%f,cur2->z=%f\ncur2->n->x=%f,cur2->n->y=%f,cur2->n->z=%f\n", cur2->x,cur2->y,cur2->z,cur2->n->x,cur2->n->y,cur2->n->z); cur = cur->n; cur2 = cur2->n; } cur_slice = cur_slice->n; cur2_slice = cur2_slice->n != NULL ? cur2_slice->n : slices; /* circle around */ } break; case 'n': normals=(~normals)&1; printf("Normal mode %s\n",normals?"on":"off"); break; case 'e': solid=(~solid)&1; printf("%s\n",solid?"Solid mode":"Wireframe mode"); switch(solid) { case 0: glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break; case 1: glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break; } break; case 'r': faces=(~faces)&1; printf("%s\n",faces?"Faces mode":"Control points mode"); break; case 'w': /* calculate initial 3d object */ if(num<5) printf("There must be at least 5 control points.\n"); else if(!mode) { mode=(~mode)&1; printf("%s\n",mode?"3D mode":"2D mode"); switch(mode) { case 0: resetCamera(); break; case 1: reset3DCamera(); break; } freeModel(); subdiv_v = 0; subdiv_h = NUMSLICES; /* the radius of the circle for each of the points is x */ for(i=0;i<subdiv_h;i++) { ALLOC_POINT(slice); cur=slice; linecur=line; while(linecur!=NULL) { cur->z = linecur->x*sin(DEGINC*i); cur->x = linecur->x*cos(DEGINC*i); cur->y = linecur->y; linecur = linecur->n; if(linecur!=NULL) { ALLOC_POINT(cur->n); cur = cur->n; } } addSlice(slice); } } recompute_normals(); break; case 's': /* horizontal subdivision */ if(!mode || slices==NULL) break; /* backup the original slice */ new_points = duplicate_slice(slices->line); freeModel(); subdiv_h<<=1; subdiv++; printf("Horizontal subdivision level %d\n",subdiv); deginc = 2*M_PI/subdiv_h; for(i=0;i<subdiv_h;i++) { ALLOC_POINT(slice); cur=slice; linecur=new_points; while(linecur!=NULL) { cur->z = linecur->x*sin(deginc*i); cur->x = linecur->x*cos(deginc*i); cur->y = linecur->y; linecur = linecur->n; if(linecur!=NULL) { ALLOC_POINT(cur->n); cur = cur->n; } } addSlice(slice); } recompute_normals(); break; case 'a': /* vertical subdivision */ if(!mode || slices==NULL) break; cur_slice=slices; subdiv_v++; printf("Vertical subdivision level %d\n",subdiv_v); linecur = cur_slice->line; /* calc the first point */ cur = new_points = calc_point(linecur,linecur,linecur->n,linecur->n->n); /* calc middle and last points */ while(linecur->n->n!=NULL) { if(linecur->n->n->n!=NULL) /* middle points */ cur->n = calc_point(linecur,linecur->n,linecur->n->n,linecur->n->n->n); else cur->n = calc_point(linecur,linecur->n,linecur->n->n,linecur->n->n); cur = cur->n; linecur = linecur->n; } interleave(cur_slice->line,new_points); new_points = duplicate_slice(cur_slice->line); deginc = 2*M_PI/subdiv_h; freeModel(); for(i=0;i<subdiv_h;i++) { ALLOC_POINT(slice); cur=slice; linecur=new_points; while(linecur!=NULL) { cur->z = linecur->x*sin(deginc*i); cur->x = linecur->x*cos(deginc*i); cur->y = linecur->y; linecur = linecur->n; if(linecur!=NULL) { ALLOC_POINT(cur->n); cur = cur->n; } } addSlice(slice); } recompute_normals(); break; case 'd': shading=(~shading)&1; printf("%s shading\n",shading?"Phong":"Gouraud"); break; case '<': if(mode) { glMatrixMode(GL_MODELVIEW); glRotatef(1,0.0,1.0,0.0); } break; case '>': if(mode) { glMatrixMode(GL_MODELVIEW); glRotatef(-1,0.0,1.0,0.0); } break; default: /* Unrecognized keypress */ return; } glutPostRedisplay(); return; }