1
0
forked from 0ad/0ad
0ad/source/tools/pmdexp/PSProp.cpp
2004-05-30 00:46:58 +00:00

925 lines
23 KiB
C++
Executable File

/**********************************************************************
*<
FILE: pthelp.cpp
DESCRIPTION: A point helper implementation
CREATED BY:
HISTORY: created 14 July 1995
*> Copyright (c) 1995, All Rights Reserved.
**********************************************************************/
#include "PSProp.h"
//------------------------------------------------------
// in prim.cpp - The dll instance handle
extern HINSTANCE hInstance;
#define AXIS_LENGTH 20.0f
#define ZFACT (float).005;
void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect);
void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize);
Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM);
//////////////////////////////////////////////////////////////////////////////////////
// PSPropClassDesc : required class to expose PSProp to MAX
class PSPropClassDesc : public ClassDesc2
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new PSPropObject; }
const TCHAR * ClassName() { return GetString(IDS_DB_POINT_CLASS); }
SClass_ID SuperClassID() { return HELPER_CLASS_ID; }
Class_ID ClassID() { return PSPROP_CLASS_ID; }
const TCHAR* Category() { return _T("PS Helpers"); }
const TCHAR* InternalName() {return _T("PSProp");}
HINSTANCE HInstance() {return hInstance;}
};
PSPropClassDesc pointHelpObjDesc;
ClassDesc* GetPSPropDesc() { return &pointHelpObjDesc; }
// class variable for point class.
IObjParam *PSPropObject::ip = NULL;
PSPropObject *PSPropObject::editOb = NULL;
//HWND PSPropObject::hParams = NULL;
//IObjParam *PSPropObject::iObjParams;
//int PSPropObject::dlgShowAxis = TRUE;
//float PSPropObject::dlgAxisLength = AXIS_LENGTH;
void resetPointParams()
{
//PSPropObject::dlgShowAxis = TRUE;
//PSPropObject::dlgAxisLength = AXIS_LENGTH;
}
#define PBLOCK_REF_NO 0
// The following two enums are transfered to the istdplug.h by AG: 01/20/2002
// in order to access the parameters for use in Spline IK Control modifier
// and the Spline IK Solver
// block IDs
//enum { pointobj_params, };
// pointobj_params IDs
// enum {
// pointobj_size, pointobj_centermarker, pointobj_axistripod,
// pointobj_cross, pointobj_box, pointobj_screensize, pointobj_drawontop };
// per instance block
static ParamBlockDesc2 pointobj_param_blk(
pointobj_params, _T("PointObjectParameters"), 0, &pointHelpObjDesc, P_AUTO_CONSTRUCT+P_AUTO_UI, PBLOCK_REF_NO,
//rollout
IDD_NEW_POINTPARAM, IDS_POINT_PARAMS, 0, 0, NULL,
// params
pointobj_size, _T("size"), TYPE_FLOAT, P_ANIMATABLE, IDS_POINT_SIZE,
p_default, 20.0,
p_ms_default, 20.0,
p_range, 0.0f, float(1.0E30),
p_ui, TYPE_SPINNER, EDITTYPE_UNIVERSE, IDC_POINT_SIZE, IDC_POINT_SIZESPIN, SPIN_AUTOSCALE,
end,
pointobj_centermarker, _T("centermarker"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CENTERMARKER,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_MARKER,
end,
pointobj_axistripod, _T("axistripod"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_AXISTRIPOD,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_AXIS,
end,
pointobj_cross, _T("cross"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CROSS,
p_default, TRUE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_CROSS,
end,
pointobj_box, _T("box"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_BOX,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_BOX,
end,
pointobj_screensize, _T("constantscreensize"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_SCREENSIZE,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_SCREENSIZE,
end,
pointobj_drawontop, _T("drawontop"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_DRAWONTOP,
p_default, FALSE,
p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_DRAWONTOP,
end,
end
);
/*
INT_PTR CALLBACK PointParamProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
PSPropObject *po = (PSPropObject*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
if (!po && msg!=WM_INITDIALOG) return FALSE;
switch (msg) {
case WM_INITDIALOG: {
po = (PSPropObject*)lParam;
SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
CheckDlgButton(hWnd,IDC_SHOWAXIS,po->showAxis);
ISpinnerControl *spin =
GetISpinner(GetDlgItem(hWnd,IDC_AXISLENGHSPIN));
spin->SetLimits(10,1000,FALSE);
spin->SetScale(0.1f);
spin->SetValue(po->axisLength,FALSE);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_AXISLENGTH),EDITTYPE_FLOAT);
ReleaseISpinner(spin);
return FALSE;
}
case CC_SPINNER_CHANGE: {
ISpinnerControl *spin = (ISpinnerControl*)lParam;
po->axisLength = spin->GetFVal();
po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE);
po->iObjParams->RedrawViews(po->iObjParams->GetTime());
break;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_SHOWAXIS:
po->showAxis = IsDlgButtonChecked(hWnd,IDC_SHOWAXIS);
po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE);
po->iObjParams->RedrawViews(po->iObjParams->GetTime());
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
*/
void PSPropObject::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editOb = this;
pointHelpObjDesc.BeginEditParams(ip, this, flags, prev);
/*
iObjParams = ip;
if (!hParams) {
hParams = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_POINTPARAM),
PointParamProc,
GetString(IDS_DB_PARAMETERS),
(LPARAM)this );
ip->RegisterDlgWnd(hParams);
} else {
SetWindowLongPtr(hParams,GWLP_USERDATA,(LONG_PTR)this);
CheckDlgButton(hParams,IDC_SHOWAXIS,showAxis);
ISpinnerControl *spin =
GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN));
spin->SetValue(axisLength,FALSE);
ReleaseISpinner(spin);
}
*/
}
void PSPropObject::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
editOb = NULL;
this->ip = NULL;
pointHelpObjDesc.EndEditParams(ip, this, flags, next);
ClearAFlag(A_OBJ_CREATING);
/*
dlgShowAxis = IsDlgButtonChecked(hParams, IDC_SHOWAXIS );
ISpinnerControl *spin = GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN));
dlgAxisLength = spin->GetFVal();
ReleaseISpinner(spin);
if (flags&END_EDIT_REMOVEUI) {
ip->UnRegisterDlgWnd(hParams);
ip->DeleteRollupPage(hParams);
hParams = NULL;
} else {
SetWindowLongPtr(hParams,GWLP_USERDATA,0);
}
iObjParams = NULL;
*/
}
PSPropObject::PSPropObject()
{
pointHelpObjDesc.MakeAutoParamBlocks(this);
showAxis = TRUE; //dlgShowAxis;
axisLength = 10.0f; //dlgAxisLength;
suspendSnap = FALSE;
SetAFlag(A_OBJ_CREATING);
}
PSPropObject::~PSPropObject()
{
DeleteAllRefsFromMe();
}
IParamArray *PSPropObject::GetParamBlock()
{
return (IParamArray*)pblock2;
}
int PSPropObject::GetParamBlockIndex(int id)
{
if (pblock2 && id>=0 && id<pblock2->NumParams()) return id;
else return -1;
}
class PointHelpObjCreateCallBack: public CreateMouseCallBack {
PSPropObject *ob;
public:
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
void SetObj(PSPropObject *obj) { ob = obj; }
};
int PointHelpObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) {
#ifdef _OSNAP
if (msg == MOUSE_FREEMOVE)
{
#ifdef _3D_CREATE
vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);
#else
vpt->SnapPreview(m,m,NULL, SNAP_IN_PLANE);
#endif
}
#endif
if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
switch(point) {
case 0: {
// Find the node and plug in the wire color
ULONG handle;
ob->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE);
INode *node;
node = GetCOREInterface()->GetINodeByHandle(handle);
if (node) {
Point3 color(0,0,1);// = GetUIColor(COLOR_POINT_OBJ);
node->SetWireColor(RGB(color.x*255.0f, color.y*255.0f, color.z*255.0f));
}
ob->suspendSnap = TRUE;
#ifdef _3D_CREATE
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));
#else
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
#endif
break;
}
case 1:
#ifdef _3D_CREATE
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D));
#else
mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
#endif
if (msg==MOUSE_POINT) {
ob->suspendSnap = FALSE;
return 0;
}
break;
}
} else
if (msg == MOUSE_ABORT) {
return CREATE_ABORT;
}
return 1;
}
static PointHelpObjCreateCallBack pointHelpCreateCB;
CreateMouseCallBack* PSPropObject::GetCreateMouseCallBack() {
pointHelpCreateCB.SetObj(this);
return(&pointHelpCreateCB);
}
void PSPropObject::SetExtendedDisplay(int flags)
{
extDispFlags = flags;
}
void PSPropObject::GetLocalBoundBox(
TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
{
Matrix3 tm = inode->GetObjectTM(t);
float size;
int screenSize;
pblock2->GetValue(pointobj_size, t, size, FOREVER);
pblock2->GetValue(pointobj_screensize, t, screenSize, FOREVER);
float zoom = 1.0f;
if (screenSize) {
zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT;
}
if (zoom==0.0f) zoom = 1.0f;
size *= zoom;
box = Box3(Point3(0,0,0), Point3(0,0,0));
box += Point3(size*0.5f, 0.0f, 0.0f);
box += Point3( 0.0f, size*0.5f, 0.0f);
box += Point3( 0.0f, 0.0f, size*0.5f);
box += Point3(-size*0.5f, 0.0f, 0.0f);
box += Point3( 0.0f, -size*0.5f, 0.0f);
box += Point3( 0.0f, 0.0f, -size*0.5f);
box.EnlargeBy(10.0f/zoom);
/*
if (showAxis)
box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, TRUE);
else
box = Box3(Point3(0,0,0), Point3(0,0,0));
*/
}
void PSPropObject::GetWorldBoundBox(
TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
{
Matrix3 tm;
tm = inode->GetObjectTM(t);
Box3 lbox;
GetLocalBoundBox(t, inode, vpt, lbox);
box = Box3(tm.GetTrans(), tm.GetTrans());
for (int i=0; i<8; i++) {
box += lbox * tm;
}
/*
if(!(extDispFlags & EXT_DISP_ZOOM_EXT) && showAxis)
box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, FALSE);
else
box = Box3(tm.GetTrans(), tm.GetTrans());
*/
}
void PSPropObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt)
{
if(suspendSnap)
return;
Matrix3 tm = inode->GetObjectTM(t);
GraphicsWindow *gw = vpt->getGW();
gw->setTransform(tm);
Matrix3 invPlane = Inverse(snap->plane);
// Make sure the vertex priority is active and at least as important as the best snap so far
if(snap->vertPriority > 0 && snap->vertPriority <= snap->priority) {
Point2 fp = Point2((float)p->x, (float)p->y);
Point2 screen2;
IPoint3 pt3;
Point3 thePoint(0,0,0);
// If constrained to the plane, make sure this point is in it!
if(snap->snapType == SNAP_2D || snap->flags & SNAP_IN_PLANE) {
Point3 test = thePoint * tm * invPlane;
if(fabs(test.z) > 0.0001) // Is it in the plane (within reason)?
return;
}
gw->wTransPoint(&thePoint,&pt3);
screen2.x = (float)pt3.x;
screen2.y = (float)pt3.y;
// Are we within the snap radius?
int len = (int)Length(screen2 - fp);
if(len <= snap->strength) {
// Is this priority better than the best so far?
if(snap->vertPriority < snap->priority) {
snap->priority = snap->vertPriority;
snap->bestWorld = thePoint * tm;
snap->bestScreen = screen2;
snap->bestDist = len;
}
else
if(len < snap->bestDist) {
snap->priority = snap->vertPriority;
snap->bestWorld = thePoint * tm;
snap->bestScreen = screen2;
snap->bestDist = len;
}
}
}
}
int PSPropObject::DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt)
{
float size;
int centerMarker, axisTripod, cross, box, screenSize, drawOnTop;
// Color color = inode->GetWireColor();
Interval ivalid = FOREVER;
pblock2->GetValue(pointobj_size, t, size, ivalid);
pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid);
pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid);
pblock2->GetValue(pointobj_cross, t, cross, ivalid);
pblock2->GetValue(pointobj_box, t, box, ivalid);
pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid);
pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid);
Matrix3 tm(1);
Point3 pt(0,0,0);
Point3 pts[5];
vpt->getGW()->setTransform(tm);
tm = inode->GetObjectTM(t);
int limits = vpt->getGW()->getRndLimits();
if (drawOnTop) vpt->getGW()->setRndLimits(limits & ~GW_Z_BUFFER);
if (inode->Selected()) {
vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_SELECTION) );
vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_SELECTION) );
} else if (!inode->IsFrozen() && !inode->Dependent()) {
//vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_POINT_AXES) );
//vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_POINT_AXES) );
vpt->getGW()->setColor( TEXT_COLOR, Color(0,0,1));
vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1));
}
if (axisTripod) {
DrawAxis(vpt, tm, size, screenSize);
}
size *= 0.5f;
float zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT;
if (screenSize) {
tm.Scale(Point3(zoom,zoom,zoom));
}
vpt->getGW()->setTransform(tm);
if (!inode->IsFrozen() && !inode->Dependent() && !inode->Selected()) {
//vpt->getGW()->setColor(LINE_COLOR, GetUIColor(COLOR_POINT_OBJ));
vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1));
}
if (centerMarker) {
vpt->getGW()->marker(&pt,X_MRKR);
}
if (cross) {
// X
pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
// Y
pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, size, 0.0f);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
// Z
pts[0] = Point3(0.0f, 0.0f, -size); pts[1] = Point3(0.0f, 0.0f, size);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
}
if (box) {
// Make the box half the size
size = size * 0.5f;
// Bottom
pts[0] = Point3(-size, -size, -size);
pts[1] = Point3(-size, size, -size);
pts[2] = Point3( size, size, -size);
pts[3] = Point3( size, -size, -size);
vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL);
// Top
pts[0] = Point3(-size, -size, size);
pts[1] = Point3(-size, size, size);
pts[2] = Point3( size, size, size);
pts[3] = Point3( size, -size, size);
vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL);
// Sides
pts[0] = Point3(-size, -size, -size);
pts[1] = Point3(-size, -size, size);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
pts[0] = Point3(-size, size, -size);
pts[1] = Point3(-size, size, size);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
pts[0] = Point3( size, size, -size);
pts[1] = Point3( size, size, size);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
pts[0] = Point3( size, -size, -size);
pts[1] = Point3( size, -size, size);
vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);
}
vpt->getGW()->setRndLimits(limits);
return 1;
}
int PSPropObject::HitTest(
TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt)
{
Matrix3 tm(1);
HitRegion hitRegion;
DWORD savedLimits;
Point3 pt(0,0,0);
vpt->getGW()->setTransform(tm);
GraphicsWindow *gw = vpt->getGW();
Material *mtl = gw->getMaterial();
tm = inode->GetObjectTM(t);
MakeHitRegion(hitRegion, type, crossing, 4, p);
gw->setRndLimits(((savedLimits = gw->getRndLimits())|GW_PICK)&~GW_ILLUM);
gw->setHitRegion(&hitRegion);
gw->clearHitCode();
DrawAndHit(t, inode, vpt);
/*
if (showAxis) {
DrawAxis(vpt,tm,axisLength,screenSize);
}
vpt->getGW()->setTransform(tm);
vpt->getGW()->marker(&pt,X_MRKR);
*/
gw->setRndLimits(savedLimits);
if((hitRegion.type != POINT_RGN) && !hitRegion.crossing)
return TRUE;
return gw->checkHitCode();
}
int PSPropObject::Display(
TimeValue t, INode* inode, ViewExp *vpt, int flags)
{
DrawAndHit(t, inode, vpt);
/*
Matrix3 tm(1);
Point3 pt(0,0,0);
vpt->getGW()->setTransform(tm);
tm = inode->GetObjectTM(t);
if (showAxis) {
DrawAxis(vpt,tm,axisLength,inode->Selected(),inode->IsFrozen());
}
vpt->getGW()->setTransform(tm);
if(!inode->IsFrozen())
vpt->getGW()->setColor(LINE_COLOR,GetUIColor(COLOR_POINT_OBJ));
vpt->getGW()->marker(&pt,X_MRKR);
*/
return(0);
}
//
// Reference Managment:
//
// This is only called if the object MAKES references to other things.
RefResult PSPropObject::NotifyRefChanged(
Interval changeInt, RefTargetHandle hTarget,
PartID& partID, RefMessage message )
{
switch (message) {
case REFMSG_CHANGE:
if (editOb==this) InvalidateUI();
break;
}
return(REF_SUCCEED);
}
void PSPropObject::InvalidateUI()
{
pointobj_param_blk.InvalidateUI(pblock2->LastNotifyParamID());
}
Interval PSPropObject::ObjectValidity(TimeValue t)
{
float size;
int centerMarker, axisTripod, cross, box, screenSize, drawOnTop;
Interval ivalid = FOREVER;
pblock2->GetValue(pointobj_size, t, size, ivalid);
pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid);
pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid);
pblock2->GetValue(pointobj_cross, t, cross, ivalid);
pblock2->GetValue(pointobj_box, t, box, ivalid);
pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid);
pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid);
return ivalid;
}
ObjectState PSPropObject::Eval(TimeValue t)
{
return ObjectState(this);
}
RefTargetHandle PSPropObject::Clone(RemapDir& remap)
{
PSPropObject* newob = new PSPropObject();
newob->showAxis = showAxis;
newob->axisLength = axisLength;
newob->ReplaceReference(0, pblock2->Clone(remap));
BaseClone(this, newob, remap);
return(newob);
}
void PSPropObject::UpdateParamblockFromVars()
{
SuspendAnimate();
AnimateOff();
pblock2->SetValue(pointobj_size, TimeValue(0), axisLength);
pblock2->SetValue(pointobj_centermarker, TimeValue(0), TRUE);
pblock2->SetValue(pointobj_axistripod, TimeValue(0), showAxis);
pblock2->SetValue(pointobj_cross, TimeValue(0), FALSE);
pblock2->SetValue(pointobj_box, TimeValue(0), FALSE);
pblock2->SetValue(pointobj_screensize, TimeValue(0), TRUE);
ResumeAnimate();
}
class PointHelperPostLoadCallback : public PostLoadCallback {
public:
PSPropObject *pobj;
PointHelperPostLoadCallback(PSPropObject *p) {pobj=p;}
void proc(ILoad *iload) {
pobj->UpdateParamblockFromVars();
}
};
#define SHOW_AXIS_CHUNK 0x0100
#define AXIS_LENGTH_CHUNK 0x0110
#define POINT_HELPER_R4_CHUNKID 0x0120 // new version of point helper for R4 (updated to use PB2)
IOResult PSPropObject::Load(ILoad *iload)
{
ULONG nb;
IOResult res = IO_OK;
BOOL oldVersion = TRUE;
while (IO_OK==(res=iload->OpenChunk())) {
switch (iload->CurChunkID()) {
case SHOW_AXIS_CHUNK:
res = iload->Read(&showAxis,sizeof(showAxis),&nb);
break;
case AXIS_LENGTH_CHUNK:
res = iload->Read(&axisLength,sizeof(axisLength),&nb);
break;
case POINT_HELPER_R4_CHUNKID:
oldVersion = FALSE;
break;
}
res = iload->CloseChunk();
if (res!=IO_OK) return res;
}
if (oldVersion) {
iload->RegisterPostLoadCallback(new PointHelperPostLoadCallback(this));
}
return IO_OK;
}
IOResult PSPropObject::Save(ISave *isave)
{
/*
isave->BeginChunk(SHOW_AXIS_CHUNK);
isave->Write(&showAxis,sizeof(showAxis),&nb);
isave->EndChunk();
isave->BeginChunk(AXIS_LENGTH_CHUNK);
isave->Write(&axisLength,sizeof(axisLength),&nb);
isave->EndChunk();
*/
isave->BeginChunk(POINT_HELPER_R4_CHUNKID);
isave->EndChunk();
return IO_OK;
}
/*--------------------------------------------------------------------*/
//
// Stole this from scene.cpp
// Probably couldn't hurt to make an API...
//
//
void Text( ViewExp *vpt, TCHAR *str, Point3 &pt )
{
vpt->getGW()->text( &pt, str );
}
static void DrawAnAxis( ViewExp *vpt, Point3 axis )
{
Point3 v1, v2, v[3];
v1 = axis * (float)0.9;
if ( axis.x != 0.0 || axis.y != 0.0 ) {
v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1;
} else {
v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1;
}
v[0] = Point3(0.0,0.0,0.0);
v[1] = axis;
vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL );
v[0] = axis;
v[1] = v1+v2;
vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL );
v[0] = axis;
v[1] = v1-v2;
vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL );
}
void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize)
{
Matrix3 tmn = tm;
float zoom;
// Get width of viewport in world units: --DS
zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
if (screenSize) {
tmn.Scale( Point3(zoom,zoom,zoom) );
}
vpt->getGW()->setTransform( tmn );
Text( vpt, _T("x"), Point3(length,0.0f,0.0f) );
DrawAnAxis( vpt, Point3(length,0.0f,0.0f) );
Text( vpt, _T("y"), Point3(0.0f,length,0.0f) );
DrawAnAxis( vpt, Point3(0.0f,length,0.0f) );
Text( vpt, _T("z"), Point3(0.0f,0.0f,length) );
DrawAnAxis( vpt, Point3(0.0f,0.0f,length) );
}
//--- RB 7/17/2000: the code below seems to be unused ---------------------------------------------------
Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM)
{
Matrix3 tmn = tm;
Box3 box;
float zoom;
// Get width of viewport in world units: --DS
zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
if (zoom==0.0f) zoom = 1.0f;
// tmn.Scale(Point3(zoom,zoom,zoom));
length *= zoom;
if(resetTM)
tmn.IdentityMatrix();
box += Point3(0.0f,0.0f,0.0f) * tmn;
box += Point3(length,0.0f,0.0f) * tmn;
box += Point3(0.0f,length,0.0f) * tmn;
box += Point3(0.0f,0.0f,length) * tmn;
box += Point3(-length/5.f,0.0f,0.0f) * tmn;
box += Point3(0.0f,-length/5.f,0.0f) * tmn;
box += Point3(0.0f,0.0f,-length/5.0f) * tmn;
box.EnlargeBy(10.0f/zoom);
return box;
}
inline void EnlargeRectIPoint3( RECT *rect, IPoint3& pt )
{
if ( pt.x < rect->left ) rect->left = pt.x;
if ( pt.x > rect->right ) rect->right = pt.x;
if ( pt.y < rect->top ) rect->top = pt.y;
if ( pt.y > rect->bottom ) rect->bottom = pt.y;
}
// This is a guess - need to find real w/h.
#define FONT_HEIGHT 11
#define FONT_WIDTH 9
static void AxisRect( GraphicsWindow *gw, Point3 axis, Rect *rect )
{
Point3 v1, v2, v;
IPoint3 iv;
v1 = axis * (float)0.9;
if ( axis.x != 0.0 || axis.y != 0.0 ) {
v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1;
} else {
v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1;
}
v = axis;
gw->wTransPoint( &v, &iv );
EnlargeRectIPoint3( rect, iv);
iv.x += FONT_WIDTH;
iv.y -= FONT_HEIGHT;
EnlargeRectIPoint3( rect, iv);
v = v1+v2;
gw->wTransPoint( &v, &iv );
EnlargeRectIPoint3( rect, iv);
v = v1-v2;
gw->wTransPoint( &v, &iv );
EnlargeRectIPoint3( rect, iv);
}
void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect)
{
Matrix3 tmn = tm;
float zoom;
IPoint3 wpt;
Point3 pt;
GraphicsWindow *gw = vpt->getGW();
// Get width of viewport in world units: --DS
zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
tmn.Scale( Point3(zoom,zoom,zoom) );
gw->setTransform( tmn );
pt = Point3(0.0f, 0.0f, 0.0f);
gw->wTransPoint( &pt, &wpt );
rect->left = rect->right = wpt.x;
rect->top = rect->bottom = wpt.y;
AxisRect( gw, Point3(length,0.0f,0.0f),rect );
AxisRect( gw, Point3(0.0f,length,0.0f),rect );
AxisRect( gw, Point3(0.0f,0.0f,length),rect );
rect->right += 2;
rect->bottom += 2;
rect->left -= 2;
rect->top -= 2;
}