diff --git a/Makefile b/Makefile index 3cafb8e..09a502b 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ RES = $(OBJDIR)\resource.res LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib opengl32.lib glu32.lib \ - extlib\libpng.lib extlib\zlib.lib + extlib\libpng.lib extlib\zlib.lib extlib\si\siapp.lib all: $(OBJDIR)/solvespace.exe @cp $(OBJDIR)/solvespace.exe . diff --git a/draw.cpp b/draw.cpp index fc349fa..ba8b930 100644 --- a/draw.cpp +++ b/draw.cpp @@ -269,6 +269,75 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, havePainted = false; } +void GraphicsWindow::SpaceNavigatorMoved(double tx, double ty, double tz, + double rx, double ry, double rz, + bool shiftDown) +{ + if(!havePainted) return; + Vector out = projRight.Cross(projUp); + + // rotation vector is axis of rotation, and its magnitude is angle + Vector aa = Vector::From(rx, ry, rz); + // but it's given with respect to screen projection frame + aa = aa.ScaleOutOfCsys(projRight, projUp, out); + double aam = aa.Magnitude(); + aa = aa.WithMagnitude(1); + + // This can either transform our view, or transform an imported part. + GroupSelection(); + Entity *e = NULL; + Group *g = NULL; + if(gs.points == 1 && gs.n == 1) e = SK.GetEntity(gs.point [0]); + if(gs.entities == 1 && gs.n == 1) e = SK.GetEntity(gs.entity[0]); + if(e) g = SK.GetGroup(e->group); + if(g && g->type == Group::IMPORTED && !shiftDown) { + // Apply the transformation to an imported part. + Vector t = projRight.ScaledBy(tx).Plus( + projUp .ScaledBy(ty).Plus( + out .ScaledBy(tz))); + Quaternion q = Quaternion::From(aa, aam); + + // If we go five seconds without SpaceNavigator input, or if we've + // switched groups, then consider that a new action and save an undo + // point. + SDWORD now = GetMilliseconds(); + if(now - lastSpaceNavigatorTime > 5000 || + lastSpaceNavigatorGroup.v != g->h.v) + { + SS.UndoRemember(); + } + + g->TransformImportedBy(t, q); + + lastSpaceNavigatorTime = now; + lastSpaceNavigatorGroup = g->h; + SS.MarkGroupDirty(g->h); + SS.later.generateAll = true; + } else { + // Apply the transformation to the view of the everything. The + // x and y components are translation; but z component is scale, + // not translation, or else it would do nothing in a parallel + // projection + offset = offset.Plus(projRight.ScaledBy(tx)); + offset = offset.Plus(projUp.ScaledBy(ty)); + scale *= exp(0.01*tz); + + if(aam != 0.0) { + projRight = projRight.RotatedAbout(aa, -aam); + projUp = projUp. RotatedAbout(aa, -aam); + NormalizeProjectionVectors(); + } + } + + havePainted = false; + InvalidateGraphics(); +} + +void GraphicsWindow::SpaceNavigatorButtonUp(void) { + ZoomToFit(false); + InvalidateGraphics(); +} + void GraphicsWindow::ClearPending(void) { memset(&pending, 0, sizeof(pending)); } diff --git a/extlib/si/si.h b/extlib/si/si.h new file mode 100644 index 0000000..04aaf9b --- /dev/null +++ b/extlib/si/si.h @@ -0,0 +1,373 @@ +/*---------------------------------------------------------------------- + * si.h -- SpaceWare input library header + * + * $Id: si.h,v 1.22 1998/03/12 11:07:03 mfarr Exp $ + * + * SpaceWare input library + * + *---------------------------------------------------------------------- + * + * (C) 1998-2001 3Dconnexion. All rights reserved. + * Permission to use, copy, modify, and distribute this software for all + * purposes and without fees is hereby grated provided that this copyright + * notice appears in all copies. Permission to modify this software is granted + * and 3Dconnexion will support such modifications only is said modifications are + * approved by 3Dconnexion. + * + */ + + +#ifndef _SI_H_ +#define _SI_H_ + +static char incFileNameCvsId[]="(C) 1996 Spacetec IMC Corporation: $Id: si.h,v 1.22 1998/03/12 11:07:03 mfarr Exp $"; + +#include + +#include "spwmacro.h" +#include "spwdata.h" +#include "siSync.h" + +#include +#include "spwerror.h" + +/* + * UI modes + */ +#define SI_UI_ALL_CONTROLS 0xffffffffL +#define SI_UI_NO_CONTROLS 0x00000000L + +/* + * These UI modes are left here for legacy applications. + */ +#define SI_UI_FILTERS 0x00000001L +#define SI_UI_FUNC_BUTTONS 0x00000002L +#define SI_UI_RESET_BUTTONS 0x00000004L +#define SI_UI_SENSITIVITY 0x00000008L +#define SI_UI_TUNING 0x00000010L +#define SI_UI_DIALOG_POPUP 0x00000020L + +/* + * Device types and classes + */ +typedef enum + { + SI_ALL_TYPES = -1, + SI_UNKNOWN_DEVICE = 0, + SI_SPACEBALL_2003 = 1, + SI_SPACEBALL_3003 = 2, + SI_SPACE_CONTROLLER = 3, + SI_AVENGER = 4, + SI_SPACEORB_360 = 5, + SI_NAVIGATOR = 6, + SI_SPACEBALL_2003A = 7, + SI_SPACEBALL_2003B = 8, + SI_SPACEBALL_2003C = 9, + SI_SPACEBALL_3003A = 10, + SI_SPACEBALL_3003B = 11, + SI_SPACEBALL_3003C = 12, + SI_SPACEBALL_4000 = 13, + SI_SPACEMOUSE_CLASSIC = 14, + SI_SPACEMOUSE_PLUS = 15, + SI_SPACEMOUSE_XT = 16, + SI_CYBERMAN = 17, + SI_CADMAN = 18, + SI_SPACEMOUSE_CLASSIC_PROMO = 19, + SI_SERIAL_CADMAN = 20, + SI_SPACEBALL_5000 = 21, + SI_TEST_NO_DEVICE = 22, + SI_3DX_KEYBOARD_BLACK = 23, + SI_3DX_KEYBOARD_WHITE = 24, + SI_TRAVELER = 25, + SI_TRAVELER1 = 26, + SI_SPACEBALL_5000A = 27, + SI_SPACEDRAGON = 28, + SI_SPACEPILOT = 29, + SI_NUM_DEV_TYPES /* Leave this last, add before it */ + } SiDevType; + +/* + * These defintions of device classes are left in for legacy applications. + */ +#define SI_HIGH_END 63 +#define SI_MED_END 62 +#define SI_LOW_END 61 + +/* + * Data retrieval mode, only SI_EVENT is currently supported. + */ +#define SI_EVENT 0x0001 +#define SI_POLL 0x0002 + +/* + * Get event flags + */ +#define SI_AVERAGE_EVENTS 0x0001 + +/* + * This is an INTERNAL flag used by the polling mechanism, user applications + * should NOT send this flag. + */ +#define SI_POLLED_REQUEST 0x0100 + +/* + * SpaceWare event types + */ +typedef enum + { + SI_BUTTON_EVENT = 1, + SI_MOTION_EVENT, + SI_COMBO_EVENT, /* Not implemented */ + SI_ZERO_EVENT, + SI_EXCEPTION_EVENT, + SI_OUT_OF_BAND, + SI_ORIENTATION_EVENT, + SI_KEYBOARD_EVENT, + SI_LPFK_EVENT, + SI_APP_EVENT, /* Application functions */ + SI_SYNC_EVENT, /* GUI synchronization events */ + SI_BUTTON_PRESS_EVENT, /* Single button events (replace SI_BUTTON_EVENT) */ + SI_BUTTON_RELEASE_EVENT /* Single button events (replace SI_BUTTON_EVENT) */ + } SiEventType; + +/* + * Data modes + */ +#define SI_MODE_NORMALIZE 0x0001 +#define SI_MODE_COMPRESS 0x0002 +#define SI_MODE_SENSITIVITY 0x0004 +#define SI_MODE_TUNING 0x0008 + +/* + * Motion data offsets + */ +#define SI_TX 0 /* Translation X value */ +#define SI_TY 1 /* Translation Y value */ +#define SI_TZ 2 /* Translation Z value */ +#define SI_RX 3 /* Rotation X value */ +#define SI_RY 4 /* Rotation Y value */ +#define SI_RZ 5 /* Rotation Z value */ + +/* + * Reserved buttons + */ + +#define SI_RESET_DEVICE_BIT 0x00000001L +#define SI_APP_FIT_BIT 0x80000000L +#define SI_APP_DIALOG_BIT 0x40000000L + +#define SI_RESET_DEVICE_BUTTON 0 +#define SI_APP_FIT_BUTTON 31 +#define SI_APP_DIALOG_BUTTON 30 + +/* + * Miscellaneous + */ +#define SI_END_ARGS 0 +#define SI_NO_HANDLE ((SiHdl) NULL) +#define SI_ALL_HANDLES ((SiHdl) NULL) +#define SI_ANY_HANDLE ((SiHdl) NULL) +#define SI_NO_TRANSCTL ((SiTransCtl) NULL) +#define SI_NO_MASK ((SiTypeMask *) NULL) +#define SI_ANY_DEVICE -1 +#define SI_NO_DEVICE -1 +#define SI_NO_TYPE -1 +#define SI_NO_LIST -1 +#define SI_NO_BUTTON -1 +#define SI_STRSIZE 128 +#define SI_MAXBUF 128 +#define SI_KEY_MAXBUF 5120 + +typedef int SiDevID; /* Device ID */ +typedef void *SiHdl; /* SpaceWare handle */ +typedef void *SiTransCtl; /* SpaceWare transport control handle */ + +typedef struct /* Open data */ + { + + HWND hWnd; /* Window handle for SpaceWare messages. */ + SiTransCtl transCtl; /* SpaceWare transport control handle. Reserved */ + /* for the s80 transport mechanism. */ + DWORD processID; /* The process ID for this application. */ + char exeFile[MAX_PATH]; /* The executable name of the process. */ + SPWint32 libFlag; /* Library version flag. */ + } SiOpenData; + +typedef struct /* Get event Data */ + { + + UINT msg; + WPARAM wParam; + LPARAM lParam; + } SiGetEventData; + +typedef struct /* Device type mask */ + { + unsigned char mask[8]; + } SiTypeMask; + +typedef struct /* Device port information */ + { + SiDevID devID; /* Device ID */ + int devType; /* Device type */ + int devClass; /* Device class */ + char devName[SI_STRSIZE]; /* Device name */ + char portName[SI_STRSIZE]; /* Port name */ + } SiDevPort; + +typedef struct /* Device information */ + { + char firmware[SI_STRSIZE]; /* Firmware version */ + int devType; /* Device type */ + int numButtons; /* Number of buttons */ + int numDegrees; /* Number of degrees of freedom */ + SPWbool canBeep; /* Device beeps */ + int majorVersion; /* Major version number */ + int minorVersion; /* Minor version number */ + } SiDevInfo; + +typedef struct /* Button information */ + { + char name[SI_STRSIZE]; /* Contains the name of a button for display in an app's GUI */ + } SiButtonName; + +typedef struct /* Button information */ + { + char name[SI_STRSIZE]; /* Contains the name of a device for display in an app's GUI */ + } SiDeviceName; + +typedef struct /* Version information */ + { + int major; /* Major version number */ + int minor; /* Minor version number */ + int build; /* Build number */ + char version[SI_STRSIZE]; /* Version string */ + char date[SI_STRSIZE]; /* Date string */ + } SiVerInfo; + +typedef struct /* Sensitivity parameters */ + { + char dummy; + } SiSensitivity; + +typedef struct /* Tuning parameters */ + { + char dummy; + } SiTuning; + +typedef struct + { + SPWuint8 code; /* Out of band message code */ + union { + SPWuint8 message[SI_MAXBUF-1]; /* The actual message */ + void *pvoid[SI_MAXBUF/8]; /* void ptrs. Enough room for 64bit ptrs */ + }; + } SiSpwOOB; + +typedef struct + { + SPWuint8 string[SI_KEY_MAXBUF]; /* String for keyboard data */ + } SiKeyboardData; + +typedef struct + { + SPWuint32 lpfk; /* LPFK number to send */ + } SiLpfkData; + +typedef enum + { + SI_LEFT = 0, + SI_RIGHT + } SiOrientation; + +typedef struct /* Bitmasks of button states */ + { + SPWuint32 last; /* Buttons pressed as of last event */ + SPWuint32 current; /* Buttons pressed as of this event */ + SPWuint32 pressed; /* Buttons pressed this event */ + SPWuint32 released; /* Buttons released this event */ + } SiButtonData; + +/* + * SI_BUTTON_PRESS_EVENT & SI_BUTTON_RELEASE_EVENT are hardware button + * events. Meaning that they are meant to be sent when a specific hardware + * button is pressed. The correlation between the actual hardware button + * and the resulting button number could be broken by careful editing of + * a config file, but it is intended that the correlation be intact. + * This is basically the same as SI_BUTTON_EVENT, but allows + * more than 29 buttons because it isn't limited to a 32-bit mask. + * Different entries in the config file determine whether SI_BUTTON_PRESS/RELEASE_EVENTs + * or SI_BUTTON_EVENTs will be generated. + * This event was introduced in 3DxWare 5.2. + */ +typedef struct /* Data for SI_BUTTON_PRESS/RELEASE_EVENT */ + { + SPWuint32 buttonNumber; /* The button number that went down/up in a * + * SI_BUTTON_PRESS/RELEASE_EVENT event */ + } SiHWButtonData; + +typedef struct /* Data for SI_APP_EVENT */ + { + SPWuint32 functionNumber; /* The Application-specific function number + * invoked by the user in a SI_APP_EVENT */ + } SiAppEventData; + +typedef struct /* SpaceWare data */ + { + SiButtonData bData; /* Button data */ + long mData[6]; /* Motion data (index via SI_TX, etc) */ + long period; /* Period (milliseconds) */ + } SiSpwData; + +typedef struct /* SpaceWare event */ + { + int type; /* Event type */ + union + { + SiSpwData spwData; /* Button, motion, or combo data */ + SiSpwOOB spwOOB; /* Out of band message */ + SiOrientation spwOrientation;/* Which hand orientation is the device */ + char exData[SI_MAXBUF]; /* Exception data */ + SiKeyboardData spwKeyData; /* String for keyboard data */ + SiLpfkData spwLpfkData; /* LPFK data */ + SiSyncPacket siSyncPacket; /* GUI SyncPacket sent to applications */ + SiHWButtonData hwButtonEvent;/* ButtonNumber that goes with * + * SI_BUTTON_PRESS/RELEASE_EVENT */ + SiAppEventData appEventData; /* Application event function data that * + * goes with an SI_APP_EVENT event */ + } u; + } SiSpwEvent; + +typedef struct /* Event handler (for SiDispatch) */ + { + int (*func) (SiOpenData *, SiGetEventData *, SiSpwEvent *, void *); + void *data; + } SiEventHandler; + +typedef struct /* SpaceWare event handlers */ + { + SiEventHandler button; /* Button event handler */ + SiEventHandler motion; /* Motion event handler */ + SiEventHandler combo; /* Combo event handler */ + SiEventHandler zero; /* Zero event handler */ + SiEventHandler exception; /* Exception event handler */ + } SiSpwHandlers; + +#ifdef __cplusplus +extern "C" { +#endif + + +enum SpwRetVal SiAndTypeMask (SiTypeMask *pTMaskA, SiTypeMask *pTMaskB); +int SiGetPortList (SiDevPort **ppPort); +void SiFreePortList (SiDevPort *pPort); +void SiTune2003 (SiSpwEvent *pEvent); +void SiTuneSC (SiSpwEvent *pEvent); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _SI_H_ */ diff --git a/extlib/si/siSync.h b/extlib/si/siSync.h new file mode 100644 index 0000000..174f6a3 --- /dev/null +++ b/extlib/si/siSync.h @@ -0,0 +1,206 @@ +/*---------------------------------------------------------------------- + * siSync.h -- 3DxWare GUI Synchronization header + * + * Written: September 2004 + * Author: Jim Wick + * + *---------------------------------------------------------------------- + * + * (c) 1998-2005 3Dconnexion. All rights reserved. + * Permission to use, copy, modify, and distribute this software for all + * purposes and without fees is hereby grated provided that this copyright + * notice appears in all copies. Permission to modify this software is granted + * and 3Dconnexion will support such modifications only is said modifications are + * approved by 3Dconnexion. + * + */ + + +#ifndef _SISYNC_H_ +#define _SISYNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Constants + */ +#define SI_SYNC_PACKET_ID 27711 +#define SI_SYNC_VERSION_MAJOR 1 +#define SI_SYNC_VERSION_MINOR 0 + + +/* + * Absolute Internal Function Numbers + * These are function numbers that will never change. + * For use with Set BUTTON_ASSIGNMENT_ABSOLUTE packets, and some INVOKE items. + * Some functions (keys) can not be INVOKED because there is a separate + * press and release and that difference is not exposed. + */ +typedef enum +{ + SI_SYNC_FUNCTION_MENU_TOGGLE = 12, + SI_SYNC_FUNCTION_TRANS_TOGGLE = 13, + SI_SYNC_FUNCTION_ROT_TOGGLE = 14, + SI_SYNC_FUNCTION_HPV_TOGGLE = 15, + SI_SYNC_FUNCTION_DEC_SENS = 16, + SI_SYNC_FUNCTION_INC_SENS = 17, + SI_SYNC_FUNCTION_RESTORE_DEF = 18, + SI_SYNC_FUNCTION_PAN = 19, + SI_SYNC_FUNCTION_ZOOM = 20, + SI_SYNC_FUNCTION_TX = 21, + SI_SYNC_FUNCTION_TY = 22, + SI_SYNC_FUNCTION_TZ = 23, + SI_SYNC_FUNCTION_RX = 24, + SI_SYNC_FUNCTION_RY = 25, + SI_SYNC_FUNCTION_RZ = 26, + SI_SYNC_FUNCTION_REZERO_DEVICE = 27, + SI_SYNC_FUNCTION_SAVE = 33, + SI_SYNC_FUNCTION_RELOAD = 57, + SI_SYNC_FUNCTION_SHIFT_KEY = 60, + SI_SYNC_FUNCTION_CTRL_KEY = 61, + SI_SYNC_FUNCTION_ALT_KEY = 62, + SI_SYNC_FUNCTION_RESTORE_SENS = 63, + SI_SYNC_FUNCTION_SPACE_KEY = 64, + SI_SYNC_FUNCTION_CTRL_SHIFT_KEY = 65, + SI_SYNC_FUNCTION_CTRL_ALT_KEY = 66, + SI_SYNC_FUNCTION_SHIFT_ALT_KEY = 67, + SI_SYNC_FUNCTION_TAB_KEY = 68, + SI_SYNC_FUNCTION_RETURN_KEY = 69, + SI_SYNC_FUNCTION_DEC_TRANS_SENS = 70, + SI_SYNC_FUNCTION_INC_TRANS_SENS = 71, + SI_SYNC_FUNCTION_DEC_ROT_SENS = 72, + SI_SYNC_FUNCTION_INC_ROT_SENS = 73, + SI_SYNC_FUNCTION_DEC_PAN_SENS = 74, + SI_SYNC_FUNCTION_INC_PAN_SENS = 75, + SI_SYNC_FUNCTION_DEC_ZOOM_SENS = 76, + SI_SYNC_FUNCTION_INC_ZOOM_SENS = 77, + SI_SYNC_FUNCTION_ESC_KEY = 78, + SI_SYNC_FUNCTION_3DX_HELP = 94, + SI_SYNC_FUNCTION_APP_HELP = 95, + SI_SYNC_FUNCTION_DIALOG_TOGGLE_FN= 96, + SI_SYNC_FUNCTION_FIT_FN = 97 +} SiSyncAbsFunctionNumber; + + +/* + * Sync Op Codes + */ +typedef enum + { + SI_SYNC_OP_COMMAND = 1, + SI_SYNC_OP_GET = 2, + SI_SYNC_OP_SET = 3 + } SiSyncOpCode; + +/* + * Sync Item Codes + */ +typedef enum +{ + SI_SYNC_ITEM_VERSION = 1, + SI_SYNC_ITEM_QUERY = 2, + SI_SYNC_ITEM_SAVE_CONFIG = 3, + SI_SYNC_ITEM_NUMBER_OF_FUNCTIONS = 4, + SI_SYNC_ITEM_FUNCTION = 5, + SI_SYNC_ITEM_BUTTON_ASSIGNMENT = 6, + SI_SYNC_ITEM_BUTTON_ASSIGNMENT_ABSOLUTE = 7, + SI_SYNC_ITEM_BUTTON_NAME = 8, + SI_SYNC_ITEM_AXIS_LABEL = 9, + SI_SYNC_ITEM_ORIENTATION = 10, + SI_SYNC_ITEM_FILTER = 11, + SI_SYNC_ITEM_AXES_STATE = 12, + SI_SYNC_ITEM_INFO_LINE = 13, + SI_SYNC_ITEM_SCALE_OVERALL = 14, + SI_SYNC_ITEM_SCALE_TX = 15, + SI_SYNC_ITEM_SCALE_TY = 16, + SI_SYNC_ITEM_SCALE_TZ = 17, + SI_SYNC_ITEM_SCALE_RX = 18, + SI_SYNC_ITEM_SCALE_RY = 19, + SI_SYNC_ITEM_SCALE_RZ = 20, + SI_SYNC_ITEM_INVOKE_ABSOLUTE_FUNCTION = 21, + SI_SYNC_ITEM_BUTTON_STATE = 22 +} SiSyncItemCode; + +/* + * Filters + */ + typedef enum + { + SI_SYNC_FILTER_TRANSLATIONS = 1, + SI_SYNC_FILTER_ROTATIONS = 2, + SI_SYNC_FILTER_DOMINANT = 3 + } SiSyncFilter; + + typedef enum + { + SI_SYNC_FILTER_OFF = 0, + SI_SYNC_FILTER_ON = 1, + SI_SYNC_FILTER_IN_BETWEEN = 2 + } SiSyncFilterValue; + +/* + * Axes State + */ +typedef enum +{ + SI_SYNC_AXES_STATE_TX = (1<<0), + SI_SYNC_AXES_STATE_TY = (1<<1), + SI_SYNC_AXES_STATE_TZ = (1<<2), + SI_SYNC_AXES_STATE_RX = (1<<3), + SI_SYNC_AXES_STATE_RY = (1<<4), + SI_SYNC_AXES_STATE_RZ = (1<<5) +} SiSyncAxesStateBits; + +typedef struct +{ + int state; /* VURZYX (Tx = LSB (& 1<<0) */ +} SiSyncAxesState; + +/* + * Button State + * For indicating the state of whatever the button sets (in the LCD at this point). + * E.g., to show that Translations are currently OFF for the Translations Toggle button. + * OFF: reverse video, flag is not set + * ON: normal video, flag is set + * DISABLED: (greyed), status of flag is invalid at this time + */ +typedef enum +{ + SI_SYNC_BUTTON_STATE_OFF = 0, + SI_SYNC_BUTTON_STATE_ON = 1, + SI_SYNC_BUTTON_STATE_DISABLED = 2, +} SiSyncButtonState; + + +/* + * Private / implementation structures + * + * We suggest you leave these hidden and use the accessor functions rather than + * directly accessing the structures. + */ +#include "siSyncPriv.h" + + +/* + * Accessor Function headers + */ +SPWuint32 SiSyncGetSize(SiSyncPacket p); +void SiSyncSetSize(SiSyncPacket *p, SPWuint32 size); + +SPWuint32 SiSyncGetHashCode(SiSyncPacket p); +void SiSyncSetHashCode(SiSyncPacket *p, SPWuint32 hashCode); + +SiSyncOpCode SiSyncGetOpCode(SiSyncPacket p); +void SiSyncSetOpCode(SiSyncPacket *p, SPWuint32 opCode); + +SiSyncItemCode SiSyncGetItemCode(SiSyncPacket p); +void SiSyncSetItemCode(SiSyncPacket *p, SPWuint32 itemCode); + +#ifdef __cplusplus +} +#endif + +#endif /* _SI_SYNC_H_ */ diff --git a/extlib/si/siSyncPriv.h b/extlib/si/siSyncPriv.h new file mode 100644 index 0000000..131cf3e --- /dev/null +++ b/extlib/si/siSyncPriv.h @@ -0,0 +1,127 @@ +/*---------------------------------------------------------------------- + * siSyncPriv.h -- 3DxWare GUI Synchronization Private header + * + * Written: June 2005 + * Author: Jim Wick + * + *---------------------------------------------------------------------- + * + * (c) 1998-2005 3Dconnexion. All rights reserved. + * Permission to use, copy, modify, and distribute this software for all + * purposes and without fees is hereby grated provided that this copyright + * notice appears in all copies. Permission to modify this software is granted + * and 3Dconnexion will support such modifications only is said modifications are + * approved by 3Dconnexion. + * + */ + + +#ifndef _SISYNCPRIV_H_ +#define _SISYNCPRIV_H_ + + +/* + * All packets start with the same fields. + * Many packets have data following the itemCode. + */ +typedef struct /* Sync Packet */ + { + SPWuint32 size; /* total packet size */ + SPWuint32 hashCode; /* Hash code that syncs a question with an answer */ + SiSyncOpCode opCode; /* OpCode */ + SiSyncItemCode itemCode; /* itemCode */ + /* There will, generally, be more data starting here. + * There will not be any pointers, the data will be in here. + */ + } SiSyncPacketHeader; + +/* + * I've enumerated all the possible packets here, not because they are all different, + * but mostly just for documentation. So the developer knows what parameters are + * expected with which packet type. + */ +typedef struct { SiSyncPacketHeader h; } SiSyncGetVersionPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 major; SPWint32 minor; } SiSyncSetVersionPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncCommandQueryPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncCommandSaveConfigPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetNumberOfFunctionsPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 n; } SiSyncSetNumberOfFunctionsPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetFunctionPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; WCHAR name[1];} SiSyncSetFunctionPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetButtonAssignmentPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; } SiSyncSetButtonAssignmentPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; } SiSyncSetButtonAssignmentAbsolutePacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; WCHAR name[1]; } SiSyncSetButtonNamePacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetAxisLabelPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; WCHAR name[1]; } SiSyncSetAxisLabelPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetOrientationPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 a[6]; } SiSyncSetOrientationPacket; +typedef struct { SiSyncPacketHeader h; SiSyncFilter i; } SiSyncGetFilterPacket; +typedef struct { SiSyncPacketHeader h; SiSyncFilter i; SiSyncFilterValue v; } SiSyncSetFilterPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetAxesStatePacket; +typedef struct { SiSyncPacketHeader h; SiSyncAxesState a; } SiSyncSetAxesStatePacket; +typedef struct { SiSyncPacketHeader h; SPWint32 duration; WCHAR s[1]; } SiSyncSetInfoLinePacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleOverallPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleOverallPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTxPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTxPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTyPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTyPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTzPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTzPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRxPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRxPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRyPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRyPacket; +typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRzPacket; +typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRzPacket; +typedef struct { SiSyncPacketHeader h; SiSyncAbsFunctionNumber i; } SiSyncAbsFunctionPacket; +typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWbool state; } SiSyncSetButtonStatePacket; + +typedef struct +{ + union + { + SiSyncPacketHeader h; + SiSyncGetVersionPacket gv; + SiSyncSetVersionPacket sv; + SiSyncCommandQueryPacket cq; + SiSyncCommandSaveConfigPacket cs; + SiSyncGetNumberOfFunctionsPacket gnf; + SiSyncSetNumberOfFunctionsPacket snf; + SiSyncGetFunctionPacket gf; + SiSyncSetFunctionPacket sf; + SiSyncGetButtonAssignmentPacket gba; + SiSyncSetButtonAssignmentPacket sba; + SiSyncSetButtonAssignmentAbsolutePacket sbaa; + SiSyncSetButtonNamePacket sbn; + SiSyncGetAxisLabelPacket ga; + SiSyncSetAxisLabelPacket sa; + SiSyncGetOrientationPacket go; + SiSyncSetOrientationPacket so; + SiSyncGetFilterPacket gfi; + SiSyncSetFilterPacket sfi; + SiSyncGetAxesStatePacket gas; + SiSyncSetAxesStatePacket sas; + SiSyncSetInfoLinePacket si; + SiSyncGetScaleOverallPacket gso; + SiSyncSetScaleOverallPacket sso; + SiSyncGetScaleTxPacket gtx; + SiSyncSetScaleTxPacket stx; + SiSyncGetScaleTyPacket gty; + SiSyncSetScaleTyPacket sty; + SiSyncGetScaleTzPacket gtz; + SiSyncSetScaleTzPacket stz; + SiSyncGetScaleRxPacket grx; + SiSyncSetScaleRxPacket srx; + SiSyncGetScaleRyPacket gry; + SiSyncSetScaleRyPacket sry; + SiSyncGetScaleRzPacket grz; + SiSyncSetScaleRzPacket srz; + SiSyncAbsFunctionPacket absf; + SiSyncSetButtonStatePacket sbs; + }; +} SiSyncPacket; + + +#endif /* _SI_SYNCPRIV_H_ */ diff --git a/extlib/si/siapp.h b/extlib/si/siapp.h new file mode 100644 index 0000000..eb8f222 --- /dev/null +++ b/extlib/si/siapp.h @@ -0,0 +1,121 @@ +/*----------------------------------------------------------------------------- + * + * siapp.h -- Si static library interface header file + * + * $Id: siapp.h,v 1.3 2001/01/16 01:18:49 HJin Exp $ + * + * Contains function headers and type definitions for siapp.c. + * + *----------------------------------------------------------------------------- + * + * (c) 1998-2005 3Dconnexion. All rights reserved. + * Permission to use, copy, modify, and distribute this software for all + * purposes and without fees is hereby grated provided that this copyright + * notice appears in all copies. Permission to modify this software is granted + * and 3Dconnexion will support such modifications only if said modifications are + * approved by 3Dconnexion. + * + */ + +#ifndef SIAPP_H +#define SIAPP_H + + +static char SiAppCvsId[]="(c) 1998-2005 3Dconnexion: $Id: siapp.h,v 1.3 2001/01/16 01:18:49 HJin Exp $"; + +#ifdef __cplusplus +extern "C" { +#endif + + +/* some enumerated types used in siapp.c */ + +enum InitResult + { + NOT_LOADED, + FAILED, + LOADED + }; + +enum ErrorCode + { + NO_DLL_ERROR=0, + DLL_LOAD_FAILURE, + DLL_FUNCTION_LOAD_FAILURE, + DLL_VAR_LOAD_FAILURE + }; + + +/* externally used functions */ + +enum SpwRetVal SiInitialize(void); +void SiTerminate(void); +int SiGetNumDevices (void); +SiDevID SiDeviceIndex (int idx); +int SiDispatch (SiHdl hdl, SiGetEventData *pData, + SiSpwEvent *pEvent, SiSpwHandlers *pDHandlers); +void SiOpenWinInit (SiOpenData *pData, HWND hWnd); +SiHdl SiOpen (char *pAppName, SiDevID devID, SiTypeMask *pTMask, int mode, + SiOpenData *pData); +enum SpwRetVal SiClose (SiHdl hdl); +void SiGetEventWinInit (SiGetEventData *pData, + UINT msg, WPARAM wParam, LPARAM lParam); +enum SpwRetVal SiGetEvent (SiHdl hdl, int flags, SiGetEventData *pData, + SiSpwEvent *pEvent); +enum SpwRetVal SiBeep (SiHdl hdl, char *string); +enum SpwRetVal SiRezero (SiHdl hdl); +enum SpwRetVal SiGrabDevice (SiHdl hdl, SPWbool exclusive); +enum SpwRetVal SiReleaseDevice (SiHdl hdl); +int SiButtonPressed (SiSpwEvent *pEvent); +int SiButtonReleased (SiSpwEvent *pEvent); +enum SpwRetVal SiSetUiMode (SiHdl hdl, SPWuint32 mode); +enum SpwRetVal SiSetTypeMask (SiTypeMask *pTMask, int type1, ...); +enum SpwRetVal SiGetDevicePort (SiDevID devID, SiDevPort *pPort); +enum SpwRetVal SiGetDriverInfo (SiVerInfo *pInfo); +void SiGetLibraryInfo (SiVerInfo *pInfo); +enum SpwRetVal SiGetDeviceInfo (SiHdl hdl, SiDevInfo *pInfo); +char * SpwErrorString (enum SpwRetVal val); +enum SpwRetVal SiSyncSendQuery(SiHdl hdl); +enum SpwRetVal SiSyncGetVersion(SiHdl hdl, SPWuint32 *pmajor, SPWuint32 *pminor); +enum SpwRetVal SiSyncGetNumberOfFunctions(SiHdl hdl, SPWuint32 *pnumberOfFunctions); +enum SpwRetVal SiSyncGetFunction(SiHdl hdl, SPWuint32 index, SPWint32 *pabsoluteFunctionNumber, WCHAR name[], SPWuint32 *pmaxNameLen); +enum SpwRetVal SiSyncGetButtonAssignment(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 *passignedFunctionIndex); +enum SpwRetVal SiSyncSetButtonAssignment(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 functionIndex); +enum SpwRetVal SiSyncSetButtonAssignmentAbsolute(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 absoluteFunctionNumber ); +enum SpwRetVal SiSyncSetButtonName(SiHdl hdl, SPWuint32 buttonNumber, WCHAR name[]); +enum SpwRetVal SiSyncGetAxisLabel (SiHdl hdl, SPWuint32 axisNumber, WCHAR name[], SPWuint32 *pmaxNameLen ); +enum SpwRetVal SiSyncSetAxisLabel (SiHdl hdl, SPWuint32 axisNumber, WCHAR name[] ); +enum SpwRetVal SiSyncGetOrientation (SiHdl hdl, SPWint32 axes[6] ); +enum SpwRetVal SiSyncSetOrientation (SiHdl hdl, SPWint32 axes[6] ); +enum SpwRetVal SiSyncGetFilter (SiHdl hdl, SiSyncFilter i, SiSyncFilterValue *pv ); +enum SpwRetVal SiSyncSetFilter (SiHdl hdl, SiSyncFilter i, SiSyncFilterValue v ); +enum SpwRetVal SiSyncGetAxesState (SiHdl hdl, SiSyncAxesState *pa ); +enum SpwRetVal SiSyncSetAxesState (SiHdl hdl, SiSyncAxesState a ); +enum SpwRetVal SiSyncSetInfoLine (SiHdl hdl, SPWint32 duration, WCHAR text[] ); +enum SpwRetVal SiSyncGetScaleOverall (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleOverall (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleTx (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleTx (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleTy (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleTy (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleTz (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleTz (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleRx (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleRx (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleRy (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleRy (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncGetScaleRz (SiHdl hdl, SPWfloat32 *pv ); +enum SpwRetVal SiSyncSetScaleRz (SiHdl hdl, SPWfloat32 v ); +enum SpwRetVal SiSyncInvokeAbsoluteFunction (SiHdl hdl, SiSyncAbsFunctionNumber i ); +enum SpwRetVal SiSyncSetButtonState (SiHdl hdl, SPWuint32 buttonNumber, SiSyncButtonState state ); +enum SpwRetVal SiGetButtonName (SiHdl hdl, SPWuint32 buttonNumber, SiButtonName *pname); +enum SpwRetVal SiGetDeviceName (SiHdl hdl, SiDeviceName *pname); +enum SpwRetVal SiGetDeviceImageFileName (SiHdl hdl, char name[], SPWuint32 *pmaxNameLen); +HICON SiGetCompanyIcon(void); +enum SpwRetVal SiGetCompanyLogoFileName (char name[], SPWuint32 *pmaxNameLen); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef SIAPP_H */ diff --git a/extlib/si/siapp.lib b/extlib/si/siapp.lib new file mode 100644 index 0000000..5dbb5c6 Binary files /dev/null and b/extlib/si/siapp.lib differ diff --git a/extlib/si/spwdata.h b/extlib/si/spwdata.h new file mode 100644 index 0000000..f54a070 --- /dev/null +++ b/extlib/si/spwdata.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------- + * spwdata.h -- datatypes + * + * + * $Id: spwdata.h,v 1.4 1996/10/08 23:01:39 chris Exp $ + * + * This contains the only acceptable type definitions for 3Dconnexion + * products. Needs more work. + * + *---------------------------------------------------------------------- + * + * (c) 1996-2005 3Dconnexion. All rights reserved. + * + * The computer codes included in this file, including source code and + * object code, constitutes the proprietary and confidential information of + * 3Dconnexion, and are provided pursuant to a license + * agreement. These computer codes are protected by international, federal + * and state law, including United States Copyright Law and international + * treaty provisions. Except as expressly authorized by the license + * agreement, or as expressly permitted under applicable laws of member + * states of the European Union and then only to the extent so permitted, + * no part of these computer codes may be reproduced or transmitted in any + * form or by any means, electronic or mechanical, modified, decompiled, + * disassembled, reverse engineered, sold, transferred, rented or utilized + * for any unauthorized purpose without the express written permission of + * 3Dconnexion. + * + *---------------------------------------------------------------------- + * + */ + +#ifndef SPWDATA_H +#define SPWDATA_H + +static char spwdataCvsId[]="(C) 1996-2005 3Dconnexion: $Id: spwdata.h,v 1.4 1996/10/08 23:01:39 chris Exp $"; + +#include + +#define tchar_t _TCHAR +#define char_t char +#define uint32_t unsigned long +#define sint32_t long +#define boolean_t unsigned char +#define void_t void +#define window_handle_t HWND + + +typedef long SPWint32; +typedef short SPWint16; +typedef char SPWint8; +typedef int SPWbool; +typedef unsigned long SPWuint32; +typedef unsigned short SPWuint16; +typedef unsigned char SPWuint8; +typedef _TCHAR SPWchar; +typedef _TCHAR* SPWstring; +typedef float SPWfloat32; +typedef double SPWfloat64; + + + +#endif /* SPWDATA_H */ + diff --git a/extlib/si/spwerror.h b/extlib/si/spwerror.h new file mode 100644 index 0000000..208d2c7 --- /dev/null +++ b/extlib/si/spwerror.h @@ -0,0 +1,64 @@ +/*---------------------------------------------------------------------- + * spwerror.h -- Standard Spacetec IMC function return values + * + * $Id: spwerror.h,v 1.10.4.1 1998/05/26 17:30:21 equerze Exp $ + * + * This file contains all the Spacetec IMC standard error return + * return values for functions + * + *---------------------------------------------------------------------- + * + * (C) 1998-2001 3Dconnexion. All rights reserved. + * Permission to use, copy, modify, and distribute this software for all + * purposes and without fees is hereby grated provided that this copyright + * notice appears in all copies. Permission to modify this software is granted + * and 3Dconnexion will support such modifications only is said modifications are + * approved by 3Dconnexion. + * + */ + +#ifndef _SPWERROR_H_ +#define _SPWERROR_H_ + +#include "spwdata.h" + +static char spwerrorCvsId[]="(C) 1996 Spacetec IMC Corporation: $Id: spwerror.h,v 1.10.4.1 1998/05/26 17:30:21 equerze Exp $"; + +enum SpwRetVal /* Error return values. */ + { + SPW_NO_ERROR, /* No error. */ + SPW_ERROR, /* Error -- function failed. */ + SI_BAD_HANDLE, /* Invalid SpaceWare handle. */ + SI_BAD_ID, /* Invalid device ID. */ + SI_BAD_VALUE, /* Invalid argument value. */ + SI_IS_EVENT, /* Event is a SpaceWare event. */ + SI_SKIP_EVENT, /* Skip this SpaceWare event. */ + SI_NOT_EVENT, /* Event is not a SpaceWare event. */ + SI_NO_DRIVER, /* SpaceWare driver is not running. */ + SI_NO_RESPONSE, /* SpaceWare driver is not responding. */ + SI_UNSUPPORTED, /* The function is unsupported by this version. */ + SI_UNINITIALIZED, /* SpaceWare input library is uninitialized. */ + SI_WRONG_DRIVER, /* Driver is incorrect for this SpaceWare version.*/ + SI_INTERNAL_ERROR, /* Internal SpaceWare error. */ + SI_BAD_PROTOCOL, /* The transport protocol is unknown. */ + SI_OUT_OF_MEMORY, /* Unable to malloc space required. */ + SPW_DLL_LOAD_ERROR, /* Could not load siapp dlls */ + SI_NOT_OPEN, /* Spaceball device not open */ + SI_ITEM_NOT_FOUND, /* Item not found */ + SI_UNSUPPORTED_DEVICE, /* The device is not supported */ + SI_NOT_ENOUGH_MEMORY, /* Not enough memory (but not a malloc problem) */ + SI_SYNC_WRONG_HASHCODE /* Wrong hash code sent to a Sync function */ + }; + +typedef enum SpwRetVal SpwReturnValue; + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _SPWERROR_H_ */ diff --git a/extlib/si/spwmacro.h b/extlib/si/spwmacro.h new file mode 100644 index 0000000..10fcf16 --- /dev/null +++ b/extlib/si/spwmacro.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------- + * spwmacro.h -- cpp macros we ALWAYS use. + * +<<<<<<< spwmacro.h + * $Id: spwmacro.h,v 1.3 2001/01/16 01:18:40 HJin Exp $ +======= + * $Id: spwmacro.h,v 1.3 2001/01/16 01:18:40 HJin Exp $ +>>>>>>> 1.1.1.1.4.1 + * + * We always seem to use the same macros. + * This is the place we define them. + * + *---------------------------------------------------------------------- + */ + +#ifndef SPWMACRO_H +#define SPWMACRO_H + + +#define SPW_FALSE (0) +#define SPW_TRUE (!SPW_FALSE) + +#define SPW_MAX(a,b) (((a)>(b))?(a):(b)) +#define SPW_MIN(a,b) (((a)<(b))?(a):(b)) + +#define SPW_ABS(a) (((a)<0)?(-(a)):(a)) + +#define SPW_SIGN(a) ((a)>=0?1:-1) + +#define SPW_BIND(min,n,max) (SPW_MIN((max),SPW_MAX((min),(n)))) + +#define SPW_NUM_ELEMENTS_IN(a) (sizeof(a)/sizeof((a)[0])) + +#define SPW_PI 3.14159265358979324f + +#define SPW_DEG_TO_RAD(d) ((d)*SPW_PI/180.0f) +#define SPW_RAD_TO_DEG(r) ((r)*180.0f/SPW_PI) + +#define SPW_LENGTH_OF(a) (sizeof(a)/sizeof((a)[0])) + +#define SPW_END_OF(a) (&(a)[SPW_LENGTH_OF(a)-1]) + +#define SPW_SQ(a) ((a)*(a)) + +#define SPW_ABSDIFF(a, b) (fabs((double) (a) - (b))) + + +#endif diff --git a/graphicswin.cpp b/graphicswin.cpp index 72945e1..4555327 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -639,27 +639,16 @@ void GraphicsWindow::MenuEdit(int id) { break; } - hParam qw, qx, qy, qz; - qw = g->h.param(3); - qx = g->h.param(4); - qy = g->h.param(5); - qz = g->h.param(6); SS.UndoRemember(); // Rotate by ninety degrees about the coordinate axis closest // to the screen normal. - Quaternion q = Quaternion::From(qw, qx, qy, qz); Vector norm = SS.GW.projRight.Cross(SS.GW.projUp); norm = norm.ClosestOrtho(); norm = norm.WithMagnitude(1); Quaternion qaa = Quaternion::From(norm, PI/2); - q = qaa.Times(q); - // And write the new quaternion - SK.GetParam(qw)->val = q.w; - SK.GetParam(qx)->val = q.vx; - SK.GetParam(qy)->val = q.vy; - SK.GetParam(qz)->val = q.vz; + g->TransformImportedBy(Vector::From(0, 0, 0), qaa); // and regenerate as necessary. SS.MarkGroupDirty(hg); diff --git a/group.cpp b/group.cpp index b3f2d69..aeb1c24 100644 --- a/group.cpp +++ b/group.cpp @@ -239,6 +239,34 @@ void Group::MenuGroup(int id) { SS.later.showTW = true; } +void Group::TransformImportedBy(Vector t, Quaternion q) { + if(type != IMPORTED) oops(); + + hParam tx, ty, tz, qw, qx, qy, qz; + tx = h.param(0); + ty = h.param(1); + tz = h.param(2); + qw = h.param(3); + qx = h.param(4); + qy = h.param(5); + qz = h.param(6); + + Quaternion qg = Quaternion::From(qw, qx, qy, qz); + qg = q.Times(qg); + + Vector tg = Vector::From(tx, ty, tz); + tg = tg.Plus(t); + + SK.GetParam(tx)->val = tg.x; + SK.GetParam(ty)->val = tg.y; + SK.GetParam(tz)->val = tg.z; + + SK.GetParam(qw)->val = qg.w; + SK.GetParam(qx)->val = qg.vx; + SK.GetParam(qy)->val = qg.vy; + SK.GetParam(qz)->val = qg.vz; +} + char *Group::DescriptionString(void) { static char ret[100]; if(name.str[0]) { diff --git a/sketch.h b/sketch.h index e0683c2..5139abb 100644 --- a/sketch.h +++ b/sketch.h @@ -188,6 +188,7 @@ public: static void AddParam(ParamList *param, hParam hp, double v); void Generate(EntityList *entity, ParamList *param); + void TransformImportedBy(Vector t, Quaternion q); // When a request generates entities from entities, and the source // entities may have come from multiple requests, it's necessary to // remap the entity ID so that it's still unique. We do this with a diff --git a/ui.h b/ui.h index 0f6ce35..61394cd 100644 --- a/ui.h +++ b/ui.h @@ -436,6 +436,12 @@ public: void MouseScroll(double x, double y, int delta); void MouseLeave(void); void EditControlDone(char *s); + + SDWORD lastSpaceNavigatorTime; + hGroup lastSpaceNavigatorGroup; + void SpaceNavigatorMoved(double tx, double ty, double tz, + double rx, double ry, double rz, bool shiftDown); + void SpaceNavigatorButtonUp(void); }; diff --git a/win32/w32main.cpp b/win32/w32main.cpp index 837e0d0..ea161a4 100644 --- a/win32/w32main.cpp +++ b/win32/w32main.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include + #include "solvespace.h" #define FREEZE_SUBKEY "SolveSpace" @@ -50,6 +53,9 @@ int ClientIsSmallerBy; HFONT FixedFont, LinkFont; +// The 6-DOF input device. +SiHdl SpaceNavigator = SI_NO_HANDLE; + static void DoMessageBox(char *str, va_list f, BOOL error) { char buf[1024*50]; @@ -287,7 +293,22 @@ void HandleTextWindowScrollBar(WPARAM wParam, LPARAM lParam) } } -void MouseWheel(int delta) { +static void MouseWheel(int thisDelta) { + static int DeltaAccum; + int delta = 0; + // Handle mouse deltas of less than 120 (like from an un-detented mouse + // wheel) correctly, even though no one ever uses those. + DeltaAccum += thisDelta; + while(DeltaAccum >= 120) { + DeltaAccum -= 120; + delta += 120; + } + while(DeltaAccum <= -120) { + DeltaAccum += 120; + delta -= 120; + } + if(delta == 0) return; + POINT pt; GetCursorPos(&pt); HWND hw = WindowFromPoint(pt); @@ -1024,6 +1045,42 @@ static void CreateMainWindows(void) ClientIsSmallerBy = (r.bottom - r.top) - (rc.bottom - rc.top); } +//----------------------------------------------------------------------------- +// Test if a message comes from the SpaceNavigator device. If yes, dispatch +// it appropriately and return TRUE. Otherwise, do nothing and return FALSE. +//----------------------------------------------------------------------------- +static BOOL ProcessSpaceNavigatorMsg(MSG *msg) { + if(SpaceNavigator == SI_NO_HANDLE) return FALSE; + + SiGetEventData sged; + SiSpwEvent sse; + + SiGetEventWinInit(&sged, msg->message, msg->wParam, msg->lParam); + int ret = SiGetEvent(SpaceNavigator, 0, &sged, &sse); + if(ret == SI_NOT_EVENT) return FALSE; + // So the device is a SpaceNavigator event, or a SpaceNavigator error. + + if(ret == SI_IS_EVENT) { + if(sse.type == SI_MOTION_EVENT) { + // The Z axis translation and rotation are both + // backwards in the default mapping. + double tx = sse.u.spwData.mData[SI_TX]*0.1, + ty = sse.u.spwData.mData[SI_TY]*0.1, + tz = -sse.u.spwData.mData[SI_TZ]*0.1, + rx = sse.u.spwData.mData[SI_RX]*0.001, + ry = sse.u.spwData.mData[SI_RY]*0.001, + rz = -sse.u.spwData.mData[SI_RZ]*0.001; + SS.GW.SpaceNavigatorMoved(tx, ty, tz, rx, ry, rz, + !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)); + } else if(sse.type == SI_BUTTON_EVENT) { + int button; + button = SiButtonReleased(&sse); + if(button == SI_APP_FIT_BUTTON) SS.GW.SpaceNavigatorButtonUp(); + } + } + return TRUE; +} + //----------------------------------------------------------------------------- // Entry point into the program. //----------------------------------------------------------------------------- @@ -1079,6 +1136,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, if(*file != '\0') { GetAbsoluteFilename(file); } + + // Initialize the SpaceBall, if present. Test if the driver is running + // first, to avoid a long timeout if it's not. + HWND swdc = FindWindow("SpaceWare Driver Class", NULL); + if(swdc != NULL) { + SiOpenData sod; + SiInitialize(); + SiOpenWinInit(&sod, GraphicsWnd); + SpaceNavigator = + SiOpen("GraphicsWnd", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &sod); + SiSetUiMode(SpaceNavigator, SI_UI_NO_CONTROLS); + } // Call in to the platform-independent code, and let them do their init SS.Init(file); @@ -1088,6 +1157,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, MSG msg; DWORD ret; while(ret = GetMessage(&msg, NULL, 0, 0)) { + // Is it a message from the six degree of freedom input device? + if(ProcessSpaceNavigatorMsg(&msg)) goto done; + + // A message from the keyboard, which should be processed as a keyboard + // accelerator? if(msg.message == WM_KEYDOWN) { if(ProcessKeyDown(msg.wParam)) goto done; } @@ -1096,12 +1170,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, // then that should probably go to the graphics window instead. SetForegroundWindow(GraphicsWnd); } + + // None of the above; so just a normal message to process. TranslateMessage(&msg); DispatchMessage(&msg); done: SS.DoLater(); } + if(swdc != NULL) { + if(SpaceNavigator != SI_NO_HANDLE) SiClose(SpaceNavigator); + SiTerminate(); + } + // Write everything back to the registry FreezeWindowPos(TextWnd); FreezeWindowPos(GraphicsWnd); diff --git a/wishlist.txt b/wishlist.txt index 4eb82c9..029b5d1 100644 --- a/wishlist.txt +++ b/wishlist.txt @@ -6,9 +6,9 @@ background color setting better text better drawing of dimensions faster triangulation -SpaceNavigator support ----- +copy and paste loop detection IGES export incremental regen of entities