PageRenderTime 49ms CodeModel.GetById 6ms app.highlight 36ms RepoModel.GetById 0ms app.codeStats 0ms

/project/max5_modifier/max_joint.cpp

http://narutortsproject.googlecode.com/
C++ | 831 lines | 517 code | 154 blank | 160 comment | 47 complexity | 1f1e5cf6912dbc0b90cbd79d5c099c38 MD5 | raw file
  1
  2#include <crtdbg.h>
  3
  4#include "max5_modifier_mod.h"
  5#include "max_joint.h"
  6
  7
  8JointObjectClassDesc  joint_object_class_desc;
  9
 10int JointObjectClassDesc::IsPublic()
 11{
 12  return 1;
 13};
 14
 15void * JointObjectClassDesc::Create(BOOL loading)
 16{
 17  return new JointObject;
 18};
 19
 20const TCHAR * JointObjectClassDesc::ClassName()
 21{
 22  static char class_name[MAX_STRING_LENGTH];
 23  strcpy_s(class_name, MAX_STRING_LENGTH, JOINTOBJECT_CLASS_NAME);
 24  return class_name;
 25};
 26
 27const TCHAR* JointObjectClassDesc::InternalName()
 28{
 29  static char class_name[MAX_STRING_LENGTH];
 30  strcpy_s(class_name, MAX_STRING_LENGTH, JOINTOBJECT_CLASS_NAME);
 31  return class_name;
 32};
 33
 34HINSTANCE JointObjectClassDesc::HInstance()
 35{
 36  return hInstance;
 37}
 38
 39SClass_ID JointObjectClassDesc::SuperClassID()
 40{
 41  //return WSM_OBJECT_CLASS_ID;
 42  return GEOMOBJECT_CLASS_ID;
 43};
 44
 45Class_ID JointObjectClassDesc::ClassID()
 46{
 47  return Class_ID (JOINTOBJECT_CLASS_ID, JOINTOBJECT_CLASS_SID);
 48};
 49
 50const TCHAR* JointObjectClassDesc::Category()
 51{
 52  static char class_category[MAX_STRING_LENGTH];
 53  strcpy_s(class_category, MAX_STRING_LENGTH, JOINTOBJECT_CATEGORY);
 54
 55  return class_category;
 56};
 57
 58class JointObjectValidator : public PBValidator
 59{
 60  // pick only
 61  BOOL Validate(PB2Value &v)
 62  {
 63    if (!v.r)
 64      return FALSE;
 65    //static Object *ob;
 66    //ob = (((INode *)v.r)->EvalWorldState(0)).obj;
 67    //if ( ob && (ob->ClassID() == Class_ID(WAYPOINT_CLASS_ID, WAYPOINT_CLASS_SID)) )
 68    return TRUE;
 69    //else
 70    //  return FALSE;
 71  }
 72};
 73
 74static JointObjectValidator joint_object_point_validator;
 75
 76
 77class JointObjectPBAccessor : public PBAccessor
 78{ 
 79public:
 80
 81  void TabChanged(tab_changes changeCode, Tab<PB2Value>* tab, ReferenceMaker* owner, ParamID id, int tabIndex, int count) 
 82  {
 83  }
 84
 85  void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid)
 86  {
 87    JointObject* joint_object = (JointObject*) owner;
 88    switch (id)
 89    {
 90    case JO_NODE0:
 91      {
 92        /*ICustButton *iBut = GetICustButton(GetDlgItem(giz->hGizmoParams, IDC_EDIT));
 93        if (GetCOREInterface()->GetSubObjectLevel() == 0)
 94          iBut->Enable(FALSE);
 95        else iBut->Enable(TRUE);
 96        iBut->SetType(CBT_CHECK);
 97        iBut->SetHighlightColor(GREEN_WASH);
 98        ReleaseICustButton(iBut);*/
 99
100      }
101    };
102  }
103
104  void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)    // set from v
105  {
106    JointObject* joint_object = (JointObject*) owner;
107    switch (id)
108    {
109    case JO_NODE0:
110      {
111        //way_point->SetNodeR(WP_NODE_R0, v.i > 0, t);
112      }
113    };
114  }
115};
116
117
118static JointObjectPBAccessor joint_object_point_accessor;
119
120static ParamBlockDesc2 JointObjectDescParam
121(
122	0, _T("JointObjectParameters"), 0, &joint_object_class_desc, P_AUTO_CONSTRUCT+P_AUTO_UI, 0,
123
124	//rollout
125	IDD_DIALOG_JOINT, "Parameters", 0, 0, NULL,
126
127	  // params
128    WP_NODE0,	_T("nodePicker1"), TYPE_INODE, 0, "NODE1",
129    p_ui,	TYPE_PICKNODEBUTTON, IDC_BUTTON_BODY1,
130    end,
131
132    WP_NODE1,	_T("nodePicker2"), TYPE_INODE, 0, "NODE2",
133    p_ui,	TYPE_PICKNODEBUTTON, IDC_BUTTON_BODY2,
134    end,
135	end
136);
137
138IObjParam* JointObject::ip = 0;
139JointObject* JointObject::editOb = 0;
140IParamMap2* JointObject::pmapParam = 0;
141
142//Call back
143class JointObjectCreateCallBack: public CreateMouseCallBack {
144  JointObject* ob;
145  Point3    p0,p1;
146  IPoint2   sp0, sp1;
147  BOOL      square;
148public:
149  int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
150  void SetObj(JointObject *obj) { ob = obj; }
151};
152
153int JointObjectCreateCallBack::proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
154{
155	Point3 d;
156	if (msg == MOUSE_FREEMOVE)
157	{
158    //vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);
159	}	else
160  if ( msg == MOUSE_POINT || msg == MOUSE_MOVE)
161  {
162    if (point == 0)
163    {
164				// Find the node and plug in the wire color
165				ULONG handle;
166				ob->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE);
167				INode *node;
168				node = GetCOREInterface()->GetINodeByHandle(handle);
169				if (node)
170        {
171					Point3 color = GetUIColor(COLOR_POINT_OBJ);
172					node->SetWireColor(RGB(color.x*255.0f, color.y*255.0f, color.z*255.0f));
173				}
174
175				ob->suspendSnap = TRUE;
176				#ifdef _3D_CREATE	
177					mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));
178				#else	
179					mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
180				#endif
181    } else
182		if (point == 1)
183    {
184      #ifdef _3D_CREATE	
185        mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));
186      #else	
187        mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
188      #endif
189      if (msg==MOUSE_POINT)
190      {
191        ob->suspendSnap = FALSE;
192        return 0;
193      }
194			return CREATE_STOP;
195		}
196  } else
197	if (msg == MOUSE_ABORT)
198  {		
199		return CREATE_ABORT;
200	}
201
202	return TRUE;
203};
204
205static JointObjectCreateCallBack joint_object_create_call_back;
206
207
208JointObject::JointObject()
209{
210  pblock = 0;
211  joint_object_class_desc.MakeAutoParamBlocks(this);
212
213  //SetAFlag(A_OBJ_CREATING);
214};
215
216JointObject::~JointObject()
217{
218
219};
220
221void JointObject::SetNodeR(int node_id, bool val, TimeValue time)
222{
223  pblock->SetValue(node_id, time, BOOL(val));
224};
225
226bool JointObject::GetNodeR(int node_id, TimeValue time)
227{
228  BOOL val = FALSE;
229  pblock->GetValue(node_id, time, val, FOREVER);
230  return val;
231};
232
233RefResult JointObject::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message )
234{
235  switch (message)
236  {
237  case REFMSG_CHANGE:
238    {
239      if (editOb==this)
240        InvalidateUI();
241
242      /*if (pblock)
243      {
244        for (int i = WP_NODE0; i <= WP_NODE4; i ++)
245        {
246          INode* node = 0;
247          if (pblock->GetValue(i, changeInt.Start(), node, FOREVER) && node)
248          {
249            Class_ID node_class = node->ClassID();
250            Object * node_obj = node->EvalWorldState(changeInt.Start()).obj;
251            if (node_obj)
252            {
253              Class_ID obj_class = node_obj->ClassID();
254
255              if (obj_class != Class_ID(WAYPOINT_CLASS_ID, WAYPOINT_CLASS_SID))
256                pblock->SetValue(i, changeInt.Start(), 0);
257            }
258          };
259        }
260      }*/
261      break;
262    };
263  }
264  return(REF_SUCCEED);
265};		
266
267int JointObject::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) 
268{
269  Matrix3 tm(1);	
270  HitRegion hitRegion;
271  DWORD	savedLimits;
272  Point3 pt(0,0,0);
273
274  vpt->getGW()->setTransform(tm);
275  GraphicsWindow *gw = vpt->getGW();	
276  Material *mtl = gw->getMaterial();
277
278  tm = inode->GetObjectTM(t);		
279  MakeHitRegion(hitRegion, type, crossing, 4, p);
280
281  gw->setRndLimits(((savedLimits = gw->getRndLimits())|GW_PICK)&~GW_ILLUM);
282  gw->setHitRegion(&hitRegion);
283  gw->clearHitCode();
284
285  DrawAndHit(t, inode, vpt);
286  
287  //if (showAxis) {
288  //DrawAxis(vpt,tm,axisLength,screenSize);
289  //}
290  //vpt->getGW()->setTransform(tm);
291  //vpt->getGW()->marker(&pt,X_MRKR);
292
293  gw->setRndLimits(savedLimits);
294
295  if ((hitRegion.type != POINT_RGN) && !hitRegion.crossing)
296    return TRUE;
297
298  return gw->checkHitCode();
299  return 0;
300}
301
302void JointObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt)
303{
304	if(suspendSnap)
305		return;
306  /*
307
308	Matrix3 tm = inode->GetObjectTM(t);	
309	GraphicsWindow *gw = vpt->getGW();	
310	gw->setTransform(tm);
311
312	Matrix3 invPlane = Inverse(snap->plane);
313
314	// Make sure the vertex priority is active and at least as important as the best snap so far
315	if(snap->vertPriority > 0 && snap->vertPriority <= snap->priority)
316  {
317		Point2 fp = Point2((float)p->x, (float)p->y);
318		Point2 screen2;
319		IPoint3 pt3;
320
321		Point3 thePoint(0,0,0);
322		// If constrained to the plane, make sure this point is in it!
323		if(snap->snapType == SNAP_2D || snap->flags & SNAP_IN_PLANE)
324    {
325			Point3 test = thePoint * tm * invPlane;
326			if(fabs(test.z) > 0.0001)	// Is it in the plane (within reason)?
327				return;
328		}
329
330		gw->wTransPoint(&thePoint,&pt3);
331		screen2.x = (float)pt3.x;
332		screen2.y = (float)pt3.y;
333
334		// Are we within the snap radius?
335		int len = (int)Length(screen2 - fp);
336		if(len <= snap->strength)
337    {
338			// Is this priority better than the best so far?
339			if(snap->vertPriority < snap->priority)
340      {
341				snap->priority = snap->vertPriority;
342				snap->bestWorld = thePoint * tm;
343				snap->bestScreen = screen2;
344				snap->bestDist = len;
345			} else
346			if(len < snap->bestDist)
347      {
348				snap->priority = snap->vertPriority;
349				snap->bestWorld = thePoint * tm;
350				snap->bestScreen = screen2;
351				snap->bestDist = len;
352			}
353		}
354	}*/
355
356};
357
358void JointObject::SetExtendedDisplay(int flags)
359{
360  extDispFlags = flags;
361};
362
363int JointObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
364{
365  DrawAndHit(t, inode, vpt);
366  return 0;
367};
368
369
370CreateMouseCallBack* JointObject::GetCreateMouseCallBack()
371{
372  joint_object_create_call_back.SetObj(this);
373  return(&joint_object_create_call_back);
374};
375
376void JointObject::BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev)
377{
378  editOb = this;
379  this->ip = ip;
380
381  joint_object_class_desc.BeginEditParams(ip, this, flags, prev);
382
383  /*static TCHAR stringBuf[MAX_STRING_LENGTH];
384  strcpy_s(stringBuf, MAX_STRING_LENGTH, NARUTO_PARAMETERS);
385
386  if (pmapParam)
387  {
388    // Left over from last one created
389    pmapParam->SetParamBlock(pblock);
390  } else
391  {
392    // Gotta make a new one.
393    pmapParam = CreateCPParamMap(
394      WayPointdescParam, WAYPOINT_PARAMDESC_LENGTH,
395      pblock,
396      ip,
397      hInstance,
398      MAKEINTRESOURCE(IDD_DIALOG_WAYPOINT),
399      stringBuf, 0);
400  }
401  way_point_dlg_proc.SetObject(this);
402  pmapParam->SetUserDlgProc(&way_point_dlg_proc);*/
403};
404
405//On close custom menu
406void JointObject::EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
407{
408  editOb = NULL;
409
410  this->ip = NULL;
411  joint_object_class_desc.EndEditParams(ip, this, flags, next);
412  ClearAFlag(A_OBJ_CREATING);
413
414  /*
415  if(IsDlgButtonChecked(pmapParam->GetHWnd(), IDC_GRID_HOME_INTENSITY ))
416    dlgGridColor = GRID_COLOR_HOME_INT;
417  else if(IsDlgButtonChecked(pmapParam->GetHWnd(), IDC_GRID_HOME_COLOR ))
418    dlgGridColor = GRID_COLOR_HOME;
419  else if(IsDlgButtonChecked(pmapParam->GetHWnd(), IDC_GRID_OBJECT_COLOR ))
420    dlgGridColor = GRID_COLOR_OBJECT;
421  else
422    dlgGridColor = GRID_COLOR_GRAY;
423    */
424
425  /*if (flags & END_EDIT_REMOVEUI )
426  {
427    DestroyCPParamMap(pmapParam);
428    pmapParam  = 0;
429  }
430  this->ip = 0;
431  way_point_dlg_proc.SetObject(0);*/
432};
433
434TCHAR* JointObject::GetObjectName()
435{
436  return JOINTOBJECT_NAME;
437};
438
439ObjectState JointObject::Eval(TimeValue time)
440{
441  return ObjectState(this);
442};
443
444
445void JointObject::DeleteThis()
446{
447  delete this;
448};
449
450Class_ID JointObject::ClassID()
451{
452  return Class_ID (JOINTOBJECT_CLASS_ID, JOINTOBJECT_CLASS_SID);
453};
454
455int JointObject::GetParamBlockIndex(int id)
456{
457  if (pblock && id >= 0 && id < pblock->NumParams())
458    return id;
459  else
460    return -1;
461};
462
463void JointObject::GetWorldBoundBox(TimeValue t, INode *inode, ViewExp *vpt, Box3& box )
464{
465  Matrix3 tm;
466  tm = inode->GetObjectTM(t);
467  Box3 lbox;
468
469  GetLocalBoundBox(t, inode, vpt, lbox);
470  box = Box3(tm.GetTrans(), tm.GetTrans());
471  for (int i=0; i<8; i++)
472  {
473    box += lbox * tm;
474  }
475};
476
477void JointObject::GetLocalBoundBox(TimeValue t, INode *inode, ViewExp *vpt, Box3& box )
478{
479  Matrix3 tm = inode->GetObjectTM(t);	
480
481  float size = 20.0;
482  int screenSize = 0;
483
484  //pblock2->GetValue(pointobj_size, t, size, FOREVER);
485  //pblock2->GetValue(pointobj_screensize, t, screenSize, FOREVER);
486
487  float zoom = 1.0f;
488  if (screenSize)
489  {
490    zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*0.005f;
491  }
492  if (zoom==0.0f) zoom = 1.0f;
493
494  size *= zoom;
495  box =  Box3(Point3(0,0,0), Point3(0,0,0));
496  box += Point3(size*0.5f,  0.0f, 0.0f);
497  box += Point3( 0.0f, size*0.5f, 0.0f);
498  box += Point3( 0.0f, 0.0f, size*0.5f);
499  box += Point3(-size*0.5f,   0.0f,  0.0f);
500  box += Point3(  0.0f, -size*0.5f,  0.0f);
501  box += Point3(  0.0f,  0.0f, -size*0.5f);
502
503  box.EnlargeBy(10.0f/zoom);
504};
505
506Interval JointObject::ObjectValidity(TimeValue t)
507{
508  return FOREVER;
509};
510
511RefTargetHandle JointObject::Clone(RemapDir& remap)
512{
513  JointObject* new_joint = new JointObject();	
514  new_joint->ReplaceReference(0,remap.CloneRef(pblock));
515  BaseClone(this, new_joint, remap);
516  return(new_joint);
517};
518
519Animatable* JointObject::SubAnim(int i)
520{
521  return pblock;
522}
523
524IParamArray* JointObject::GetParamBlock()
525{
526  return (IParamArray*)pblock;
527};
528
529IParamBlock2* JointObject::GetParamBlock(int i)
530{
531  return pblock;
532}
533
534IParamBlock2* JointObject::GetParamBlockByID(short id)
535{
536  return pblock;
537}
538
539RefTargetHandle JointObject::GetReference(int i)
540{
541  return pblock;
542}
543
544void JointObject::SetReference(int i, RefTargetHandle rtarg)
545{
546  pblock=(IParamBlock2*)rtarg;
547}
548
549
550void JointObject::InvalidateUI()
551{
552  //pointobj_param_blk.InvalidateUI(pblock2->LastNotifyParamID());
553};
554
555void JointObject::UpdateParamblockFromVars()
556{
557  SuspendAnimate();
558  AnimateOff();
559
560
561  ResumeAnimate();
562};
563
564void JointObject::DrawLine(ViewExp *vpt, float x1, float y1, float z1, float x2, float y2, float z2)
565{
566  Point3 pts[2];
567  pts[0] = Point3(x1, y1, z1); pts[1] = Point3(x2, y2, z2);
568  vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
569}
570
571void JointObject::DrawArrow(ViewExp *vpt, float x, float y, float z, float size, bool arrow1, bool arrow2)
572{
573  float x1 = x/3.0f;
574  float y1 = y/3.0f;
575  float z1 = z/3.0f;
576
577  float x2 = 0.75f*x;
578  float y2 = 0.75f*y;
579  float z2 = 0.75f*z;
580
581  vpt->getGW()->setColor( LINE_COLOR, 0.0f, 1.0f, 0.0f);
582  DrawLine(vpt,  0.0f, 0.0f, 0.0f,   x, y, z);
583
584  float d = size/4.0f;
585  vpt->getGW()->setColor(LINE_COLOR, 1.0f, 1.0f, 0.0f);
586
587  //Arrow 1
588  if (arrow1)
589  {
590    DrawLine(vpt,  x2, y2, z2,   x, y, z);
591
592    DrawLine(vpt,  x2-d, y2, z2,   x, y, z);
593    DrawLine(vpt,  x2+d, y2, z2,   x, y, z);
594
595    DrawLine(vpt,  x2, y2-d, z2,   x, y, z);
596    DrawLine(vpt,  x2, y2+d, z2,   x, y, z);
597
598    DrawLine(vpt,  x2, y2, z2-d,   x, y, z);
599    DrawLine(vpt,  x2, y2, z2+d,   x, y, z);
600  };
601
602  if (arrow2)
603  {
604    DrawLine(vpt,  x1, y1, z1,   0.0f, 0.0f, 0.0f);
605
606    DrawLine(vpt,  x1-d, y1, z1,   0.0f, 0.0f, 0.0f);
607    DrawLine(vpt,  x1+d, y1, z1,   0.0f, 0.0f, 0.0f);
608
609    DrawLine(vpt,  x1, y1-d, z1,   0.0f, 0.0f, 0.0f);
610    DrawLine(vpt,  x1, y1+d, z1,   0.0f, 0.0f, 0.0f);
611
612    DrawLine(vpt,  x1, y1, z1-d,   0.0f, 0.0f, 0.0f);
613    DrawLine(vpt,  x1, y1, z1+d,   0.0f, 0.0f, 0.0f);
614  };
615};
616
617int JointObject::DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt)
618{
619  float size;
620  int centerMarker, axisTripod, cross, box, screenSize, drawOnTop;
621
622  DWORD dw_color = inode->GetWireColor();
623  Color color(dw_color);
624
625  Interval ivalid = FOREVER;
626  size = 20.0f;
627  centerMarker = 0;
628  axisTripod = 0;
629  cross = 1;
630  box = 0;
631  screenSize = 0;
632  drawOnTop = 0;
633
634  //pblock2->GetValue(pointobj_size, t,         size, ivalid);
635  //pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid);
636  //pblock2->GetValue(pointobj_axistripod, t,   axisTripod, ivalid);
637  //pblock2->GetValue(pointobj_cross, t,        cross, ivalid);
638  //pblock2->GetValue(pointobj_box, t,          box, ivalid);
639  //pblock2->GetValue(pointobj_screensize, t,   screenSize, ivalid);
640  //pblock2->GetValue(pointobj_drawontop, t,    drawOnTop, ivalid);
641
642  Matrix3 tm(1);
643  Matrix3 tm_base(1);
644  Point3 pt(0,0,0);
645  Point3 pts[5];
646
647  tm_base = vpt->getGW()->getTransform();
648
649  vpt->getGW()->setTransform(tm);	
650  tm = inode->GetObjectTM(t);
651
652  int limits = vpt->getGW()->getRndLimits();
653  if (drawOnTop)
654    vpt->getGW()->setRndLimits(limits & ~GW_Z_BUFFER);
655
656  if (inode->Selected())
657  {
658    vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_SELECTION) );
659    vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_SELECTION) );
660  } else if (!inode->IsFrozen() && !inode->Dependent())
661  {
662    //vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_POINT_AXES) );
663    //vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_POINT_AXES) );		
664    vpt->getGW()->setColor( TEXT_COLOR, color);
665    vpt->getGW()->setColor( LINE_COLOR, color);
666  }	
667
668  if (axisTripod) {
669    //DrawAxis(vpt, tm, size, screenSize);
670  }
671
672  size *= 0.5f;
673
674  float zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*0.005f;
675  if (screenSize)
676  {
677    tm.Scale(Point3(zoom,zoom,zoom));
678  }
679
680  vpt->getGW()->setTransform(tm);
681
682  if (!inode->IsFrozen() && !inode->Dependent() && !inode->Selected())
683  {
684    //vpt->getGW()->setColor(LINE_COLOR, GetUIColor(COLOR_POINT_OBJ));
685    vpt->getGW()->setColor( LINE_COLOR, color);
686  }
687
688  if (centerMarker) {		
689    vpt->getGW()->marker(&pt,X_MRKR);
690  }
691
692  //if (cross)
693  {
694    // X
695    pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f);
696    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
697
698    // Y
699    pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, size, 0.0f);
700    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
701
702    // Z
703    pts[0] = Point3(0.0f, 0.0f, -size); pts[1] = Point3(0.0f, 0.0f, size);
704    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
705  }
706
707  {
708    pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(0.0f, 0.0f, size);
709    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
710
711    pts[0] = Point3( size, 0.0f, 0.0f); pts[1] = Point3(0.0f, 0.0f, size);
712    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
713
714    pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, 0.0f, size);
715    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
716
717    pts[0] = Point3(0.0f,  size, 0.0f); pts[1] = Point3(0.0f, 0.0f, size);
718    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
719
720    pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(0.0f, 0.0f, -size);
721    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
722
723    pts[0] = Point3( size, 0.0f, 0.0f); pts[1] = Point3(0.0f, 0.0f, -size);
724    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
725
726    pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, 0.0f, -size);
727    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
728
729    pts[0] = Point3(0.0f,  size, 0.0f); pts[1] = Point3(0.0f, 0.0f, -size);
730    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
731
732
733    
734    pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(0.0f, -size, 0.0f);
735    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
736
737    pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(0.0f, size, 0.0f);
738    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
739
740    pts[0] = Point3(size, 0.0f, 0.0f); pts[1] = Point3(0.0f, -size, 0.0f);
741    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
742
743    pts[0] = Point3(size, 0.0f, 0.0f); pts[1] = Point3(0.0f, size, 0.0f);
744    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
745  }
746
747  //Link to another node
748  if (pblock)
749  {
750    Matrix3 matrix_base = inode->GetObjectTM(t);
751    Point3 pos_base = matrix_base.GetRow(3);
752
753    for (int node_i = JO_NODE0; node_i <= JO_NODE1; node_i ++)
754    {
755      INode* node = 0;
756      if (pblock->GetValue(node_i, t, node, FOREVER) && node)
757      {
758        Matrix3 matrix = node->GetObjectTM(t);
759        vpt->getGW()->setColor( LINE_COLOR, 0.0f, 1.0f, 0.0f);
760
761        Point3 pos = matrix.GetRow(3);
762        Point3 delta_pos = pos-pos_base;
763
764        BOOL arrow_1 = FALSE;
765        BOOL arrow_2 = FALSE;
766        pblock->GetValue(node_i+WP_NODE_R0, t, arrow_1, FOREVER);
767        pblock->GetValue(node_i+WP_NODE_B0, t, arrow_2, FOREVER);
768
769        DrawArrow(vpt, delta_pos.x, delta_pos.y, delta_pos.z, size, arrow_1, arrow_2);
770      }
771    }
772  };
773
774
775  if (box)
776  {
777
778    // Make the box half the size
779    size = size * 0.5f;
780
781    // Bottom
782    pts[0] = Point3(-size, -size, -size); 
783    pts[1] = Point3(-size,  size, -size);
784    pts[2] = Point3( size,  size, -size);
785    pts[3] = Point3( size, -size, -size);
786    vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL);
787
788    // Top
789    pts[0] = Point3(-size, -size,  size); 
790    pts[1] = Point3(-size,  size,  size);
791    pts[2] = Point3( size,  size,  size);
792    pts[3] = Point3( size, -size,  size);
793    vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL);
794
795    // Sides
796    pts[0] = Point3(-size, -size, -size); 
797    pts[1] = Point3(-size, -size,  size);
798    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
799
800    pts[0] = Point3(-size,  size, -size); 
801    pts[1] = Point3(-size,  size,  size);
802    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
803
804    pts[0] = Point3( size,  size, -size); 
805    pts[1] = Point3( size,  size,  size);
806    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
807
808    pts[0] = Point3( size, -size, -size); 
809    pts[1] = Point3( size, -size,  size);
810    vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
811  }
812
813  vpt->getGW()->setTransform(tm_base);
814  vpt->getGW()->setRndLimits(limits);
815
816  return 1;
817};
818
819IOResult JointObject::Load(ILoad *iload)
820{
821  //WAYPOINT_CHUNKID
822  return IO_OK;
823};
824
825IOResult JointObject::Save(ISave *isave)
826{
827  //useless
828  //isave->BeginChunk(WAYPOINT_CHUNKID);
829  //isave->EndChunk();
830  return IO_OK;
831};