SpaceNav turntable and fit in 3D view. Tablet data rides with cursor/button events (incomplete! Mac-only for now). Grease pencil works better with pen.

This commit is contained in:
Mike Erwin 2010-08-07 10:57:15 +00:00
parent ad623ddd82
commit f399481251
23 changed files with 763 additions and 842 deletions

@ -29,27 +29,22 @@
#ifndef _GHOST_TYPES_H_
#define _GHOST_TYPES_H_
typedef char GHOST_TInt8;
typedef unsigned char GHOST_TUns8;
typedef short GHOST_TInt16;
typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
#ifdef WIN32
#define WM_BLND_NDOF_AXIS WM_USER + 1
#define WM_BLND_NDOF_BTN WM_USER + 2
#endif
typedef char GHOST_TInt8;
typedef unsigned char GHOST_TUns8;
typedef short GHOST_TInt16;
typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
#if defined(WIN32) && !defined(FREE_WINDOWS)
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
#else
typedef long long GHOST_TInt64;
typedef unsigned long long GHOST_TUns64;
typedef long long GHOST_TInt64;
typedef unsigned long long GHOST_TUns64;
#endif
typedef void* GHOST_TUserDataPtr;
typedef void* GHOST_TUserDataPtr;
typedef enum
{
@ -154,8 +149,7 @@ typedef enum {
GHOST_kEventTrackpad, /// Trackpad event
GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
GHOST_kEventNDOFButtonDown,/// N degree of freedom device button events
GHOST_kEventNDOFButtonUp,
GHOST_kEventNDOFButton,
GHOST_kEventKeyDown,
GHOST_kEventKeyUp,
@ -276,7 +270,6 @@ typedef enum {
GHOST_kKeyRightBracket = ']',
GHOST_kKeyBackslash = 0x5C,
GHOST_kKeyAccentGrave = '`',
GHOST_kKeyLeftShift = 0x100,
GHOST_kKeyRightShift,
@ -284,8 +277,8 @@ typedef enum {
GHOST_kKeyRightControl,
GHOST_kKeyLeftAlt,
GHOST_kKeyRightAlt,
GHOST_kKeyCommand, // APPLE only!
GHOST_kKeyGrLess , // German PC only!
GHOST_kKeyCommand, // APPLE only!
GHOST_kKeyGrLess, // German PC only!
GHOST_kKeyCapsLock,
GHOST_kKeyNumLock,
@ -365,11 +358,17 @@ typedef struct {
GHOST_TInt32 x;
/** The y-coordinate of the cursor position. */
GHOST_TInt32 y;
GHOST_TabletData tablet;
} GHOST_TEventCursorData;
typedef struct {
/** The mask of the mouse button. */
GHOST_TButtonMask button;
GHOST_TabletData tablet;
} GHOST_TEventButtonData;
typedef struct {
@ -384,7 +383,6 @@ typedef enum {
GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
GHOST_kTrackpadEventMagnify
} GHOST_TTrackpadEventSubTypes;
typedef struct {
/** The event subtype */
@ -423,40 +421,23 @@ typedef struct {
GHOST_TUns8 **strings;
} GHOST_TStringArray;
/* original patch used floats, but the driver return ints and uns. We will calibrate in view, no sense on doing conversions twice */
/* as all USB device controls are likely to use ints, this is also more future proof */
//typedef struct {
// /** N-degree of freedom device data */
// float tx, ty, tz; /** -x left, +y up, +z forward */
// float rx, ry, rz;
// float dt;
//} GHOST_TEventNDOFData;
// typedef struct {
// /** N-degree of freedom device data v2*/
// int changed;
// GHOST_TUns64 client;
// GHOST_TUns64 address;
// GHOST_TInt16 tx, ty, tz; /** -x left, +y up, +z forward */
// GHOST_TInt16 rx, ry, rz;
// GHOST_TInt16 buttons;
// GHOST_TUns64 time;
// GHOST_TUns64 delta;
// } GHOST_TEventNDOFData;
typedef struct {
/** N-degree of freedom device data v3 [GSoC 2010]*/
/* Each component normally ranges from -1 to +1, but can exceed that. */
float tx, ty, tz; /* translation: -x left, +y forward, -z up */
float rx, ry, rz; /* rotation:
axis = (rx,ry,rz).normalized
amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] */
float dt; // time since previous NDOF Motion event (or zero if this is the first)
// Fairly close to raw device data.
// Each component normally ranges from -1 to +1, but can exceed that.
// rot axis = (rx,ry,rz).normalized
// rot amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
} GHOST_TEventNDOFMotionData;
float tx, ty, tz; /** -x left, +y forward, -z up */
float rx, ry, rz;
} GHOST_TEventNDOFData;
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction; // good for mouse or other buttons too, hmmm?
typedef struct {
GHOST_TButtonAction action;
short button;
} GHOST_TEventNDOFButtonData;
typedef struct {
/** The key code. */
@ -478,13 +459,13 @@ typedef struct {
#ifdef _WIN32
typedef long GHOST_TEmbedderWindowID;
typedef long GHOST_TEmbedderWindowID;
#endif // _WIN32
#ifndef _WIN32
// I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h
typedef int GHOST_TEmbedderWindowID;
#endif // _WIN32
// I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h
typedef int GHOST_TEmbedderWindowID;
#endif
/**
* A timer task callback routine.
@ -492,12 +473,11 @@ typedef int GHOST_TEmbedderWindowID;
* @param time The current time.
*/
#ifdef __cplusplus
class GHOST_ITimerTask;
typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask* task, GHOST_TUns64 time);
class GHOST_ITimerTask;
typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask* task, GHOST_TUns64 time);
#else
struct GHOST_TimerTaskHandle__;
typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__* task, GHOST_TUns64 time);
struct GHOST_TimerTaskHandle__;
typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__* task, GHOST_TUns64 time);
#endif
#endif // _GHOST_TYPES_H_

@ -55,6 +55,7 @@ public:
: GHOST_Event(time, type, window)
{
m_buttonEventData.button = button;
m_buttonEventData.tablet.Active = GHOST_kTabletModeNone;
m_data = &m_buttonEventData;
}
@ -64,4 +65,3 @@ protected:
};
#endif // _GHOST_EVENT_BUTTON_H_

@ -55,6 +55,7 @@ public:
{
m_cursorEventData.x = x;
m_cursorEventData.y = y;
m_cursorEventData.tablet.Active = GHOST_kTabletModeNone;
m_data = &m_cursorEventData;
}

@ -110,7 +110,7 @@ GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event)
bool GHOST_EventManager::dispatchEvent(GHOST_IEvent* event)
{
// [mce] this variant switches the "handled" flag to work as described in the header
// it also stops after the first consumer has handled the event
// it also stops after the first consumer has handled the event (no it doesn't)
bool handled = false;
if (event) {
TConsumerVector::iterator iter;
@ -322,7 +322,7 @@ GHOST_IEvent* GHOST_EventManager::popEvent()
void GHOST_EventManager::disposeEvents()
{
while (m_events.size() > 0) {
while (!m_events.empty()) {
GHOST_ASSERT(m_events[0], "invalid event");
delete m_events[0];
m_events.pop_front();

@ -28,33 +28,31 @@
class GHOST_EventNDOFMotion : public GHOST_Event
{
protected:
GHOST_TEventNDOFData m_axisData;
{
protected:
GHOST_TEventNDOFMotionData m_axisData;
public:
GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow* window)
: GHOST_Event(time, GHOST_kEventNDOFMotion, window)
{
m_data = &m_axisData;
}
};
public:
GHOST_EventNDOFMotion(GHOST_TUns64 time)
: GHOST_Event(time, GHOST_kEventNDOFMotion, NULL)
// , m_data(&m_axisData)
{
m_data = &m_axisData;
}
};
class GHOST_EventNDOFButton : public GHOST_Event
{
protected:
GHOST_TUns16 m_buttonNumber;
public:
GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_TUns16 buttonNumber, GHOST_TEventType upOrDown)
: GHOST_Event(time, upOrDown, NULL)
, m_buttonNumber(buttonNumber)
// , m_data(&m_buttonNumber)
{
m_data = &m_buttonNumber;
}
};
{
protected:
GHOST_TEventNDOFButtonData m_buttonData;
public:
GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow* window)
: GHOST_Event(time, GHOST_kEventNDOFButton, window)
{
m_data = &m_buttonData;
}
};
#endif // _GHOST_EVENT_NDOF_H_

@ -22,12 +22,15 @@
#include "GHOST_NDOFManager.h"
#include "GHOST_EventNDOF.h"
#include "GHOST_WindowManager.h"
#include <string.h> // for memory functions
#include <stdio.h> // for debug tracing
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
: m_system(sys)
, m_buttons(0)
, m_motionTime(1000) // one full second (operators should filter out such large time deltas)
, m_prevMotionTime(0)
, m_atRest(true)
{
// to avoid the rare situation where one triple is updated and
@ -52,13 +55,28 @@ void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
void GHOST_NDOFManager::updateButtons(unsigned short buttons, GHOST_TUns64 time)
{
GHOST_System* system = (GHOST_System*) GHOST_System::getSystem();
GHOST_IWindow* window = system->getWindowManager()->getActiveWindow();
unsigned short diff = m_buttons ^ buttons;
for (int i = 0; i < 16; ++i)
{
unsigned short mask = 1 << i;
if (diff & mask)
m_system.pushEvent(new GHOST_EventNDOFButton(time, i + 1,
(buttons & mask) ? GHOST_kEventNDOFButtonDown : GHOST_kEventNDOFButtonUp));
{
GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
data->action = (buttons & mask) ? GHOST_kPress : GHOST_kRelease;
// data->pressed = buttons & mask;
data->button = i + 1;
// printf("sending button %d %s\n", data->button, (data->action == GHOST_kPress) ? "pressed" : "released");
m_system.pushEvent(event);
}
}
m_buttons = buttons;
@ -69,8 +87,11 @@ bool GHOST_NDOFManager::sendMotionEvent()
if (m_atRest)
return false;
GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime);
GHOST_TEventNDOFData* data = (GHOST_TEventNDOFData*) event->getData();
GHOST_System* system = (GHOST_System*) GHOST_System::getSystem();
GHOST_IWindow* window = system->getWindowManager()->getActiveWindow();
GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, window);
GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
const float scale = 1.f / 350.f; // SpaceNavigator sends +/- 350 usually
// 350 according to their developer's guide; others recommend 500 as comfortable
@ -78,7 +99,7 @@ bool GHOST_NDOFManager::sendMotionEvent()
// possible future enhancement
// scale *= m_sensitivity;
data->tx = scale * m_translation[0];
data->tx = -scale * m_translation[0];
data->ty = scale * m_translation[1];
data->tz = scale * m_translation[2];
@ -86,13 +107,19 @@ bool GHOST_NDOFManager::sendMotionEvent()
data->ry = scale * m_rotation[1];
data->rz = scale * m_rotation[2];
printf("sending T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f)\n", data->tx, data->ty, data->tz, data->rx, data->ry, data->rz);
data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
printf("dt = %d ms\n", (int)(m_motionTime - m_prevMotionTime));
m_prevMotionTime = m_motionTime;
// printf("sending T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f)\n", data->tx, data->ty, data->tz, data->rx, data->ry, data->rz);
m_system.pushEvent(event);
// 'at rest' test goes at the end so that the first 'rest' event gets sent
m_atRest = m_rotation[0] == 0 && m_rotation[1] == 0 && m_rotation[2] == 0 &&
m_translation[0] == 0 && m_translation[1] == 0 && m_translation[2] == 0;
return true;
}

@ -55,7 +55,11 @@ protected:
unsigned short m_buttons;
GHOST_TUns64 m_motionTime;
GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
bool m_atRest;
void updateMotionTime(GHOST_TUns64 t);
void resetMotion();
};

@ -47,16 +47,20 @@ static void SpaceNavEvent(io_connect_t connection, natural_t messageType, void *
case kConnexionMsgDeviceState:
{
ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
GHOST_TUns64 now = system->getMilliSeconds();
switch (s->command)
{
case kConnexionCmdHandleAxis:
manager->updateTranslation(s->axis, s->time);
manager->updateRotation(s->axis + 3, s->time);
// manager->updateTranslation(s->axis, s->time);
manager->updateTranslation(s->axis, now);
manager->updateRotation(s->axis + 3, now);
system->notifyExternalEventProcessed();
break;
case kConnexionCmdHandleButtons:
manager->updateButtons(s->buttons, s->time);
manager->updateButtons(s->buttons, now);
system->notifyExternalEventProcessed();
break;
}

@ -35,11 +35,8 @@
#define _GHOST_SYSTEM_COCOA_H_
#ifndef __APPLE__
#error Apple OSX only!
#endif // __APPLE__
//#define __CARBONSOUND__
#error Apple OSX only!
#endif
#include "GHOST_System.h"
@ -266,6 +263,11 @@ protected:
* @return Indication whether the event was handled.
*/
GHOST_TSuccess handleTabletEvent(void *eventPtr);
/**
* Helps handleTabletEvent function.
*/
void fillTabletData(GHOST_TabletData& tablet, void* event_ptr);
/**
* Handles a tablet proximity event. Sets pen or mouse ID for later events.
@ -307,7 +309,8 @@ protected:
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
double m_start_time_2;
/** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
bool m_outsideLoopEventProcessed;
@ -336,4 +339,3 @@ protected:
};
#endif // _GHOST_SYSTEM_COCOA_H_

@ -568,6 +568,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
sysctl(mib, 2, &boottime, &len, NULL, 0);
m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
m_start_time_2 = CFAbsoluteTimeGetCurrent();
//Detect multitouch trackpad
mib[0] = CTL_HW;
mib[1] = HW_MODEL;
@ -675,6 +677,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
{
/*
//Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
struct timeval currentTime;
@ -682,6 +685,10 @@ GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
//Return timestamp of system uptime
return ((currentTime.tv_sec*1000)+(currentTime.tv_usec/1000)-m_start_time);
*/
double now = CFAbsoluteTimeGetCurrent();
return 1000 * (now - m_start_time_2);
}
@ -1392,7 +1399,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletProximity(void *eventPtr)
return GHOST_kFailure;
}
GHOST_TabletData& ct = window->GetCocoaTabletData();
// don't involve the window!
// GHOST_TabletData& ct = window->GetCocoaTabletData();
GHOST_TTabletMode active_tool;
int* tool_id_ptr;
@ -1423,27 +1431,43 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletProximity(void *eventPtr)
printf("entering\n");
*tool_id_ptr = [event deviceID];
ct.Active = active_tool;
ct.Pressure = (active_tool == GHOST_kTabletModeNone) ? /*mouse*/ 1 : /*pen*/ 0;
ct.Xtilt = 0;
ct.Ytilt = 0;
m_tablet_pen_mode = active_tool;
// ct.Active = active_tool;
// ct.Pressure = (active_tool == GHOST_kTabletModeNone) ? /*mouse*/ 1 : /*pen*/ 0;
// ct.Xtilt = 0;
// ct.Ytilt = 0;
// this is a good place to remember the tool's capabilities
// (later though, after tablet mouse is fixed and (not) coalescing is in place)
}
else {
printf("leaving\n");
*tool_id_ptr = TOOL_ID_NONE;
ct.Active = GHOST_kTabletModeNone;
ct.Pressure = 0;
ct.Xtilt = 0;
ct.Ytilt = 0;
m_tablet_pen_mode = GHOST_kTabletModeNone;
// ct.Active = GHOST_kTabletModeNone;
// ct.Pressure = 0;
// ct.Xtilt = 0;
// ct.Ytilt = 0;
}
return GHOST_kSuccess;
}
void GHOST_SystemCocoa::fillTabletData(GHOST_TabletData& tablet, void* event_ptr)
{
NSEvent* event = (NSEvent*)event_ptr;
NSPoint tilt = [event tilt];
tablet.Active = m_tablet_pen_mode;
tablet.Pressure = [event pressure];
tablet.Xtilt = tilt.x;
tablet.Ytilt = tilt.y;
printf("> pressure = %.2f tilt = %.2f %2f\n", tablet.Pressure, tablet.Xtilt, tablet.Ytilt);
}
GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
{
puts("tablet point");
@ -1456,35 +1480,49 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
return GHOST_kFailure;
}
/*
// don't involve the window!
GHOST_TabletData& ct = window->GetCocoaTabletData();
ct.Pressure = [event pressure];
NSPoint tilt = [event tilt];
ct.Xtilt = tilt.x;
ct.Ytilt = tilt.y;
*/
switch ([event type])
{
case NSLeftMouseDown:
{
if (m_input_fidelity_hint == HI_FI)
{
printf("hi-fi on\n");
[NSEvent setMouseCoalescingEnabled:NO];
}
pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
GHOST_EventButton* e = new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber]));
GHOST_TEventButtonData* data = (GHOST_TEventButtonData*) e->getData();
fillTabletData(data->tablet, event);
pushEvent(e);
break;
}
case NSLeftMouseUp:
{
if (m_input_fidelity_hint == HI_FI)
{
printf("hi-fi off\n");
[NSEvent setMouseCoalescingEnabled:YES];
}
// no tablet data needed for 'pen up'
pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
break;
}
default:
{
NSPoint pos = [event locationInWindow];
pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, pos.x, pos.y));
GHOST_EventCursor* e = new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, pos.x, pos.y);
GHOST_TEventCursorData* data = (GHOST_TEventCursorData*) e->getData();
fillTabletData(data->tablet, event);
pushEvent(e);
break;
}
}

@ -222,11 +222,8 @@ public:
const GHOST_TabletData* GetTabletData()
{ return &m_tablet; }
{ return NULL; }
GHOST_TabletData& GetCocoaTabletData()
{ return m_tablet; }
/**
* Sets the progress bar value displayed in the window/application icon
* @param progress The progress % (0.0 to 1.0)
@ -300,9 +297,6 @@ protected:
static NSOpenGLContext *s_firstOpenGLcontext;
NSCursor* m_customCursor;
GHOST_TabletData m_tablet;
};
#endif // _GHOST_WINDOW_COCOA_H_

@ -39,7 +39,7 @@
#include <OpenGL/OpenGL.h>
*/
#include "GHOST_WindowCocoa.h"
#include "GHOST_SystemCocoa.h"
#include "GHOST_Debug.h"
@ -161,12 +161,12 @@ extern "C" {
{
NSPoint mouseLocation = [sender draggingLocation];
NSPasteboard *draggingPBoard = [sender draggingPasteboard];
if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap;
else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames;
else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString;
else return NSDragOperationNone;
associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default
systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
return NSDragOperationCopy;
@ -180,7 +180,7 @@ extern "C" {
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
NSPoint mouseLocation = [sender draggingLocation];
systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
return associatedWindow->canAcceptDragOperation()?NSDragOperationCopy:NSDragOperationNone;
}
@ -205,7 +205,7 @@ extern "C" {
NSPasteboard *draggingPBoard = [sender draggingPasteboard];
NSImage *droppedImg;
id data;
switch (m_draggedObjectType) {
case GHOST_kDragnDropTypeBitmap:
if([NSImage canInitWithPasteboard:draggingPBoard]) {
@ -242,7 +242,7 @@ extern "C" {
- (BOOL)acceptsFirstResponder
{
return YES;
return YES;
}
//The trick to prevent Cocoa from complaining (beeping)
@ -254,10 +254,10 @@ extern "C" {
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
NSString *chars = [theEvent charactersIgnoringModifiers];
if ([chars length] <1)
return NO;
//Let cocoa handle menu shortcuts
switch ([chars characterAtIndex:0]) {
case 'q':
@ -277,7 +277,7 @@ extern "C" {
- (BOOL)isOpaque
{
return YES;
return YES;
}
@end
@ -304,22 +304,21 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40];
NSOpenGLPixelFormat *pixelFormat = nil;
int i;
m_systemCocoa = systemCocoa;
m_fullScreen = false;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//Creates the window
NSRect rect;
NSSize minSize;
rect.origin.x = left;
rect.origin.y = top;
rect.size.width = width;
rect.size.height = height;
m_window = [[CocoaWindow alloc] initWithContentRect:rect
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
backing:NSBackingStoreBuffered defer:NO];
@ -327,75 +326,75 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[pool drain];
return;
}
[m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
//Forbid to resize the window below the blender defined minimum one
minSize.width = 320;
minSize.height = 240;
[m_window setContentMinSize:minSize];
setTitle(title);
// Pixel Format Attributes for the windowed NSOpenGLContext
i=0;
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext objects flushBuffer
// needed for 'Draw Overlap' drawing method
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
if (numOfAASamples>0) {
// Multisample anti-aliasing
pixelFormatAttrsWindow[i++] = NSOpenGLPFAMultisample;
pixelFormatAttrsWindow[i++] = NSOpenGLPFASampleBuffers;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 1;
pixelFormatAttrsWindow[i++] = NSOpenGLPFASamples;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) numOfAASamples;
pixelFormatAttrsWindow[i++] = NSOpenGLPFANoRecovery;
}
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
//Fall back to no multisampling if Antialiasing init failed
if (pixelFormat == nil) {
i=0;
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext objects flushBuffer
// needed for 'Draw Overlap' drawing method
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
}
if (numOfAASamples>0) { //Set m_numOfAASamples to the actual value
GLint gli;
[pixelFormat getValues:&gli forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
@ -404,40 +403,38 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
printf("GHOST_Window could be created with anti-aliasing of only %i samples\n",m_numOfAASamples);
}
}
//Creates the OpenGL View inside the window
m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
pixelFormat:pixelFormat];
[pixelFormat release];
m_openGLContext = [m_openGLView openGLContext]; //This context will be replaced by the proper one just after
[m_window setContentView:m_openGLView];
[m_window setInitialFirstResponder:m_openGLView];
[m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
[m_window makeKeyAndOrderFront:nil];
setDrawingContextType(type);
updateDrawingContext();
activateDrawingContext();
m_tablet.Active = GHOST_kTabletModeNone;
CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
[windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
[m_window setDelegate:windowDelegate];
[m_window setAcceptsMouseMovedEvents:YES];
[m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType, NSTIFFPboardType, nil]];
if (state == GHOST_kWindowStateFullScreen)
setState(GHOST_kWindowStateFullScreen);
[pool drain];
}
@ -448,14 +445,14 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[m_openGLView release];
if (m_window) {
[m_window close];
[[m_window delegate] release];
[m_window release];
m_window = nil;
}
//Check for other blender opened windows and make the frontmost key
NSArray *windowsList = [NSApp orderedWindows];
if ([windowsList count]) {
@ -478,7 +475,7 @@ void* GHOST_WindowCocoa::getOSWindow() const
void GHOST_WindowCocoa::setTitle(const STR_String& title)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *windowTitle = [[NSString alloc] initWithUTF8String:title];

@ -132,7 +132,6 @@ void mul_fac_qt_fl(float *q, float fac)
q[1]*= si;
q[2]*= si;
q[3]*= si;
}
void quat_to_mat3(float m[][3], float *q)
@ -308,7 +307,6 @@ void mat3_to_quat_is_ok(float q[4], float wmat[3][3])
mul_qt_qtqt(q, q1, q2);
}
void normalize_qt(float *q)
{
float len;
@ -585,7 +583,7 @@ void axis_angle_to_quat(float q[4], float axis[3], float angle)
}
/* Quaternions to Axis Angle */
void quat_to_axis_angle(float axis[3], float *angle,float q[4])
void quat_to_axis_angle(float axis[3], float *angle, float q[4])
{
float ha, si;
@ -687,7 +685,7 @@ void mat4_to_axis_angle(float axis[3], float *angle,float mat[4][4])
}
/****************************** Vector/Rotation ******************************/
/* TODO: the following calls should probably be depreceated sometime */
/* TODO: the following calls should probably be deprecated sometime */
/* 3x3 matrix to axis angle */
void mat3_to_vec_rot(float axis[3], float *angle,float mat[3][3])

@ -1233,6 +1233,8 @@ static int gpencil_draw_cancel (bContext *C, wmOperator *op)
/* create a new stroke point at the point indicated by the painting context */
static void gpencil_draw_apply (bContext *C, wmOperator *op, tGPsdata *p)
{
printf("< pressure = %.2f\n", p->pressure);
/* handle drawing/erasing -> test for erasing first */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* do 'live' erasing now */
@ -1245,6 +1247,7 @@ static void gpencil_draw_apply (bContext *C, wmOperator *op, tGPsdata *p)
}
/* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */
else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
/* try to add point */
short ok= gp_stroke_addpoint(p, p->mval, p->pressure);
@ -1293,11 +1296,18 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even
wmTabletData *wmtab= event->customdata;
tablet= (wmtab->Active != EVT_TABLET_NONE);
p->pressure= wmtab->Pressure;
if (wmtab->Active == EVT_TABLET_ERASER)
if (wmtab->Active == EVT_TABLET_ERASER) {
// TODO... this should get caught by the keymaps which call drawing in the first place
// .. but until that's possible, duct tape the eraser function back on
p->paintmode = GP_PAINTMODE_ERASER;
p->pressure = wmtab->Pressure;
}
else {
/* 20% to 200% of normal mouse-based strength */
p->pressure = 1.8 * wmtab->Pressure + 0.2;
}
}
else
p->pressure= 1.0f;

@ -313,7 +313,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
QUATCOPY(vod->oldquat, rv3d->viewquat);
vod->origx= vod->oldx= event->x;
vod->origy= vod->oldy= event->y;
vod->origkey= event->type; /* the key that triggered the operator. */
vod->origkey= event->type; /* the key that triggered the operator. */
vod->use_dyn_ofs= (U.uiflag & USER_ORBIT_SELECTION) ? 1:0;
if (vod->use_dyn_ofs) {
@ -351,7 +351,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
negate_v3(my_pivot); /* ofs is flipped */
/* find a new ofs value that is allong the view axis (rather then the mouse location) */
/* find a new ofs value that is along the view axis (rather then the mouse location) */
closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
vod->dist0 = rv3d->dist = len_v3v3(my_pivot, dvec);
@ -498,7 +498,6 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
}
static void viewrotate_apply(ViewOpsData *vod, int x, int y)
@ -602,7 +601,6 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
int i;
float viewmat[3][3];
quat_to_mat3( viewmat,rv3d->viewquat);
for (i = 0 ; i < 39; i++){
@ -759,7 +757,6 @@ static int view3d_rotate_poll(bContext *C)
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Rotate view";
ot->description = "Rotate the view";
@ -774,6 +771,169 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
}
// returns angular velocity (0..1), fills axis of rotation
// (shouldn't live in this file!)
float ndof_to_angle_axis(const float ndof[3], float axis[3])
{
const float x = ndof[0];
const float y = ndof[1];
const float z = ndof[2];
float angular_velocity = sqrtf(x*x + y*y + z*z);
float scale = 1.f / angular_velocity;
// normalize
axis[0] = scale * x;
axis[1] = scale * y;
axis[2] = scale * z;
return angular_velocity;
}
static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
float dt = ndof->dt;
RegionView3D* rv3d = CTX_wm_region_view3d(C);
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
float phi, q1[4];
float m[3][3];
float m_inv[3][3];
float xvec[3] = {1,0,0};
const float sensitivity = 0.035;
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3(m,rv3d->viewquat);
invert_m3_m3(m_inv,m);
/* Determine the direction of the x vector (for rotating up and down) */
/* This can likely be computed directly from the quaternion. */
mul_m3_v3(m_inv,xvec);
/* Perform the up/down rotation */
phi = sensitivity * -ndof->rx;
q1[0] = cos(phi);
mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
/* Perform the orbital rotation */
phi = sensitivity * ndof->rz;
q1[0] = cos(phi);
q1[1] = q1[2] = 0.0;
q1[3] = sin(phi);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
static int viewndof_invoke_1st_try(bContext *C, wmOperator *op, wmEvent *event)
{
wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
float dt = ndof->dt;
RegionView3D *rv3d= CTX_wm_region_view3d(C);
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
/* very simple for now, move viewpoint along world axes */
rv3d->ofs[0] += dt * ndof->tx;
rv3d->ofs[1] += dt * ndof->ty;
rv3d->ofs[2] += dt * ndof->tz;
// request_depth_update(CTX_wm_region_view3d(C)); /* need this? */
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
static int viewndof_invoke_2nd_try(bContext *C, wmOperator *op, wmEvent *event)
{
wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
float dt = ndof->dt;
RegionView3D* rv3d = CTX_wm_region_view3d(C);
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
float axis[3];
float angle = ndof_to_angle_axis(&(ndof->rx), axis);
float eyeball_q[4];// = {0.f};
// float* eyeball_v = eyeball_q + 1;
axis_angle_to_quat(eyeball_q, axis, angle);
float eye_conj[4];
copy_qt_qt(eye_conj, eyeball_q);
conjugate_qt(eye_conj);
// float mat[3][3];
// quat_to_mat3(mat, rv3d->viewquat);
/*
eyeball_v[0] = dt * ndof->tx;
eyeball_v[1] = dt * ndof->ty;
eyeball_v[2] = dt * ndof->tz;
*/
// mul_m3_v3(mat, eyeball_vector);
// mul_qt_v3(rv3d->viewquat, eyeball_vector);
// doesn't this transform v?
// v' = (q)(v)(~q)
float view_q[4];
copy_qt_qt(view_q, rv3d->viewquat);
// float q_conj[4];
// copy_qt_qt(q_conj, q);
// conjugate_qt(q_conj);
mul_qt_qtqt(view_q, eyeball_q, view_q);
mul_qt_qtqt(view_q, view_q, eye_conj);
// mul_qt_qtqt(eyeball_q, q, eyeball_q);
// mul_qt_qtqt(eyeball_q, eyeball_q, q_conj);
// add_v3_v3(rv3d->ofs, eyeball_v);
copy_qt_qt(rv3d->viewquat, view_q);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
void VIEW3D_OT_ndof(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Navigate view";
ot->description = "Navigate the view using a 3D mouse.";
ot->idname = "VIEW3D_OT_ndof";
/* api callbacks */
ot->invoke = viewndof_invoke;
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = 0;
}
/* ************************ viewmove ******************************** */
@ -839,7 +999,6 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewOpsData *vod= op->customdata;
short event_code= VIEW_PASS;
@ -2650,397 +2809,3 @@ int view_autodist_depth(struct ARegion *ar, short *mval, int margin, float *dept
return (*depth==FLT_MAX) ? 0:1;
return 0;
}
/* ********************* NDOF ************************ */
/* note: this code is confusing and unclear... (ton) */
/* **************************************************** */
// ndof scaling will be moved to user setting.
// In the mean time this is just a place holder.
// Note: scaling in the plugin and ghostwinlay.c
// should be removed. With driver default setting,
// each axis returns approx. +-200 max deflection.
// The values I selected are based on the older
// polling i/f. With event i/f, the sensistivity
// can be increased for improved response from
// small deflections of the device input.
// lukep notes : i disagree on the range.
// the normal 3Dconnection driver give +/-400
// on defaut range in other applications
// and up to +/- 1000 if set to maximum
// because i remove the scaling by delta,
// which was a bad idea as it depend of the system
// speed and os, i changed the scaling values, but
// those are still not ok
float ndof_axis_scale[6] = {
+0.01, // Tx
+0.01, // Tz
+0.01, // Ty
+0.0015, // Rx
+0.0015, // Rz
+0.0015 // Ry
};
void filterNDOFvalues(float *sbval)
{
int i=0;
float max = 0.0;
for (i =0; i<6;i++)
if (fabs(sbval[i]) > max)
max = fabs(sbval[i]);
for (i =0; i<6;i++)
if (fabs(sbval[i]) != max )
sbval[i]=0.0;
}
// statics for controlling rv3d->dist corrections.
// viewmoveNDOF zeros and adjusts rv3d->ofs.
// viewmove restores based on dz_flag state.
int dz_flag = 0;
float m_dist;
void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
{
RegionView3D *rv3d= ar->regiondata;
int i;
float phi;
float dval[7];
// static fval[6] for low pass filter; device input vector is dval[6]
static float fval[6];
float tvec[3],rvec[3];
float q1[4];
float mat[3][3];
float upvec[3];
/*----------------------------------------------------
* sometimes this routine is called from headerbuttons
* viewmove needs to refresh the screen
*/
// XXX areawinset(ar->win);
// fetch the current state of the ndof device
// XXX getndof(dval);
if (v3d->ndoffilter)
filterNDOFvalues(fval);
// Scale input values
// if(dval[6] == 0) return; // guard against divide by zero
for(i=0;i<6;i++) {
// user scaling
dval[i] = dval[i] * ndof_axis_scale[i];
}
// low pass filter with zero crossing reset
for(i=0;i<6;i++) {
if((dval[i] * fval[i]) >= 0)
dval[i] = (fval[i] * 15 + dval[i]) / 16;
else
fval[i] = 0;
}
// force perspective mode. This is a hack and is
// incomplete. It doesn't actually effect the view
// until the first draw and doesn't update the menu
// to reflect persp mode.
rv3d->persp = RV3D_PERSP;
// Correct the distance jump if rv3d->dist != 0
// This is due to a side effect of the original
// mouse view rotation code. The rotation point is
// set a distance in front of the viewport to
// make rotating with the mouse look better.
// The distance effect is written at a low level
// in the view management instead of the mouse
// view function. This means that all other view
// movement devices must subtract this from their
// view transformations.
if(rv3d->dist != 0.0) {
dz_flag = 1;
m_dist = rv3d->dist;
upvec[0] = upvec[1] = 0;
upvec[2] = rv3d->dist;
copy_m3_m4(mat, rv3d->viewinv);
mul_m3_v3(mat, upvec);
sub_v3_v3(rv3d->ofs, upvec);
rv3d->dist = 0.0;
}
// Apply rotation
// Rotations feel relatively faster than translations only in fly mode, so
// we have no choice but to fix that here (not in the plugins)
rvec[0] = -0.5 * dval[3];
rvec[1] = -0.5 * dval[4];
rvec[2] = -0.5 * dval[5];
// rotate device x and y by view z
copy_m3_m4(mat, rv3d->viewinv);
mat[2][2] = 0.0f;
mul_m3_v3(mat, rvec);
// rotate the view
phi = normalize_v3(rvec);
if(phi != 0) {
axis_angle_to_quat(q1,rvec,phi);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
}
// Apply translation
tvec[0] = dval[0];
tvec[1] = dval[1];
tvec[2] = -dval[2];
// the next three lines rotate the x and y translation coordinates
// by the current z axis angle
copy_m3_m4(mat, rv3d->viewinv);
mat[2][2] = 0.0f;
mul_m3_v3(mat, tvec);
// translate the view
sub_v3_v3(rv3d->ofs, tvec);
/*----------------------------------------------------
* refresh the screen XXX
*/
// update render preview window
// XXX BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
}
void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
{
RegionView3D *rv3d= ar->regiondata;
float fval[7];
float dvec[3];
float sbadjust = 1.0f;
float len;
short use_sel = 0;
Object *ob = OBACT;
float m[3][3];
float m_inv[3][3];
float xvec[3] = {1,0,0};
float yvec[3] = {0,-1,0};
float zvec[3] = {0,0,1};
float phi;
float q1[4];
float obofs[3];
float reverse;
//float diff[4];
float d, curareaX, curareaY;
float mat[3][3];
float upvec[3];
/* Sensitivity will control how fast the view rotates. The value was
* obtained experimentally by tweaking until the author didn't get dizzy watching.
* Perhaps this should be a configurable user parameter.
*/
float psens = 0.005f * (float) U.ndof_pan; /* pan sensitivity */
float rsens = 0.005f * (float) U.ndof_rotate; /* rotate sensitivity */
float zsens = 0.3f; /* zoom sensitivity */
const float minZoom = -30.0f;
const float maxZoom = 300.0f;
//reset view type
rv3d->view = 0;
//printf("passing here \n");
//
if (scene->obedit==NULL && ob && !(ob->mode & OB_MODE_POSE)) {
use_sel = 1;
}
if((dz_flag)||rv3d->dist==0) {
dz_flag = 0;
rv3d->dist = m_dist;
upvec[0] = upvec[1] = 0;
upvec[2] = rv3d->dist;
copy_m3_m4(mat, rv3d->viewinv);
mul_m3_v3(mat, upvec);
add_v3_v3(rv3d->ofs, upvec);
}
/*----------------------------------------------------
* sometimes this routine is called from headerbuttons
* viewmove needs to refresh the screen
*/
// XXX areawinset(curarea->win);
/*----------------------------------------------------
* record how much time has passed. clamp at 10 Hz
* pretend the previous frame occurred at the clamped time
*/
// now = PIL_check_seconds_timer();
// frametime = (now - prevTime);
// if (frametime > 0.1f){ /* if more than 1/10s */
// frametime = 1.0f/60.0; /* clamp at 1/60s so no jumps when starting to move */
// }
// prevTime = now;
// sbadjust *= 60 * frametime; /* normalize ndof device adjustments to 100Hz for framerate independence */
/* fetch the current state of the ndof device & enforce dominant mode if selected */
// XXX getndof(fval);
if (v3d->ndoffilter)
filterNDOFvalues(fval);
// put scaling back here, was previously in ghostwinlay
fval[0] = fval[0] * (1.0f/600.0f);
fval[1] = fval[1] * (1.0f/600.0f);
fval[2] = fval[2] * (1.0f/1100.0f);
fval[3] = fval[3] * 0.00005f;
fval[4] =-fval[4] * 0.00005f;
fval[5] = fval[5] * 0.00005f;
fval[6] = fval[6] / 1000000.0f;
// scale more if not in perspective mode
if (rv3d->persp == RV3D_ORTHO) {
fval[0] = fval[0] * 0.05f;
fval[1] = fval[1] * 0.05f;
fval[2] = fval[2] * 0.05f;
fval[3] = fval[3] * 0.9f;
fval[4] = fval[4] * 0.9f;
fval[5] = fval[5] * 0.9f;
zsens *= 8;
}
/* set object offset */
if (ob) {
obofs[0] = -ob->obmat[3][0];
obofs[1] = -ob->obmat[3][1];
obofs[2] = -ob->obmat[3][2];
}
else {
VECCOPY(obofs, rv3d->ofs);
}
/* calc an adjustment based on distance from camera
disabled per patch 14402 */
d = 1.0f;
/* if (ob) {
sub_v3_v3v3(diff, obofs, rv3d->ofs);
d = len_v3(diff);
}
*/
reverse = (rv3d->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
/*----------------------------------------------------
* ndof device pan
*/
psens *= 1.0f + d;
curareaX = sbadjust * psens * fval[0];
curareaY = sbadjust * psens * fval[1];
dvec[0] = curareaX * rv3d->persinv[0][0] + curareaY * rv3d->persinv[1][0];
dvec[1] = curareaX * rv3d->persinv[0][1] + curareaY * rv3d->persinv[1][1];
dvec[2] = curareaX * rv3d->persinv[0][2] + curareaY * rv3d->persinv[1][2];
add_v3_v3(rv3d->ofs, dvec);
/*----------------------------------------------------
* ndof device dolly
*/
len = zsens * sbadjust * fval[2];
if (rv3d->persp==RV3D_CAMOB) {
if(rv3d->persp==RV3D_CAMOB) { /* This is stupid, please fix - TODO */
rv3d->camzoom+= 10.0f * -len;
}
if (rv3d->camzoom < minZoom) rv3d->camzoom = minZoom;
else if (rv3d->camzoom > maxZoom) rv3d->camzoom = maxZoom;
}
else if ((rv3d->dist> 0.001*v3d->grid) && (rv3d->dist<10.0*v3d->far)) {
rv3d->dist*=(1.0 + len);
}
/*----------------------------------------------------
* ndof device turntable
* derived from the turntable code in viewmove
*/
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3( m,rv3d->viewquat);
invert_m3_m3(m_inv,m);
/* Determine the direction of the x vector (for rotating up and down) */
/* This can likely be compuated directly from the quaternion. */
mul_m3_v3(m_inv,xvec);
mul_m3_v3(m_inv,yvec);
mul_m3_v3(m_inv,zvec);
/* Perform the up/down rotation */
phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
q1[0] = cos(phi);
mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (use_sel) {
conjugate_qt(q1); /* conj == inv for unit quat */
sub_v3_v3(rv3d->ofs, obofs);
mul_qt_v3(q1, rv3d->ofs);
add_v3_v3(rv3d->ofs, obofs);
}
/* Perform the orbital rotation */
/* Perform the orbital rotation
If the seen Up axis is parallel to the zoom axis, rotation should be
achieved with a pure Roll motion (no Spin) on the device. When you start
to tilt, moving from Top to Side view, Spinning will increasingly become
more relevant while the Roll component will decrease. When a full
Side view is reached, rotations around the world's Up axis are achieved
with a pure Spin-only motion. In other words the control of the spinning
around the world's Up axis should move from the device's Spin axis to the
device's Roll axis depending on the orientation of the world's Up axis
relative to the screen. */
//phi = sbadjust * rsens * reverse * fval[4]; /* spin the knob, y axis */
phi = sbadjust * rsens * (yvec[2] * fval[4] + zvec[2] * fval[5]);
q1[0] = cos(phi);
q1[1] = q1[2] = 0.0;
q1[3] = sin(phi);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (use_sel) {
conjugate_qt(q1);
sub_v3_v3(rv3d->ofs, obofs);
mul_qt_v3(q1, rv3d->ofs);
add_v3_v3(rv3d->ofs, obofs);
}
/*----------------------------------------------------
* refresh the screen
*/
// XXX scrarea_do_windraw(curarea);
}

@ -71,6 +71,7 @@ void view3d_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_zoom(struct wmOperatorType *ot);
void VIEW3D_OT_move(struct wmOperatorType *ot);
void VIEW3D_OT_rotate(struct wmOperatorType *ot);
void VIEW3D_OT_ndof(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot);
void VIEW3D_OT_view_selected(struct wmOperatorType *ot);
@ -98,8 +99,6 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, struct ARegion *ar,
struct bAnimVizSettings *avs, struct bMotionPath *mpath);
void draw_motion_paths_cleanup(Scene *scene, View3D *v3d, struct ARegion *ar);
/* drawobject.c */
void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag);
int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
@ -192,4 +191,3 @@ void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, st
#endif /* ED_VIEW3D_INTERN_H */

@ -28,6 +28,7 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h> // [mce] debug, remove when finished
#include "MEM_guardedalloc.h"
@ -61,6 +62,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_rotate);
WM_operatortype_append(VIEW3D_OT_move);
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_ndof);
WM_operatortype_append(VIEW3D_OT_view_all);
WM_operatortype_append(VIEW3D_OT_viewnumpad);
WM_operatortype_append(VIEW3D_OT_view_orbit);
@ -155,12 +157,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
/* 3D mouse */
WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON1, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof", NDOF_MOTION, 0, 0, 0);
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD2, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPDOWN);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD4, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_persportho", PAD5, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD6, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
@ -300,4 +307,3 @@ void view3d_keymap(wmKeyConfig *keyconf)
viewmove_modal_keymap(keyconf);
viewzoom_modal_keymap(keyconf);
}

@ -47,10 +47,10 @@ struct wmTimer;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
#ifdef WIN32
#undef near
#undef far
#define near clipsta
#define far clipend
#undef near
#undef far
#define near clipsta
#define far clipend
#endif
#include "DNA_listBase.h"
@ -137,12 +137,12 @@ typedef struct View3D {
float blockscale;
short blockhandler[8];
float viewquat[4], dist, pad1; /* XXX depricated */
float viewquat[4], dist, pad1; /* XXX deprecated */
int lay_used; /* used while drawing */
short persp; /* XXX depricated */
short view; /* XXX depricated */
short persp; /* XXX deprecated */
short view; /* XXX deprecated */
struct Object *camera, *ob_centre;
@ -298,5 +298,3 @@ typedef struct View3D {
#define V3D_BGPIC_EXPANDED 2
#endif

@ -346,6 +346,7 @@ typedef struct wmEvent {
} wmEvent;
/* ************** custom wmEvent data ************** */
typedef struct wmTabletData {
int Active; /* 0=EVT_TABLET_NONE, 1=EVT_TABLET_STYLUS, 2=EVT_TABLET_ERASER */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
@ -371,6 +372,19 @@ typedef struct wmTimer {
int sleep; /* internal, put timers to sleep when needed */
} wmTimer;
typedef struct {
/* awfully similar to GHOST_TEventNDOFMotionData... */
/* Each component normally ranges from -1 to +1, but can exceed that. */
float tx, ty, tz; /* translation: -x left, +y forward, -z up */
float rx, ry, rz; /* rotation:
axis = (rx,ry,rz).normalized
amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] */
float dt; // time since previous NDOF Motion event (or zero if this is the first)
} wmNDOFMotionData;
typedef struct wmOperatorType {
struct wmOperatorType *next, *prev;

File diff suppressed because it is too large Load Diff

@ -796,8 +796,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
}
}
break;
}
@ -805,7 +803,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
wm_event_add_ghostevent(wm, win, type, time, data);
break;
}
}
return 1;
}

@ -83,4 +83,3 @@ extern int circle_select_size;
#endif
#endif /* WM_H */

@ -36,42 +36,66 @@
#define WM_EVENT_TYPES_H
/* customdata type */
#define EVT_DATA_TABLET 1
#define EVT_DATA_GESTURE 2
#define EVT_DATA_TIMER 3
#define EVT_DATA_LISTBASE 4
#define EVT_DATA_TABLET 1
#define EVT_DATA_GESTURE 2
#define EVT_DATA_TIMER 3
#define EVT_DATA_LISTBASE 4
#define EVT_DATA_NDOF_MOTION 5
/* tablet active, matches GHOST_TTabletMode */
/* [mce] also matches my own TabletTool.type */
#define EVT_TABLET_NONE 0
#define EVT_TABLET_STYLUS 1
#define EVT_TABLET_ERASER 2
#define MOUSEX 0x004
#define MOUSEY 0x005
/* [mce] what are these for? */
#define MOUSEX 0x004
#define MOUSEY 0x005
/* MOUSE : 0x00x */
#define LEFTMOUSE 0x001
#define MIDDLEMOUSE 0x002
#define RIGHTMOUSE 0x003
#define MOUSEMOVE 0x004
#define LEFTMOUSE 0x001
#define MIDDLEMOUSE 0x002
#define RIGHTMOUSE 0x003
#define MOUSEMOVE 0x004
/* only use if you want user option switch possible */
#define ACTIONMOUSE 0x005
#define SELECTMOUSE 0x006
/* Extra mouse buttons */
#define BUTTON4MOUSE 0x007
#define BUTTON4MOUSE 0x007
#define BUTTON5MOUSE 0x008
/* Extra trackpad gestures */
#define MOUSEPAN 0x00e
#define MOUSEZOOM 0x00f
#define MOUSEROTATE 0x010
/* defaults from ghost */
#define WHEELUPMOUSE 0x00a
#define WHEELUPMOUSE 0x00a
#define WHEELDOWNMOUSE 0x00b
/* mapped with userdef */
#define WHEELINMOUSE 0x00c
#define WHEELOUTMOUSE 0x00d
#define INBETWEEN_MOUSEMOVE 0x011
/* NDOF (from SpaceNavigator & friends) */
#define NDOF_MOTION 0x12
enum {
NDOF_BUTTON_NONE = NDOF_MOTION, /* never sent, used during translation */
NDOF_BUTTON1,
NDOF_BUTTON2/*,
NDOF_BUTTON3,
NDOF_BUTTON4,
NDOF_BUTTON5,
NDOF_BUTTON6,
NDOF_BUTTON7,
NDOF_BUTTON8,
NDOF_BUTTON9,
NDOF_BUTTON10,
NDOF_BUTTON11,
NDOF_BUTTON12,
NDOF_BUTTON13,
NDOF_BUTTON14,
NDOF_BUTTON15,
NDOF_BUTTON16*/
};
/* SYSTEM : 0x01xx */
#define INPUTCHANGE 0x0103 /* input connected or disconnected */
@ -126,9 +150,9 @@
#define CAPSLOCKKEY 211
#define LEFTCTRLKEY 212
#define LEFTALTKEY 213
#define RIGHTALTKEY 214
#define RIGHTCTRLKEY 215
#define LEFTALTKEY 213
#define RIGHTALTKEY 214
#define RIGHTCTRLKEY 215
#define RIGHTSHIFTKEY 216
#define LEFTSHIFTKEY 217
@ -169,8 +193,8 @@
#define PADPERIOD 199
#define PADSLASHKEY 161
#define PADASTERKEY 160
#define PADSLASHKEY 161
#define PADASTERKEY 160
#define PADMINUS 162
#define PADENTER 163
@ -299,4 +323,3 @@
#endif /* WM_EVENT_TYPES_H */