MEDMISC.C 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*
  2. * $Source: f:/miner/source/main/editor/rcs/medmisc.c $
  3. * $Revision: 2.1 $
  4. * $Author: john $
  5. * $Date: 1995/03/06 15:20:50 $
  6. *
  7. * Miscellaneous functions stripped out of med.c
  8. *
  9. * $Log: medmisc.c $
  10. * Revision 2.1 1995/03/06 15:20:50 john
  11. * New screen mode method.
  12. *
  13. * Revision 2.0 1995/02/27 11:36:40 john
  14. * Version 2.0. Ansi-fied.
  15. *
  16. * Revision 1.31 1994/11/27 23:17:20 matt
  17. * Made changes for new mprintf calling convention
  18. *
  19. * Revision 1.30 1994/11/17 14:48:11 mike
  20. * validation functions moved from editor to game.
  21. *
  22. * Revision 1.29 1994/08/25 21:56:15 mike
  23. * IS_CHILD stuff.
  24. *
  25. * Revision 1.28 1994/08/09 16:06:00 john
  26. * Added the ability to place players. Made old
  27. * Player variable be ConsoleObject.
  28. *
  29. * Revision 1.27 1994/07/21 17:25:43 matt
  30. * Took out unused func medlisp_create_new_mine() and its prototype
  31. *
  32. * Revision 1.26 1994/07/21 13:27:01 matt
  33. * Cleaned up render code and added error checking
  34. *
  35. * Revision 1.25 1994/07/20 15:32:52 matt
  36. * Added func to call g3_point_2_vec() for texture-mapped window
  37. *
  38. * Revision 1.24 1994/07/15 15:26:53 yuan
  39. * Fixed warning
  40. *
  41. * Revision 1.23 1994/07/14 14:45:16 yuan
  42. * Added function to set default segment and attach.
  43. *
  44. * Revision 1.22 1994/07/14 09:46:34 yuan
  45. * Make E attach segment as well as make default.
  46. *
  47. *
  48. * Revision 1.21 1994/07/11 18:39:17 john
  49. * Reversed y axis roll.
  50. *
  51. * Revision 1.20 1994/07/06 16:36:32 mike
  52. * Add hook for game to render wireframe view: draw_world_from_game.
  53. *
  54. * Revision 1.19 1994/06/24 14:08:31 john
  55. * Changed calling params for render_frame.
  56. *
  57. * Revision 1.18 1994/06/23 15:54:02 matt
  58. * Finished hacking in 3d rendering in big window
  59. *
  60. * Revision 1.17 1994/06/22 00:32:56 matt
  61. * New version, without all the errors of the last version. Sorry.
  62. *
  63. * Revision 1.15 1994/05/23 14:48:54 mike
  64. * make current segment be add segment.
  65. *
  66. * Revision 1.14 1994/05/19 12:09:35 matt
  67. * Use new vecmat macros and globals
  68. *
  69. * Revision 1.13 1994/05/14 17:17:55 matt
  70. * Got rid of externs in source (non-header) files
  71. *
  72. * Revision 1.12 1994/05/09 23:35:06 mike
  73. * Add ClearFoundList, which is probably no longer being called.
  74. *
  75. * Revision 1.11 1994/05/04 14:11:40 mike
  76. * Increase render depth from 4 to 6 by default.
  77. *
  78. * Revision 1.10 1994/04/27 21:00:25 matt
  79. * Made texture-mapped window redraw when editor state variables (such as
  80. * current object) have changed.
  81. *
  82. * Revision 1.9 1994/03/31 12:03:38 matt
  83. * Cleaned up includes
  84. *
  85. * Revision 1.8 1994/02/17 11:31:21 matt
  86. * Changes in object system
  87. *
  88. * Revision 1.7 1994/02/11 11:05:14 yuan
  89. * Make chase mode unsettable... Gives a warning on the mono.
  90. *
  91. * Revision 1.6 1994/01/21 17:37:24 matt
  92. * Moved code from render_frame() to caller, making code cleaner
  93. *
  94. * Revision 1.5 1994/01/11 18:12:43 yuan
  95. * compress_mines removed. Now it is called within
  96. * the gamesave.min save whenever we go into the game.
  97. *
  98. * Revision 1.4 1994/01/05 10:54:15 john
  99. * New object code by John
  100. *
  101. * Revision 1.3 1993/12/29 16:15:27 mike
  102. * Kill scale field from segment struct.
  103. *
  104. * Revision 1.2 1993/12/17 12:05:00 john
  105. * Took stuff out of med.c; moved into medsel.c, meddraw.c, medmisc.c
  106. *
  107. * Revision 1.1 1993/12/17 08:35:47 john
  108. * Initial revision
  109. *
  110. *
  111. */
  112. #pragma off (unreferenced)
  113. static char rcsid[] = "$Id: medmisc.c 2.1 1995/03/06 15:20:50 john Exp $";
  114. #pragma on (unreferenced)
  115. #include <stdio.h>
  116. #include <stdlib.h>
  117. #include <stdarg.h>
  118. #include <string.h>
  119. #include <process.h>
  120. #include "gr.h"
  121. #include "ui.h"
  122. #include "3d.h"
  123. #include "mem.h"
  124. #include "error.h"
  125. #include "mono.h"
  126. #include "key.h"
  127. #include "func.h"
  128. #include "inferno.h"
  129. #include "editor.h"
  130. #include "segment.h"
  131. #include "render.h"
  132. #include "screens.h"
  133. #include "object.h"
  134. #include "texpage.h" // For texpage_goto_first
  135. #include "meddraw.h" // For draw_World
  136. #include "game.h"
  137. //return 2d distance, i.e, sqrt(x*x + y*y)
  138. long dist_2d(long x,long y);
  139. #pragma aux dist_2d parm [eax] [ebx] value [eax] modify [ecx edx] = \
  140. "imul eax" \
  141. "xchg ebx,eax" \
  142. "mov ecx,edx" \
  143. "imul eax" \
  144. "add eax,ebx" \
  145. "adc edx,ecx" \
  146. "call quad_sqrt";
  147. // Given mouse movement in dx, dy, returns a 3x3 rotation matrix in RotMat.
  148. // Taken from Graphics Gems III, page 51, "The Rolling Ball"
  149. void GetMouseRotation( int idx, int idy, vms_matrix * RotMat )
  150. {
  151. fix dr, cos_theta, sin_theta, denom, cos_theta1;
  152. fix Radius = i2f(100);
  153. fix dx,dy;
  154. fix dxdr,dydr;
  155. idy *= -1;
  156. dx = i2f(idx); dy = i2f(idy);
  157. dr = dist_2d(dx,dy);
  158. denom = dist_2d(Radius,dr);
  159. cos_theta = fixdiv(Radius,denom);
  160. sin_theta = fixdiv(dr,denom);
  161. cos_theta1 = f1_0 - cos_theta;
  162. dxdr = fixdiv(dx,dr);
  163. dydr = fixdiv(dy,dr);
  164. RotMat->rvec.x = cos_theta + fixmul(fixmul(dydr,dydr),cos_theta1);
  165. RotMat->uvec.x = - fixmul(fixmul(dxdr,dydr),cos_theta1);
  166. RotMat->fvec.x = fixmul(dxdr,sin_theta);
  167. RotMat->rvec.y = RotMat->uvec.x;
  168. RotMat->uvec.y = cos_theta + fixmul(fixmul(dxdr,dxdr),cos_theta1);
  169. RotMat->fvec.y = fixmul(dydr,sin_theta);
  170. RotMat->rvec.z = -RotMat->fvec.x;
  171. RotMat->uvec.z = -RotMat->fvec.y;
  172. RotMat->fvec.z = cos_theta;
  173. }
  174. int Gameview_lockstep; //if set, view is locked to Curseg
  175. int ToggleLockstep()
  176. {
  177. Gameview_lockstep = !Gameview_lockstep;
  178. if (Gameview_lockstep == 0) {
  179. if (last_keypress != KEY_L)
  180. diagnostic_message("[L] - Lock mode OFF");
  181. else
  182. diagnostic_message("Lock mode OFF");
  183. }
  184. if (Gameview_lockstep) {
  185. if (last_keypress != KEY_L)
  186. diagnostic_message("[L] Lock mode ON");
  187. else
  188. diagnostic_message("Lock mode ON");
  189. Cursegp = &Segments[ConsoleObject->segnum];
  190. med_create_new_segment_from_cursegp();
  191. set_view_target_from_segment(Cursegp);
  192. Update_flags = UF_ED_STATE_CHANGED;
  193. }
  194. return Gameview_lockstep;
  195. }
  196. int medlisp_delete_segment(void)
  197. {
  198. if (!med_delete_segment(Cursegp)) {
  199. if (Lock_view_to_cursegp)
  200. set_view_target_from_segment(Cursegp);
  201. autosave_mine(mine_filename);
  202. strcpy(undo_status[Autosave_count], "Delete Segment UNDONE.");
  203. Update_flags |= UF_WORLD_CHANGED;
  204. mine_changed = 1;
  205. diagnostic_message("Segment deleted.");
  206. warn_if_concave_segments(); // This could be faster -- just check if deleted segment was concave, warn accordingly
  207. }
  208. return 1;
  209. }
  210. int medlisp_scale_segment(void)
  211. {
  212. vms_matrix rotmat;
  213. vms_vector scale;
  214. scale.x = fl2f((float) func_get_param(0));
  215. scale.y = fl2f((float) func_get_param(1));
  216. scale.z = fl2f((float) func_get_param(2));
  217. med_create_new_segment(&scale);
  218. med_rotate_segment(Cursegp,vm_angles_2_matrix(&rotmat,&Seg_orientation));
  219. Update_flags |= UF_WORLD_CHANGED;
  220. mine_changed = 1;
  221. return 1;
  222. }
  223. int medlisp_rotate_segment(void)
  224. {
  225. vms_matrix rotmat;
  226. Seg_orientation.p = func_get_param(0);
  227. Seg_orientation.b = func_get_param(1);
  228. Seg_orientation.h = func_get_param(2);
  229. med_rotate_segment(Cursegp,vm_angles_2_matrix(&rotmat,&Seg_orientation));
  230. Update_flags |= UF_WORLD_CHANGED | UF_VIEWPOINT_MOVED;
  231. mine_changed = 1;
  232. return 1;
  233. }
  234. int ToggleLockViewToCursegp(void)
  235. {
  236. Lock_view_to_cursegp = !Lock_view_to_cursegp;
  237. Update_flags = UF_ED_STATE_CHANGED;
  238. if (Lock_view_to_cursegp) {
  239. if (last_keypress != KEY_V+KEY_CTRLED)
  240. diagnostic_message("[ctrl-V] View locked to Cursegp.");
  241. else
  242. diagnostic_message("View locked to Cursegp.");
  243. set_view_target_from_segment(Cursegp);
  244. } else {
  245. if (last_keypress != KEY_V+KEY_CTRLED)
  246. diagnostic_message("[ctrl-V] View not locked to Cursegp.");
  247. else
  248. diagnostic_message("View not locked to Cursegp.");
  249. }
  250. return Lock_view_to_cursegp;
  251. }
  252. int ToggleDrawAllSegments()
  253. {
  254. Draw_all_segments = !Draw_all_segments;
  255. Update_flags = UF_ED_STATE_CHANGED;
  256. if (Draw_all_segments == 1) {
  257. if (last_keypress != KEY_A+KEY_CTRLED)
  258. diagnostic_message("[ctrl-A] Draw all segments ON.");
  259. else
  260. diagnostic_message("Draw all segments ON.");
  261. }
  262. if (Draw_all_segments == 0) {
  263. if (last_keypress != KEY_A+KEY_CTRLED)
  264. diagnostic_message("[ctrl-A] Draw all segments OFF.");
  265. else
  266. diagnostic_message("Draw all segments OFF.");
  267. }
  268. return Draw_all_segments;
  269. }
  270. int Big_depth=6;
  271. int IncreaseDrawDepth(void)
  272. {
  273. Big_depth++;
  274. Update_flags = UF_ED_STATE_CHANGED;
  275. return 1;
  276. }
  277. int DecreaseDrawDepth(void)
  278. {
  279. if (Big_depth > 1) {
  280. Big_depth--;
  281. Update_flags = UF_ED_STATE_CHANGED;
  282. }
  283. return 1;
  284. }
  285. int ToggleCoordAxes()
  286. {
  287. // Toggle display of coordinate axes.
  288. Show_axes_flag = !Show_axes_flag;
  289. LargeView.ev_changed = 1;
  290. if (Show_axes_flag == 1) {
  291. if (last_keypress != KEY_D+KEY_CTRLED)
  292. diagnostic_message("[ctrl-D] Coordinate axes ON.");
  293. else
  294. diagnostic_message("Coordinate axes ON.");
  295. }
  296. if (Show_axes_flag == 0) {
  297. if (last_keypress != KEY_D+KEY_CTRLED)
  298. diagnostic_message("[ctrl-D] Coordinate axes OFF.");
  299. else
  300. diagnostic_message("Coordinate axes OFF.");
  301. }
  302. return Show_axes_flag;
  303. }
  304. int med_keypad_goto_prev()
  305. {
  306. ui_pad_goto_prev();
  307. return 0;
  308. }
  309. int med_keypad_goto_next()
  310. {
  311. ui_pad_goto_next();
  312. return 0;
  313. }
  314. int med_keypad_goto()
  315. {
  316. ui_pad_goto(func_get_param(0));
  317. return 0;
  318. }
  319. int render_3d_in_big_window=0;
  320. int medlisp_update_screen()
  321. {
  322. int vn;
  323. if (!render_3d_in_big_window)
  324. for (vn=0;vn<N_views;vn++)
  325. if (Views[vn]->ev_changed || (Update_flags & (UF_WORLD_CHANGED|UF_VIEWPOINT_MOVED|UF_ED_STATE_CHANGED))) {
  326. draw_world(Views[vn]->ev_canv,Views[vn],Cursegp,Big_depth);
  327. Views[vn]->ev_changed = 0;
  328. }
  329. if (Update_flags & (UF_WORLD_CHANGED|UF_GAME_VIEW_CHANGED|UF_ED_STATE_CHANGED)) {
  330. grs_canvas temp_canvas;
  331. grs_canvas *render_canv,*show_canv;
  332. if (render_3d_in_big_window) {
  333. gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
  334. LargeView.ev_canv->cv_bitmap.bm_w,LargeView.ev_canv->cv_bitmap.bm_h);
  335. render_canv = &temp_canvas;
  336. show_canv = LargeView.ev_canv;
  337. }
  338. else {
  339. render_canv = VR_offscreen_buffer;
  340. show_canv = Canv_editor_game;
  341. }
  342. gr_set_current_canvas(render_canv);
  343. render_frame(0);
  344. Assert(render_canv->cv_bitmap.bm_w == show_canv->cv_bitmap.bm_w &&
  345. render_canv->cv_bitmap.bm_h == show_canv->cv_bitmap.bm_h);
  346. ui_mouse_hide();
  347. gr_bm_ubitblt(show_canv->cv_bitmap.bm_w,show_canv->cv_bitmap.bm_h,
  348. 0,0,0,0,&render_canv->cv_bitmap,&show_canv->cv_bitmap);
  349. ui_mouse_show();
  350. }
  351. Update_flags=UF_NONE; //clear flags
  352. return 1;
  353. }
  354. med_point_2_vec(grs_canvas *canv,vms_vector *v,short sx,short sy)
  355. {
  356. gr_set_current_canvas(canv);
  357. g3_start_frame();
  358. g3_set_view_matrix(&Viewer->pos,&Viewer->orient,Render_zoom);
  359. g3_point_2_vec(v,sx,sy);
  360. g3_end_frame();
  361. }
  362. void draw_world_from_game(void)
  363. {
  364. if (ModeFlag == 2)
  365. draw_world(Views[0]->ev_canv,Views[0],Cursegp,Big_depth);
  366. }
  367. int UndoCommand()
  368. { int u;
  369. u = undo();
  370. if (Lock_view_to_cursegp)
  371. set_view_target_from_segment(Cursegp);
  372. if (u == 0) {
  373. if (Autosave_count==9) diagnostic_message(undo_status[0]);
  374. else
  375. diagnostic_message(undo_status[Autosave_count+1]);
  376. }
  377. else
  378. if (u == 1) diagnostic_message("Can't Undo.");
  379. else
  380. if (u == 2) diagnostic_message("Can't Undo - Autosave OFF");
  381. Update_flags |= UF_WORLD_CHANGED;
  382. mine_changed = 1;
  383. warn_if_concave_segments();
  384. return 1;
  385. }
  386. int ToggleAutosave()
  387. {
  388. Autosave_flag = !Autosave_flag;
  389. if (Autosave_flag == 1)
  390. diagnostic_message("Autosave ON.");
  391. else
  392. diagnostic_message("Autosave OFF.");
  393. return Autosave_flag;
  394. }
  395. int AttachSegment()
  396. {
  397. if (med_attach_segment(Cursegp, &New_segment, Curside, AttachSide)==4) // Used to be WBACK instead of Curside
  398. diagnostic_message("Cannot attach segment - already a connection on current side.");
  399. else {
  400. if (Lock_view_to_cursegp)
  401. set_view_target_from_segment(Cursegp);
  402. vm_angvec_make(&Seg_orientation,0,0,0);
  403. Curside = WBACK;
  404. Update_flags |= UF_WORLD_CHANGED;
  405. autosave_mine(mine_filename);
  406. strcpy(undo_status[Autosave_count], "Attach Segment UNDONE.\n");
  407. mine_changed = 1;
  408. warn_if_concave_segment(Cursegp);
  409. }
  410. return 1;
  411. }
  412. int ForceTotalRedraw()
  413. {
  414. Update_flags = UF_ALL;
  415. return 1;
  416. }
  417. #if ORTHO_VIEWS
  418. int SyncLargeView()
  419. {
  420. // Make large view be same as one of the orthogonal views.
  421. Large_view_index = (Large_view_index + 1) % 3; // keep in 0,1,2 for top, front, right
  422. switch (Large_view_index) {
  423. case 0: LargeView.ev_matrix = TopView.ev_matrix; break;
  424. case 1: LargeView.ev_matrix = FrontView.ev_matrix; break;
  425. case 2: LargeView.ev_matrix = RightView.ev_matrix; break;
  426. }
  427. Update_flags |= UF_VIEWPOINT_MOVED;
  428. return 1;
  429. }
  430. #endif
  431. int DeleteCurSegment()
  432. {
  433. // Delete current segment.
  434. med_delete_segment(Cursegp);
  435. autosave_mine(mine_filename);
  436. strcpy(undo_status[Autosave_count], "Delete segment UNDONE.");
  437. if (Lock_view_to_cursegp)
  438. set_view_target_from_segment(Cursegp);
  439. Update_flags |= UF_WORLD_CHANGED;
  440. mine_changed = 1;
  441. diagnostic_message("Segment deleted.");
  442. warn_if_concave_segments(); // This could be faster -- just check if deleted segment was concave, warn accordingly
  443. return 1;
  444. }
  445. int CreateDefaultNewSegment()
  446. {
  447. // Create a default segment for New_segment.
  448. vms_vector tempvec;
  449. med_create_new_segment(vm_vec_make(&tempvec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));
  450. mine_changed = 1;
  451. return 1;
  452. }
  453. int CreateDefaultNewSegmentandAttach()
  454. {
  455. CreateDefaultNewSegment();
  456. AttachSegment();
  457. return 1;
  458. }
  459. int ExchangeMarkAndCurseg()
  460. {
  461. // If Markedsegp != Cursegp, and Markedsegp->segnum != -1, exchange Markedsegp and Cursegp
  462. if (Markedsegp)
  463. if (Markedsegp->segnum != -1) {
  464. segment *tempsegp;
  465. int tempside;
  466. tempsegp = Markedsegp; Markedsegp = Cursegp; Cursegp = tempsegp;
  467. tempside = Markedside; Markedside = Curside; Curside = tempside;
  468. med_create_new_segment_from_cursegp();
  469. Update_flags |= UF_ED_STATE_CHANGED;
  470. mine_changed = 1;
  471. }
  472. return 1;
  473. }
  474. int medlisp_add_segment()
  475. {
  476. AttachSegment();
  477. //segment *ocursegp = Cursegp;
  478. // med_attach_segment(Cursegp, &New_segment, Curside, WFRONT); // Used to be WBACK instead of Curside
  479. //med_propagate_tmaps_to_segments(ocursegp,Cursegp);
  480. // set_view_target_from_segment(Cursegp);
  481. //// while (!vm_angvec_make(&Seg_orientation,0,0,0));
  482. // Curside = WBACK;
  483. return 1;
  484. }
  485. int ClearSelectedList(void)
  486. {
  487. N_selected_segs = 0;
  488. Update_flags |= UF_WORLD_CHANGED;
  489. diagnostic_message("Selected list cleared.");
  490. return 1;
  491. }
  492. int ClearFoundList(void)
  493. {
  494. N_found_segs = 0;
  495. Update_flags |= UF_WORLD_CHANGED;
  496. diagnostic_message("Found list cleared.");
  497. return 1;
  498. }
  499. // ---------------------------------------------------------------------------------------------------
  500. // Do chase mode.
  501. // View current segment (Cursegp) from the previous segment.
  502. void set_chase_matrix(segment *sp)
  503. {
  504. int v;
  505. vms_vector forvec = ZERO_VECTOR, upvec;
  506. vms_vector tv = ZERO_VECTOR;
  507. segment *psp;
  508. // move back two segments, if possible, else move back one, if possible, else use current
  509. if (IS_CHILD(sp->children[WFRONT])) {
  510. psp = &Segments[sp->children[WFRONT]];
  511. if (IS_CHILD(psp->children[WFRONT]))
  512. psp = &Segments[psp->children[WFRONT]];
  513. } else
  514. psp = sp;
  515. for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  516. vm_vec_add2(&forvec,&Vertices[sp->verts[v]]);
  517. vm_vec_scale(&forvec,F1_0/MAX_VERTICES_PER_SEGMENT);
  518. for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  519. vm_vec_add2(&tv,&Vertices[psp->verts[v]]);
  520. vm_vec_scale(&tv,F1_0/MAX_VERTICES_PER_SEGMENT);
  521. Ed_view_target = forvec;
  522. vm_vec_sub2(&forvec,&tv);
  523. extract_up_vector_from_segment(psp,&upvec);
  524. if (!((forvec.x == 0) && (forvec.y == 0) && (forvec.z == 0)))
  525. vm_vector_2_matrix(&LargeView.ev_matrix,&forvec,&upvec,NULL);
  526. }
  527. // ---------------------------------------------------------------------------------------------------
  528. void set_view_target_from_segment(segment *sp)
  529. {
  530. vms_vector tv = ZERO_VECTOR;
  531. int v;
  532. if (Funky_chase_mode)
  533. {
  534. mprintf((0, "Trying to set chase mode\n"));
  535. //set_chase_matrix(sp);
  536. }
  537. else {
  538. for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
  539. vm_vec_add2(&tv,&Vertices[sp->verts[v]]);
  540. vm_vec_scale(&tv,F1_0/MAX_VERTICES_PER_SEGMENT);
  541. Ed_view_target = tv;
  542. }
  543. Update_flags |= UF_VIEWPOINT_MOVED;
  544. }
  545.