merged changes to revision 23620

This commit is contained in:
Maxime Curioni
2009-10-04 01:21:33 +00:00
467 changed files with 17705 additions and 8408 deletions

View File

@@ -85,33 +85,32 @@ ENDMACRO(SETUP_LIBDIRS)
MACRO(SETUP_LIBLINKS
target)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ")
#TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIBRARY} ${LLIBS})
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS})
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS})
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
IF(WITH_PYTHON)
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LINKFLAGS})
IF(WIN32)
TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
ELSE(WIN32)
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
ENDIF(WIN32)
ENDIF(WITH_PYTHON)
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${LLIBS})
TARGET_LINK_LIBRARIES(${target} ${OPENGL_glu_LIBRARY} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB})
TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIBRARY} ${LIBSAMPLERATE_LIB})
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
IF(WIN32)
TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
ELSE(WIN32)
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
ENDIF(WIN32)
IF(WITH_INTERNATIONAL)
TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB})
IF(WIN32)
TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB})
ENDIF(WIN32)
ENDIF(WITH_INTERNATIONAL)
IF(WITH_OPENAL)
TARGET_LINK_LIBRARIES(${target} ${OPENAL_LIBRARY})
ENDIF(WITH_OPENAL)
@@ -127,9 +126,6 @@ MACRO(SETUP_LIBLINKS
IF(WITH_SDL)
TARGET_LINK_LIBRARIES(${target} ${SDL_LIBRARY})
ENDIF(WITH_SDL)
IF(WIN32)
TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB})
ENDIF(WIN32)
IF(WITH_QUICKTIME)
TARGET_LINK_LIBRARIES(${target} ${QUICKTIME_LIB})
ENDIF(WITH_QUICKTIME)

View File

@@ -81,6 +81,10 @@ OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF
OPTION(WITH_BUILDINFO "Include extra build details" ON)
OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON)
IF (APPLE)
OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" OFF)
ENDIF (APPLE)
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
@@ -402,6 +406,7 @@ IF(APPLE)
FIND_PACKAGE(OpenAL)
IF(OPENAL_FOUND)
SET(WITH_OPENAL ON)
SET(OPENAL_INCLUDE_DIR "${OPENAL_INCLUDE_DIR};${LIBDIR}/openal/include")
ELSE(OPENAL_FOUND)
SET(WITH_OPENAL OFF)
ENDIF(OPENAL_FOUND)
@@ -485,9 +490,13 @@ IF(APPLE)
SET(LLIBS stdc++ SystemStubs)
IF (WITH_COCOA)
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DGHOST_COCOA")
SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
ELSE (WITH_COCOA)
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
ENDIF (WITH_COCOA)
IF(WITH_OPENMP)
SET(LLIBS "${LLIBS} -lgomp ")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")

View File

@@ -643,7 +643,6 @@ if env['WITH_BF_DOCS']:
except: epydoc = None
if epydoc:
SConscript('source/blender/python/api2_2x/doc/SConscript')
SConscript('source/gameengine/PyDoc/SConscript')
else:
print "No epydoc install detected, Python API and Gameengine API Docs will not be generated "

View File

@@ -540,6 +540,8 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
return device->setCapability(AUD_CAPS_VOLUME, &volume);
}
catch(AUD_Exception) {}
return false;
}
int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,

View File

@@ -26,9 +26,18 @@
SET(INC . ../string)
FILE(GLOB SRC intern/*.cpp)
FILE(GLOB SRC intern/*.cpp intern/*.mm)
IF(APPLE)
IF(WITH_COCOA)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
ELSE(WITH_COCOA)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
ENDIF(WITH_COCOA)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
@@ -41,6 +50,9 @@ ELSE(APPLE)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
@@ -52,6 +64,9 @@ ELSE(APPLE)
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
ENDIF(WIN32)
ENDIF(APPLE)

View File

@@ -27,8 +27,6 @@
*/
/**
* $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* @author Maarten Gribnau
* @date September 21, 2001

View File

@@ -0,0 +1,106 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/**
* @file GHOST_DisplayManagerCocoa.h
* Declaration of GHOST_DisplayManagerCocoa class.
*/
#ifndef _GHOST_DISPLAY_MANAGER_COCOA_H_
#define _GHOST_DISPLAY_MANAGER_COCOA_H_
#ifndef __APPLE__
#error Apple only!
#endif // __APPLE__
#include "GHOST_DisplayManager.h"
/**
* Manages system displays (Mac OSX/Cocoa implementation).
* @see GHOST_DisplayManager
* @author Maarten Gribnau
* @date September 21, 2001
*/
class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager
{
public:
/**
* Constructor.
*/
GHOST_DisplayManagerCocoa(void);
/**
* Returns the number of display devices on this system.
* @param numDisplays The number of displays on this system.
* @return Indication of success.
*/
virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
/**
* Returns the number of display settings for this display device.
* @param display The index of the display to query with 0 <= display < getNumDisplays().
* @param setting The number of settings of the display device with this index.
* @return Indication of success.
*/
virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
/**
* Returns the current setting for this display device.
* @param display The index of the display to query with 0 <= display < getNumDisplays().
* @param index The setting index to be returned.
* @param setting The setting of the display device with this index.
* @return Indication of success.
*/
virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
/**
* Returns the current setting for this display device.
* @param display The index of the display to query with 0 <= display < getNumDisplays().
* @param setting The current setting of the display device with this index.
* @return Indication of success.
*/
virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
/**
* Changes the current setting for this display device.
* @param display The index of the display to query with 0 <= display < getNumDisplays().
* @param setting The current setting of the display device with this index.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
protected:
//Do not cache values as OS X supports screen hot plug
/** Cached number of displays. */
//CGDisplayCount m_numDisplays;
/** Cached display id's for each display. */
//CGDirectDisplayID* m_displayIDs;
};
#endif // _GHOST_DISPLAY_MANAGER_COCOA_H_

View File

@@ -0,0 +1,168 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Maarten Gribnau 09/2001
Damien Plisson 10/2009
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <Cocoa/Cocoa.h>
#include "GHOST_DisplayManagerCocoa.h"
#include "GHOST_Debug.h"
// We do not support multiple monitors at the moment
GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)
{
}
GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
numDisplays = (GHOST_TUns8) [[NSScreen screens] count];
[pool drain];
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
{
GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");
numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
{
//Note that only current display setting is available
NSScreen *askedDisplay;
GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (display == kMainDisplay) //Screen #0 may not be the main one
askedDisplay = [NSScreen mainScreen];
else
askedDisplay = [[NSScreen screens] objectAtIndex:display];
if(askedDisplay == nil) {
[pool drain];
return GHOST_kFailure;
}
NSRect frame = [askedDisplay visibleFrame];
setting.xPixels = frame.size.width;
setting.yPixels = frame.size.height;
setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
setting.frequency = 0; //No more CRT display...
#ifdef GHOST_DEBUG
printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
#endif // GHOST_DEBUG
[pool drain];
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
{
NSScreen *askedDisplay;
GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (display == kMainDisplay) //Screen #0 may not be the main one
askedDisplay = [NSScreen mainScreen];
else
askedDisplay = [[NSScreen screens] objectAtIndex:display];
if(askedDisplay == nil) {
[pool drain];
return GHOST_kFailure;
}
NSRect frame = [askedDisplay visibleFrame];
setting.xPixels = frame.size.width;
setting.yPixels = frame.size.height;
setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
setting.frequency = 0; //No more CRT display...
#ifdef GHOST_DEBUG
printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
#endif // GHOST_DEBUG
[pool drain];
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
{
GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
#ifdef GHOST_DEBUG
printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
printf(" setting.xPixels=%d\n", setting.xPixels);
printf(" setting.yPixels=%d\n", setting.yPixels);
printf(" setting.bpp=%d\n", setting.bpp);
printf(" setting.frequency=%d\n", setting.frequency);
#endif // GHOST_DEBUG
//Display configuration is no more available in 10.6
/* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
m_displayIDs[display],
(size_t)setting.bpp,
(size_t)setting.xPixels,
(size_t)setting.yPixels,
(CGRefreshRate)setting.frequency,
NULL);*/
#ifdef GHOST_DEBUG
printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
printf(" setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
printf(" setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
printf(" setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
#endif // GHOST_DEBUG
//CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
return /*err == CGDisplayNoErr ? GHOST_kSuccess :*/ GHOST_kFailure;
}

View File

@@ -44,7 +44,11 @@
# include "GHOST_SystemWin32.h"
#else
# ifdef __APPLE__
# ifdef GHOST_COCOA
# include "GHOST_SystemCocoa.h"
# else
# include "GHOST_SystemCarbon.h"
# endif
# else
# include "GHOST_SystemX11.h"
# endif
@@ -62,7 +66,11 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = new GHOST_SystemWin32 ();
#else
# ifdef __APPLE__
# ifdef GHOST_COCOA
m_system = new GHOST_SystemCocoa ();
# else
m_system = new GHOST_SystemCarbon ();
# endif
# else
m_system = new GHOST_SystemX11 ();
# endif

View File

@@ -0,0 +1,274 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Maarten Gribnau 05/2001
* Damien Plisson 09/2009
*
* ***** END GPL LICENSE BLOCK *****
*/
/**
* @file GHOST_SystemCocoa.h
* Declaration of GHOST_SystemCocoa class.
*/
#ifndef _GHOST_SYSTEM_COCOA_H_
#define _GHOST_SYSTEM_COCOA_H_
#ifndef __APPLE__
#error Apple OSX only!
#endif // __APPLE__
//#define __CARBONSOUND__
#include "GHOST_System.h"
class GHOST_EventCursor;
class GHOST_EventKey;
class GHOST_EventWindow;
class GHOST_SystemCocoa : public GHOST_System {
public:
/**
* Constructor.
*/
GHOST_SystemCocoa();
/**
* Destructor.
*/
~GHOST_SystemCocoa();
/***************************************************************************************
** Time(r) functionality
***************************************************************************************/
/**
* Returns the system time.
* Returns the number of milliseconds since the start of the system process.
* Based on ANSI clock() routine.
* @return The number of milliseconds.
*/
virtual GHOST_TUns64 getMilliSeconds() const;
/***************************************************************************************
** Display/window management functionality
***************************************************************************************/
/**
* Returns the number of displays on this system.
* @return The number of displays.
*/
virtual GHOST_TUns8 getNumDisplays() const;
/**
* Returns the dimensions of the main display on this system.
* @return The dimension of the main display.
*/
virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
/**
* Create a new window.
* The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
* @param title The name of the window (displayed in the title bar of the window if the OS supports it).
* @param left The coordinate of the left edge of the window.
* @param top The coordinate of the top edge of the window.
* @param width The width the window.
* @param height The height the window.
* @param state The state of the window when opened.
* @param type The type of drawing context installed in this window.
* @param parentWindow Parent (embedder) window
* @return The new window (or 0 if creation failed).
*/
virtual GHOST_IWindow* createWindow(
const STR_String& title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
const GHOST_TEmbedderWindowID parentWindow = 0
);
virtual GHOST_TSuccess beginFullScreen(
const GHOST_DisplaySetting& setting,
GHOST_IWindow** window,
const bool stereoVisual
);
virtual GHOST_TSuccess endFullScreen( void );
/***************************************************************************************
** Event management functionality
***************************************************************************************/
/**
* Gets events from the system and stores them in the queue.
* @param waitForEvent Flag to wait for an event (or return immediately).
* @return Indication of the presence of events.
*/
virtual bool processEvents(bool waitForEvent);
/***************************************************************************************
** Cursor management functionality
***************************************************************************************/
/**
* Returns the current location of the cursor (location in screen coordinates)
* @param x The x-coordinate of the cursor.
* @param y The y-coordinate of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
/**
* Updates the location of the cursor (location in screen coordinates).
* @param x The x-coordinate of the cursor.
* @param y The y-coordinate of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
/***************************************************************************************
** Access to mouse button and keyboard states.
***************************************************************************************/
/**
* Returns the state of all modifier keys.
* @param keys The state of all modifier keys (true == pressed).
* @return Indication of success.
*/
virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
/**
* Returns the state of the mouse buttons (ouside the message queue).
* @param buttons The state of the buttons.
* @return Indication of success.
*/
virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
/**
* Returns Clipboard data
* @param selection Indicate which buffer to return
* @return Returns the selected buffer
*/
virtual GHOST_TUns8* getClipboard(bool selection) const;
/**
* Puts buffer to system clipboard
* @param buffer The buffer to be copied
* @param selection Indicates which buffer to copy too, only used on X11
*/
virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
protected:
/**
* Initializes the system.
* For now, it justs registers the window class (WNDCLASS).
* @return A success value.
*/
virtual GHOST_TSuccess init();
/**
* Closes the system down.
* @return A success value.
*/
virtual GHOST_TSuccess exit();
/**
* Handles a tablet event.
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
* @return Indication whether the event was handled.
*/
int handleTabletEvent(void *eventPtr);
/**
* Handles a mouse event.
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
* @return Indication whether the event was handled.
*/
int handleMouseEvent(void *eventPtr);
/**
* Handles a key event.
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
* @return Indication whether the event was handled.
*/
int handleKeyEvent(void *eventPtr);
/**
* Handles a window event.
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
* @return Indication whether the event was handled.
*/
int handleWindowEvent(void *eventPtr);
/**
* Handles all basic Mac application stuff for a mouse down event.
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
* @return Indication whether the event was handled.
*/
// bool handleMouseDown(void *eventPtr);
/**
* Handles a Mac menu command.
* @param menuResult A Mac menu/item identifier.
* @return Indication whether the event was handled.
*/
// bool handleMenuCommand(GHOST_TInt32 menuResult);
/* callback for blender generated events */
// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
/**
* Callback for Mac Timer tasks that expire.
* @param tmTask Pointer to the timer task that expired.
*/
//static void s_timerCallback(TMTaskPtr tmTask);
/** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */
void* m_autoReleasePool;
/** Event handler reference. */
//EventHandlerRef m_handler;
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
/** Mouse buttons state */
GHOST_TUns32 m_pressedMouseButtons;
/** State of the modifiers. */
GHOST_TUns32 m_modifierMask;
/** Ignores window size messages (when window is dragged). */
bool m_ignoreWindowSizedMessages;
};
#endif // _GHOST_SYSTEM_COCOA_H_

File diff suppressed because it is too large Load Diff

View File

@@ -27,8 +27,6 @@
*/
/**
* $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* @author Maarten Gribnau
* @date May 10, 2001

View File

@@ -0,0 +1,308 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/**
* @file GHOST_WindowCocoa.h
* Declaration of GHOST_WindowCocoa class.
*/
#ifndef _GHOST_WINDOW_COCOA_H_
#define _GHOST_WINDOW_COCOA_H_
#ifndef __APPLE__
#error Apple OSX only!
#endif // __APPLE__
#include "GHOST_Window.h"
#include "STR_String.h"
#include <AGL/agl.h>
/**
* Window on Mac OSX/Cocoa.
* Carbon windows have a size widget in the lower right corner of the window.
* To force it to be visible, the height of the client rectangle is reduced so
* that applications do not draw in that area. GHOST will manage that area
* which is called the gutter.
* When OpenGL contexts are active, GHOST will use AGL_BUFFER_RECT to prevent
* OpenGL drawing outside the reduced client rectangle.
* @author Maarten Gribnau
* @date May 23, 2001
*/
class GHOST_WindowCocoa : public GHOST_Window {
public:
/**
* Constructor.
* Creates a new window and opens it.
* To check if the window was created properly, use the getValid() method.
* @param title The text shown in the title bar of the window.
* @param left The coordinate of the left edge of the window.
* @param top The coordinate of the top edge of the window.
* @param width The width the window.
* @param height The height the window.
* @param state The state the window is initially opened with.
* @param type The type of drawing context installed in this window.
* @param stereoVisual Stereo visual for quad buffered stereo.
*/
GHOST_WindowCocoa(
const STR_String& title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
const bool stereoVisual = false
);
/**
* Destructor.
* Closes the window and disposes resources allocated.
*/
virtual ~GHOST_WindowCocoa();
/**
* Returns indication as to whether the window is valid.
* @return The validity of the window.
*/
virtual bool getValid() const;
/**
* Sets the title displayed in the title bar.
* @param title The title to display in the title bar.
*/
virtual void setTitle(const STR_String& title);
/**
* Returns the title displayed in the title bar.
* @param title The title displayed in the title bar.
*/
virtual void getTitle(STR_String& title) const;
/**
* Returns the window rectangle dimensions.
* The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* @param bounds The bounding rectangle of the window.
*/
virtual void getWindowBounds(GHOST_Rect& bounds) const;
/**
* Returns the client rectangle dimensions.
* The left and top members of the rectangle are always zero.
* @param bounds The bounding rectangle of the cleient area of the window.
*/
virtual void getClientBounds(GHOST_Rect& bounds) const;
/**
* Resizes client rectangle width.
* @param width The new width of the client area of the window.
*/
virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
/**
* Resizes client rectangle height.
* @param height The new height of the client area of the window.
*/
virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
/**
* Resizes client rectangle.
* @param width The new width of the client area of the window.
* @param height The new height of the client area of the window.
*/
virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
/**
* Returns the state of the window (normal, minimized, maximized).
* @return The state of the window.
*/
virtual GHOST_TWindowState getState() const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* @param inX The x-coordinate on the screen.
* @param inY The y-coordinate on the screen.
* @param outX The x-coordinate in the client rectangle.
* @param outY The y-coordinate in the client rectangle.
*/
virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
* @param inX The x-coordinate in the client rectangle.
* @param inY The y-coordinate in the client rectangle.
* @param outX The x-coordinate on the screen.
* @param outY The y-coordinate on the screen.
*/
virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Sets the state of the window (normal, minimized, maximized).
* @param state The state of the window.
* @return Indication of success.
*/
virtual GHOST_TSuccess setState(GHOST_TWindowState state);
/**
* Sets the order of the window (bottom, top).
* @param order The order of the window.
* @return Indication of success.
*/
virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
/**
* Swaps front and back buffers of a window.
* @return A boolean success indicator.
*/
virtual GHOST_TSuccess swapBuffers();
/**
* Updates the drawing context of this window. Needed
* whenever the window is changed.
* @return Indication of success.
*/
GHOST_TSuccess updateDrawingContext();
/**
* Activates the drawing context of this window.
* @return A boolean success indicator.
*/
virtual GHOST_TSuccess activateDrawingContext();
virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
/**
* Returns the dirty state of the window when in full-screen mode.
* @return Whether it is dirty.
*/
virtual bool getFullScreenDirty();
/* accessor for fullscreen window */
virtual void setMac_windowState(short value);
virtual short getMac_windowState();
const GHOST_TabletData* GetTabletData()
{ return &m_tablet; }
GHOST_TabletData& GetCocoaTabletData()
{ return m_tablet; }
protected:
/**
* Tries to install a rendering context in this window.
* @param type The type of rendering context installed.
* @return Indication as to whether installation has succeeded.
*/
virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
/**
* Removes the current drawing context.
* @return Indication as to whether removal has succeeded.
*/
virtual GHOST_TSuccess removeDrawingContext();
/**
* Invalidates the contents of this window.
* @return Indication of success.
*/
virtual GHOST_TSuccess invalidate();
/**
* Sets the cursor visibility on the window using
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
/**
* Converts a string object to a Mac Pascal string.
* @param in The string object to be converted.
* @param out The converted string.
*/
virtual void gen2mac(const STR_String& in, Str255 out) const;
/**
* Converts a Mac Pascal string to a string object.
* @param in The string to be converted.
* @param out The converted string object.
*/
virtual void mac2gen(const Str255 in, STR_String& out) const;
WindowRef m_windowRef;
CGrafPtr m_grafPtr;
AGLContext m_aglCtx;
/** The first created OpenGL context (for sharing display lists) */
static AGLContext s_firstaglCtx;
Cursor* m_customCursor;
GHOST_TabletData m_tablet;
/** When running in full-screen this tells whether to refresh the window. */
bool m_fullScreenDirty;
/** specific MacOs X full screen window setting as we use partially system mechanism
values : 0 not maximizable default
1 normal state
2 maximized state
this will be reworked when rebuilding GHOST carbon to use new OS X apis
in order to be unified with GHOST fullscreen/maximised settings
(lukep)
**/
short mac_windowState;
/**
* The width/height of the size rectangle in the lower right corner of a
* Mac/Carbon window. This is also the height of the gutter area.
*/
#ifdef GHOST_DRAW_CARBON_GUTTER
static const GHOST_TInt32 s_sizeRectSize;
#endif // GHOST_DRAW_CARBON_GUTTER
};
#endif // _GHOST_WINDOW_COCOA_H_

View File

@@ -0,0 +1,745 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/**
* Copyright (C) 2001 NaN Technologies B.V.
* @author Maarten Gribnau
* @date May 10, 2001
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Carbon/Carbon.h>
#include "GHOST_WindowCocoa.h"
#include "GHOST_Debug.h"
AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL;
#ifdef GHOST_DRAW_CARBON_GUTTER
const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16;
#endif //GHOST_DRAW_CARBON_GUTTER
static const GLint sPreferredFormatWindow[8] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ACCELERATED,
AGL_DEPTH_SIZE, 32,
AGL_NONE,
};
static const GLint sPreferredFormatFullScreen[9] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ACCELERATED,
AGL_FULLSCREEN,
AGL_DEPTH_SIZE, 32,
AGL_NONE,
};
WindowRef ugly_hack=NULL;
const EventTypeSpec kWEvents[] = {
{ kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */
};
static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
WindowRef mywindow;
GHOST_WindowCocoa *ghost_window;
OSStatus err;
int theState;
if (::GetEventKind(event) == kEventWindowZoom) {
err = ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow);
ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow);
theState = ghost_window->getMac_windowState();
if (theState == 1)
ghost_window->setMac_windowState(2);
else if (theState == 2)
ghost_window->setMac_windowState(1);
}
return eventNotHandledErr;
}
GHOST_WindowCocoa::GHOST_WindowCocoa(
const STR_String& title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual
) :
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
m_windowRef(0),
m_grafPtr(0),
m_aglCtx(0),
m_customCursor(0),
m_fullScreenDirty(false)
{
Str255 title255;
OSStatus err;
//fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
if (state >= GHOST_kWindowState8Normal ) {
if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal;
else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized;
else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized;
else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen;
// state = state - 8; this was the simple version of above code, doesnt work in gcc 4.0
setMac_windowState(1);
} else
setMac_windowState(0);
if (state != GHOST_kWindowStateFullScreen) {
Rect bnds = { top, left, top+height, left+width };
// Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
gen2mac(title, title255);
err = ::CreateNewWindow( kDocumentWindowClass,
kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
&bnds,
&m_windowRef);
if ( err != noErr) {
fprintf(stderr," error creating window %i \n",err);
} else {
::SetWRefCon(m_windowRef,(SInt32)this);
setTitle(title);
err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL);
if ( err != noErr) {
fprintf(stderr," error creating handler %i \n",err);
} else {
// ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
::ShowWindow(m_windowRef);
::MoveWindow (m_windowRef, left, top,true);
}
}
if (m_windowRef) {
m_grafPtr = ::GetWindowPort(m_windowRef);
setDrawingContextType(type);
updateDrawingContext();
activateDrawingContext();
}
if(ugly_hack==NULL) {
ugly_hack= m_windowRef;
// when started from commandline, window remains in the back... also for play anim
ProcessSerialNumber psn;
GetCurrentProcess(&psn);
SetFrontProcess(&psn);
}
}
else {
/*
Rect bnds = { top, left, top+height, left+width };
gen2mac("", title255);
m_windowRef = ::NewCWindow(
nil, // Storage
&bnds, // Bounding rectangle of the window
title255, // Title of the window
0, // Window initially visible
plainDBox, // procID
(WindowRef)-1L, // Put window before all other windows
0, // Window has minimize box
(SInt32)this); // Store a pointer to the class in the refCon
*/
//GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n");
setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
updateDrawingContext();
activateDrawingContext();
m_tablet.Active = GHOST_kTabletModeNone;
}
}
GHOST_WindowCocoa::~GHOST_WindowCocoa()
{
if (m_customCursor) delete m_customCursor;
if(ugly_hack==m_windowRef) ugly_hack= NULL;
// printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n");
if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);
if (m_windowRef) {
::DisposeWindow(m_windowRef);
m_windowRef = 0;
}
}
bool GHOST_WindowCocoa::getValid() const
{
bool valid;
if (!m_fullScreen) {
valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
}
else {
valid = true;
}
return valid;
}
void GHOST_WindowCocoa::setTitle(const STR_String& title)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
Str255 title255;
gen2mac(title, title255);
::SetWTitle(m_windowRef, title255);
}
void GHOST_WindowCocoa::getTitle(STR_String& title) const
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
Str255 title255;
::GetWTitle(m_windowRef, title255);
mac2gen(title255, title);
}
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
{
OSStatus success;
Rect rect;
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
bounds.m_b = rect.bottom;
bounds.m_l = rect.left;
bounds.m_r = rect.right;
bounds.m_t = rect.top;
}
void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
{
Rect rect;
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
//::GetPortBounds(m_grafPtr, &rect);
::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect);
bounds.m_b = rect.bottom;
bounds.m_l = rect.left;
bounds.m_r = rect.right;
bounds.m_t = rect.top;
// Subtract gutter height from bottom
#ifdef GHOST_DRAW_CARBON_GUTTER
if ((bounds.m_b - bounds.m_t) > s_sizeRectSize)
{
bounds.m_b -= s_sizeRectSize;
}
else
{
bounds.m_t = bounds.m_b;
}
#endif //GHOST_DRAW_CARBON_GUTTER
}
GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if (((GHOST_TUns32)cBnds.getWidth()) != width) {
::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
#ifdef GHOST_DRAW_CARBON_GUTTER
if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) {
::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true);
}
#else //GHOST_DRAW_CARBON_GUTTER
if (((GHOST_TUns32)cBnds.getHeight()) != height) {
::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
}
#endif //GHOST_DRAW_CARBON_GUTTER
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
#ifdef GHOST_DRAW_CARBON_GUTTER
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
(((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) {
::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true);
}
#else //GHOST_DRAW_CARBON_GUTTER
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
(((GHOST_TUns32)cBnds.getHeight()) != height)) {
::SizeWindow(m_windowRef, width, height, true);
}
#endif //GHOST_DRAW_CARBON_GUTTER
return GHOST_kSuccess;
}
GHOST_TWindowState GHOST_WindowCocoa::getState() const
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
GHOST_TWindowState state;
if (::IsWindowVisible(m_windowRef) == false) {
state = GHOST_kWindowStateMinimized;
}
else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
state = GHOST_kWindowStateMaximized;
}
else {
state = GHOST_kWindowStateNormal;
}
return state;
}
void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
Point point;
point.h = inX;
point.v = inY;
GrafPtr oldPort;
::GetPort(&oldPort);
::SetPort(m_grafPtr);
::GlobalToLocal(&point);
::SetPort(oldPort);
outX = point.h;
outY = point.v;
}
void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid")
Point point;
point.h = inX;
point.v = inY;
GrafPtr oldPort;
::GetPort(&oldPort);
::SetPort(m_grafPtr);
::LocalToGlobal(&point);
::SetPort(oldPort);
outX = point.h;
outY = point.v;
}
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
switch (state) {
case GHOST_kWindowStateMinimized:
::HideWindow(m_windowRef);
break;
case GHOST_kWindowStateModified:
SetWindowModified(m_windowRef, 1);
break;
case GHOST_kWindowStateUnModified:
SetWindowModified(m_windowRef, 0);
break;
case GHOST_kWindowStateMaximized:
case GHOST_kWindowStateNormal:
default:
::ShowWindow(m_windowRef);
break;
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
if (order == GHOST_kWindowOrderTop) {
//::BringToFront(m_windowRef); is wrong, front window should be active for input too
::SelectWindow(m_windowRef);
}
else {
/* doesnt work if you do this with a mouseclick */
::SendBehind(m_windowRef, nil);
}
return GHOST_kSuccess;
}
/*#define WAIT_FOR_VSYNC 1*/
#ifdef WAIT_FOR_VSYNC
#include <OpenGL/OpenGL.h>
#endif
GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
{
#ifdef WAIT_FOR_VSYNC
/* wait for vsync, to avoid tearing artifacts */
long VBL = 1;
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
#endif
GHOST_TSuccess succeeded = GHOST_kSuccess;
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
if (m_aglCtx) {
::aglSwapBuffers(m_aglCtx);
}
else {
succeeded = GHOST_kFailure;
}
}
return succeeded;
}
GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
{
GHOST_TSuccess succeeded = GHOST_kSuccess;
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
if (m_aglCtx) {
::aglUpdateContext(m_aglCtx);
}
else {
succeeded = GHOST_kFailure;
}
}
return succeeded;
}
GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
{
GHOST_TSuccess succeeded = GHOST_kSuccess;
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
if (m_aglCtx) {
::aglSetCurrentContext(m_aglCtx);
#ifdef GHOST_DRAW_CARBON_GUTTER
// Restrict drawing to non-gutter area
::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
GHOST_Rect bnds;
getClientBounds(bnds);
GLint b[4] =
{
bnds.m_l,
bnds.m_t+s_sizeRectSize,
bnds.m_r-bnds.m_l,
bnds.m_b-bnds.m_t
};
GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
#endif //GHOST_DRAW_CARBON_GUTTER
}
else {
succeeded = GHOST_kFailure;
}
}
return succeeded;
}
GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
{
GHOST_TSuccess success = GHOST_kFailure;
switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
{
if (!getValid()) break;
AGLPixelFormat pixelFormat;
if (!m_fullScreen) {
pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
if (!m_aglCtx) break;
if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
}
else {
//GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n");
GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen);
m_aglCtx = ::aglCreateContext(pixelFormat, 0);
if (!m_aglCtx) break;
if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
//GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n");
//::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
/*
if (success == GHOST_kSuccess) {
GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n");
}
else {
GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n");
}
*/
}
::aglDestroyPixelFormat(pixelFormat);
}
break;
case GHOST_kDrawingContextTypeNone:
success = GHOST_kSuccess;
break;
default:
break;
}
return success;
}
GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
{
GHOST_TSuccess success = GHOST_kFailure;
switch (m_drawingContextType) {
case GHOST_kDrawingContextTypeOpenGL:
if (m_aglCtx) {
aglSetCurrentContext(NULL);
aglSetDrawable(m_aglCtx, NULL);
//aglDestroyContext(m_aglCtx);
if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
m_aglCtx = 0;
}
break;
case GHOST_kDrawingContextTypeNone:
success = GHOST_kSuccess;
break;
default:
break;
}
return success;
}
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
if (!m_fullScreen) {
Rect rect;
::GetPortBounds(m_grafPtr, &rect);
::InvalWindowRect(m_windowRef, &rect);
}
else {
//EventRef event;
//OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n");
//status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n");
//status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
//status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
m_fullScreenDirty = true;
}
return GHOST_kSuccess;
}
void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const
{
STR_String tempStr = in;
int num = tempStr.Length();
if (num > 255) num = 255;
::memcpy(out+1, tempStr.Ptr(), num);
out[0] = num;
}
void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const
{
char tmp[256];
::memcpy(tmp, in+1, in[0]);
tmp[in[0]] = '\0';
out = tmp;
}
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
{
static bool systemCursorVisible = true;
if (visible != systemCursorVisible) {
if (visible) {
::ShowCursor();
systemCursorVisible = true;
}
else {
::HideCursor();
systemCursorVisible = false;
}
}
if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
::SetCursor( m_customCursor );
} else {
int carbon_cursor;
#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break
switch (cursor) {
default:
GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorRightArrow, kThemeAliasArrowCursor);
GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor);
GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor);
GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor);
GCMAP( GHOST_kStandardCursorUpDown, kThemeClosedHandCursor);
GCMAP( GHOST_kStandardCursorLeftRight, kThemeClosedHandCursor);
GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor);
GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor);
GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor);
GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor);
};
#undef GCMAP
::SetThemeCursor(carbon_cursor);
}
}
bool GHOST_WindowCocoa::getFullScreenDirty()
{
return m_fullScreen && m_fullScreenDirty;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
{
if (::FrontWindow() == m_windowRef) {
loadCursor(visible, getCursorShape());
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
{
if (m_customCursor) {
delete m_customCursor;
m_customCursor = 0;
}
if (::FrontWindow() == m_windowRef) {
loadCursor(getCursorVisibility(), shape);
}
return GHOST_kSuccess;
}
#if 0
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA);
ch= ((ch>>2)&0x33) | ((ch<<2)&0xCC);
ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0);
return ch;
}
#endif
/** Reverse the bits in a GHOST_TUns16 */
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
{
shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
return shrt;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
{
int y;
if (m_customCursor) {
delete m_customCursor;
m_customCursor = 0;
}
m_customCursor = new Cursor;
if (!m_customCursor) return GHOST_kFailure;
for (y=0; y<16; y++) {
#if !defined(__LITTLE_ENDIAN__)
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
#else
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
#endif
}
m_customCursor->hotSpot.h = hotX;
m_customCursor->hotSpot.v = hotY;
if (::FrontWindow() == m_windowRef) {
loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
GHOST_TUns8 mask[16][2], int hotX, int hotY)
{
return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
}
void GHOST_WindowCocoa::setMac_windowState(short value)
{
mac_windowState = value;
}
short GHOST_WindowCocoa::getMac_windowState()
{
return mac_windowState;
}

View File

@@ -688,17 +688,35 @@ static const char *check_memlist(MemHead *memh)
uintptr_t MEM_get_memory_in_use(void)
{
return mem_in_use;
uintptr_t _mem_in_use;
mem_lock_thread();
_mem_in_use= mem_in_use;
mem_unlock_thread();
return _mem_in_use;
}
uintptr_t MEM_get_mapped_memory_in_use(void)
{
return mmap_in_use;
uintptr_t _mmap_in_use;
mem_lock_thread();
_mmap_in_use= mmap_in_use;
mem_unlock_thread();
return _mmap_in_use;
}
int MEM_get_memory_blocks_in_use(void)
{
return totblock;
int _totblock;
mem_lock_thread();
_totblock= totblock;
mem_unlock_thread();
return _totblock;
}
/* eof */

View File

@@ -399,16 +399,12 @@ void FLUID_3D::project()
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
// if(!_obstacles[index])
if(!_obstacles[index])
{
_xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx;
_yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx;
_zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
}/*
else
{
_xVelocity[index] = _yVelocity[index] = _zVelocity[index] = 0.0f;
}*/
}
}
if (_pressure) delete[] _pressure;
@@ -497,23 +493,15 @@ void FLUID_3D::setObstaclePressure(float *_pressure)
if (top && !bottom) {
_pressure[index] += _pressure[index - _slabSize];
pcnt += 1.;
// _zVelocity[index] += - _zVelocity[index - _slabSize];
// vp += 1.0;
}
if (!top && bottom) {
_pressure[index] += _pressure[index + _slabSize];
pcnt += 1.;
// _zVelocity[index] += - _zVelocity[index + _slabSize];
// vp += 1.0;
}
if(pcnt > 0.000001f)
_pressure[index] /= pcnt;
// test - dg
// if(vp > 0.000001f)
// _zVelocity[index] /= vp;
// TODO? set correct velocity bc's
// velocities are only set to zero right now
// this means it's not a full no-slip boundary condition

View File

@@ -296,7 +296,7 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
const int slabSize = res[0] * res[1];
// scale dt up to grid resolution
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
#pragma omp parallel
#pragma omp for schedule(static)
#endif

View File

@@ -735,19 +735,17 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// enlarge timestep to match grid
const float dt = dtOrg * _amplify;
const float invAmp = 1.0f / _amplify;
float *tempBig1 = new float[_totalCellsBig];
float *tempBig2 = new float[_totalCellsBig];
float *bigUx = new float[_totalCellsBig];
float *bigUy = new float[_totalCellsBig];
float *bigUz = new float[_totalCellsBig];
float *_energy = new float[_totalCellsSm];
float *highFreqEnergy = new float[_totalCellsSm];
float *eigMin = new float[_totalCellsSm];
float *eigMax = new float[_totalCellsSm];
float *tempBig1 = (float *)calloc(_totalCellsBig, sizeof(float));
float *tempBig2 = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float));
float *_energy = (float *)calloc(_totalCellsSm, sizeof(float));
float *highFreqEnergy = (float *)calloc(_totalCellsSm, sizeof(float));
float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float));
float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float));
memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm);
memset(eigMin, 0, sizeof(float)*_totalCellsSm);
memset(eigMax, 0, sizeof(float)*_totalCellsSm);
memset(_tcTemp, 0, sizeof(float)*_totalCellsSm);
// prepare textures
advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
@@ -771,16 +769,16 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// parallel region setup
float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
#pragma omp parallel
#endif
{ float maxVelMag1 = 0.;
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
#endif
// vector noise main loop
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
#pragma omp for schedule(static)
#endif
for (int zSmall = 0; zSmall < _zResSm; zSmall++)
@@ -912,7 +910,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
bigUx[index] = bigUy[index] = bigUz[index] = 0.;
} // xyz
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
maxVelMagThreads[id] = maxVelMag1;
#else
maxVelMagThreads[0] = maxVelMag1;
@@ -922,7 +920,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// compute maximum over threads
float maxVelMag = maxVelMagThreads[0];
#if PARALLEL==1
#if PARALLEL==1 && !_WIN32
for (int i = 1; i < 8; i++)
if (maxVelMag < maxVelMagThreads[i])
maxVelMag = maxVelMagThreads[i];
@@ -957,13 +955,13 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
SWAP_POINTERS(_densityBig, _densityBigOld);
} // substep
delete[] tempBig1;
delete[] tempBig2;
delete[] bigUx;
delete[] bigUy;
delete[] bigUz;
delete[] _energy;
delete[] highFreqEnergy;
free(tempBig1);
free(tempBig2);
free(bigUx);
free(bigUy);
free(bigUz);
free(_energy);
free(highFreqEnergy);
// wipe the density borders
FLUID_3D::setZeroBorder(_densityBig, _resBig);
@@ -973,8 +971,8 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// eigenvalues stored do not reflect the underlying texture coordinates
resetTextureCoordinates(eigMin, eigMax);
delete[] eigMin;
delete[] eigMax;
free(eigMin);
free(eigMax);
// output files
// string prefix = string("./amplified.preview/density_bigxy_");

View File

@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -118,7 +118,7 @@
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="0"
@@ -193,7 +193,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="2"
@@ -268,7 +268,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -342,7 +342,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
RuntimeLibrary="0"
@@ -417,7 +417,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\source\blender;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenpluginapi"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="3"

View File

@@ -271,7 +271,7 @@
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\include\ED_previewrender.h"
RelativePath="..\..\..\source\blender\editors\include\ED_render.h"
>
</File>
<File
@@ -1220,11 +1220,11 @@
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\mesh\mesh_intern.h"
RelativePath="..\..\..\source\blender\editors\mesh\mesh_data.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\mesh\mesh_layers.c"
RelativePath="..\..\..\source\blender\editors\mesh\mesh_intern.h"
>
</File>
<File
@@ -1420,41 +1420,37 @@
>
</File>
</Filter>
<Filter
Name="preview"
>
<File
RelativePath="..\..\..\source\blender\editors\preview\previewrender.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\preview\previewrender_intern.h"
>
</File>
</Filter>
<Filter
Name="physics"
>
<File
RelativePath="..\..\..\source\blender\editors\physics\ed_fluidsim.c"
RelativePath="..\..\..\source\blender\editors\physics\particle_boids.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\ed_pointcache.c"
RelativePath="..\..\..\source\blender\editors\physics\particle_edit.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\editparticle.c"
RelativePath="..\..\..\source\blender\editors\physics\particle_object.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\physics_boids.c"
RelativePath="..\..\..\source\blender\editors\physics\physics_fluid.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\physics_intern.h"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\physics_ops.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\physics\physics_pointcache.c"
>
</File>
</Filter>
<Filter
Name="space_logic"
@@ -1548,6 +1544,26 @@
>
</File>
</Filter>
<Filter
Name="render"
>
<File
RelativePath="..\..\..\source\blender\editors\render\render_intern.h"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\render\render_ops.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\render\render_preview.c"
>
</File>
<File
RelativePath="..\..\..\source\blender\editors\render\render_shading.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>

View File

@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -114,7 +114,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\ikplugin;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
RuntimeLibrary="0"

View File

@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
MinimalRebuild="false"
BasicRuntimeChecks="3"
@@ -112,7 +112,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
@@ -182,7 +182,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_OPENEXR"
MinimalRebuild="false"
BasicRuntimeChecks="3"
@@ -253,7 +253,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_OPENEXR"
BasicRuntimeChecks="0"
RuntimeLibrary="0"

View File

@@ -44,7 +44,7 @@
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
StringPooling="true"
RuntimeLibrary="0"
@@ -119,7 +119,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
BasicRuntimeChecks="3"
RuntimeLibrary="1"

View File

@@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -113,7 +113,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
RuntimeLibrary="0"

View File

@@ -559,14 +559,15 @@ def extract_triangles(mesh):
uf = mesh.active_uv_texture.data[i] if do_uv else None
if do_uv:
f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
f_uv = uf.uv
# f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
# f_uv = face.uv
img = uf.image if uf else None
# img = face.image
if img: img = img.name
if f_v[3] == 0:
# if len(f_v)==3:
# if f_v[3] == 0:
if len(f_v)==3:
new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img)
# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
if (do_uv): new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2])
@@ -1109,11 +1110,12 @@ class EXPORT_OT_3ds(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
# bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the 3DS file", maxlen= 1024, default= ""),
]
def execute(self, context):
save_3ds(self.filename, context)
save_3ds(self.path, context)
return ('FINISHED',)
def invoke(self, context, event):

View File

@@ -1211,13 +1211,13 @@ def write(filename, batch_objects = None, \
mat_colamb = world_amb
# mat_colamb = tuple([c for c in world_amb])
mat_dif = mat.diffuse_reflection
mat_dif = mat.diffuse_intensity
# mat_dif = mat.ref
mat_amb = mat.ambient
# mat_amb = mat.amb
mat_hard = (float(mat.specular_hardness)-1)/5.10
# mat_hard = (float(mat.hard)-1)/5.10
mat_spec = mat.specular_reflection/2.0
mat_spec = mat.specular_intensity/2.0
# mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
@@ -1528,7 +1528,8 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
fi = f.verts
# fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
# fi = [v.index for v in f]
# flip the last index, odd but it looks like
@@ -1637,10 +1638,7 @@ def write(filename, batch_objects = None, \
# returns a slice of data depending on number of face verts
# data is either a MeshTextureFace or MeshColor
def face_data(data, face):
if f.verts[3] == 0:
totvert = 3
else:
totvert = 4
totvert = len(f.verts)
return data[:totvert]
@@ -1740,12 +1738,9 @@ def write(filename, batch_objects = None, \
i = -1
ii = 0 # Count how many UVs we write
for f, uf in zip(me.faces, uvlayer.data):
for uf in uvlayer.data:
# for f in me.faces:
uvs = [uf.uv1, uf.uv2, uf.uv3, uf.uv4]
uvs = face_data(uvs, f)
for uv in uvs:
for uv in uf.uv:
# for uv in f.uv:
if i==-1:
file.write('%.6f,%.6f' % tuple(uv))
@@ -3356,7 +3351,8 @@ class EXPORT_OT_fbx(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default=""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True),
# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True),
bpy.props.FloatProperty(attr="_SCALE", name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0),
@@ -3389,8 +3385,8 @@ class EXPORT_OT_fbx(bpy.types.Operator):
return context.active_object != None
def execute(self, context):
if not self.filename:
raise Exception("filename not set")
if not self.path:
raise Exception("path not set")
GLOBAL_MATRIX = mtx4_identity
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE
@@ -3398,7 +3394,7 @@ class EXPORT_OT_fbx(bpy.types.Operator):
if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
write(self.filename,
write(self.path,
None, # XXX
context,
self.EXP_OBS_SELECTED,

View File

@@ -153,7 +153,7 @@ def write_mtl(scene, filename, copy_images):
elif mat: # No face image. if we havea material search for MTex image.
for mtex in mat.textures:
if mtex and mtex.texure.type == 'IMAGE':
if mtex and mtex.texture.type == 'IMAGE':
try:
filename = copy_image(mtex.texture.image)
# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1]
@@ -330,7 +330,8 @@ def write(filename, objects, scene,
return round(v.x, 6), round(v.y, 6), round(v.z, 6)
def veckey2d(v):
return round(v.x, 6), round(v.y, 6)
return round(v[0], 6), round(v[1], 6)
# return round(v.x, 6), round(v.y, 6)
def findVertexGroupName(face, vWeightMap):
"""
@@ -593,11 +594,12 @@ def write(filename, objects, scene,
tface = uv_layer.data[f_index]
uvs = [tface.uv1, tface.uv2, tface.uv3]
uvs = tface.uv
# uvs = [tface.uv1, tface.uv2, tface.uv3]
# add another UV if it's a quad
if f.verts[3] != 0:
uvs.append(tface.uv4)
# # add another UV if it's a quad
# if len(f.verts) == 4:
# uvs.append(tface.uv4)
for uv_index, uv in enumerate(uvs):
uvkey = veckey2d(uv)
@@ -661,8 +663,8 @@ def write(filename, objects, scene,
for f_index, f in enumerate(faces):
f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts]
if f.verts[3] == 0:
f_v.pop()
# if f.verts[3] == 0:
# f_v.pop()
# f_v= f.v
f_smooth= f.smooth
@@ -673,9 +675,10 @@ def write(filename, objects, scene,
tface = me.active_uv_texture.data[face_index_pairs[f_index][1]]
f_image = tface.image
f_uv= [tface.uv1, tface.uv2, tface.uv3]
if f.verts[3] != 0:
f_uv.append(tface.uv4)
f_uv = tface.uv
# f_uv= [tface.uv1, tface.uv2, tface.uv3]
# if len(f.verts) == 4:
# f_uv.append(tface.uv4)
# f_image = f.image
# f_uv= f.uv
@@ -918,7 +921,7 @@ class EXPORT_OT_obj(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the OBJ file", maxlen= 1024, default= ""),
# context group
bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False),
@@ -949,7 +952,7 @@ class EXPORT_OT_obj(bpy.types.Operator):
def execute(self, context):
do_export(self.filename, context,
do_export(self.path, context,
EXPORT_TRI=self.use_triangles,
EXPORT_EDGES=self.use_edges,
EXPORT_NORMALS=self.use_normals,

View File

@@ -604,7 +604,8 @@ class x3d_class:
for face in mesh.active_uv_texture.data:
# for face in mesh.faces:
uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
uvs = face.uv
# uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
for uv in uvs:
# for uv in face.uv:
@@ -676,11 +677,11 @@ class x3d_class:
shininess = mat.specular_hardness/512.0
# shininess = mat.hard/512.0
specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001))
specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001))
specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001))
specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
transp = 1-mat.alpha
# matFlags = mat.getMode()
@@ -1213,7 +1214,7 @@ class EXPORT_OT_x3d(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the X3D file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True),
bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False),
@@ -1221,7 +1222,7 @@ class EXPORT_OT_x3d(bpy.types.Operator):
]
def execute(self, context):
x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress)
x3d_export(self.path, context, self.apply_modifiers, self.triangulate, self.compress)
return ('FINISHED',)
def invoke(self, context, event):

View File

@@ -420,7 +420,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
# +1 because of DUMMYVERT
bmesh.faces.foreach_set("verts", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
bmesh.faces.foreach_set("verts_raw", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
# face_mapping = bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
if bmesh.faces and (contextMeshUV or img):
@@ -1140,14 +1140,15 @@ class IMPORT_OT_3ds(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen=1024, default= ""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
]
def execute(self, context):
load_3ds(self.filename, context, 0.0, False, False)
load_3ds(self.path, context, 0.0, False, False)
return ('FINISHED',)
def invoke(self, context, event):

View File

@@ -87,11 +87,19 @@ def unpack_face_list(list_of_tuples):
l = []
for t in list_of_tuples:
face = [i for i in t]
if len(face) != 3 and len(face) != 4:
raise RuntimeError("{0} vertices in face.".format(len(face)))
# rotate indices if the 4th is 0
if len(face) == 4 and face[3] == 0:
face = [face[3], face[0], face[1], face[2]]
if len(face) == 3:
face.append(0)
l.extend(face)
return l
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
@@ -709,9 +717,9 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# me.verts.extend(verts_loc)
# faces is a list of (vert_indices, texco_indices, ...) tuples
# XXX faces should not contain edges
# XXX faces should contain either 3 or 4 verts
# XXX no check for valid face indices
me.faces.foreach_set("verts", unpack_face_list([f[0] for f in faces]))
me.faces.foreach_set("verts_raw", unpack_face_list([f[0] for f in faces]))
# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
if verts_tex and me.faces:
@@ -1568,7 +1576,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True),
bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True),
@@ -1592,10 +1600,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
def execute(self, context):
# print("Selected: " + context.active_object.name)
if not self.filename:
raise Exception("filename not set")
load_obj(self.filename,
load_obj(self.path,
context,
self.CLAMP_SIZE,
self.CREATE_FGONS,

View File

@@ -3,12 +3,12 @@ import sys, os, re
import http, http.client, http.server, urllib
import subprocess, shutil, time, hashlib
import netrender.model
import netrender.slave as slave
import netrender.master as master
from netrender.utils import *
def clientSendJob(conn, scene, anim = False, chunks = 5):
def clientSendJob(conn, scene, anim = False):
netsettings = scene.network_render
job = netrender.model.RenderJob()

View File

@@ -42,9 +42,10 @@ class MRenderSlave(netrender.model.RenderSlave):
self.job = None
class MRenderJob(netrender.model.RenderJob):
def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []):
def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []):
super().__init__()
self.id = job_id
self.type = job_type
self.name = name
self.files = files
self.frames = []
@@ -54,6 +55,10 @@ class MRenderJob(netrender.model.RenderJob):
self.blacklist = blacklist
self.last_dispatched = time.time()
# force one chunk for process jobs
if self.type == netrender.model.JOB_PROCESS:
self.chunks = 1
# special server properties
self.last_update = 0
self.save_path = ""
@@ -93,8 +98,8 @@ class MRenderJob(netrender.model.RenderJob):
if frame:
frame.log_path = log_path
def addFrame(self, frame_number):
frame = MRenderFrame(frame_number)
def addFrame(self, frame_number, command):
frame = MRenderFrame(frame_number, command)
self.frames.append(frame)
return frame
@@ -114,12 +119,14 @@ class MRenderJob(netrender.model.RenderJob):
return frames
class MRenderFrame(netrender.model.RenderFrame):
def __init__(self, frame):
def __init__(self, frame, command):
super().__init__()
self.number = frame
self.slave = None
self.time = 0
self.status = QUEUED
self.command = command
self.log_path = None
def reset(self, all):
@@ -368,10 +375,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_id = self.server.nextJobID()
job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
for frame in job_info.frames:
frame = job.addFrame(frame.number)
frame = job.addFrame(frame.number, frame.command)
self.server.addJob(job)
@@ -538,6 +545,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
frame = job[job_frame]
if frame:
if job.type == netrender.model.JOB_BLENDER:
if job_result == DONE:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)

View File

@@ -32,9 +32,8 @@ def get(handler):
def endTable():
output("</table>")
handler.send_head(content = "text/html")
if handler.path == "/html" or handler.path == "/":
handler.send_head(content = "text/html")
output("<html><head><title>NetRender</title></head><body>")
output("<h2>Master</h2>")
@@ -86,6 +85,7 @@ def get(handler):
output("</body></html>")
elif handler.path.startswith("/html/job"):
handler.send_head(content = "text/html")
job_id = handler.path[9:]
output("<html><head><title>NetRender</title></head><body>")
@@ -108,10 +108,9 @@ def get(handler):
output("</body></html>")
elif handler.path.startswith("/html/log"):
handler.send_head(content = "text/plain")
pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
output("<html><head><title>NetRender</title></head><body>")
match = pattern.match(handler.path[9:])
if match:
job_id = match.groups()[0]
@@ -125,12 +124,8 @@ def get(handler):
if frame:
f = open(frame.log_path, 'rb')
output("<pre>")
shutil.copyfileobj(f, handler.wfile)
output("</pre>")
f.close()
else:
output("no such frame")
@@ -138,5 +133,3 @@ def get(handler):
output("no such job")
else:
output("malformed url")
output("</body></html>")

View File

@@ -72,9 +72,18 @@ class RenderSlave:
return slave
JOB_BLENDER = 1
JOB_PROCESS = 2
JOB_TYPES = {
JOB_BLENDER: "Blender",
JOB_PROCESS: "Process"
}
class RenderJob:
def __init__(self):
self.id = ""
self.type = JOB_BLENDER
self.name = ""
self.files = []
self.frames = []
@@ -87,8 +96,8 @@ class RenderJob:
def addFile(self, file_path, start=-1, end=-1):
self.files.append((file_path, start, end))
def addFrame(self, frame_number):
frame = RenderFrame(frame_number)
def addFrame(self, frame_number, command = ""):
frame = RenderFrame(frame_number, command)
self.frames.append(frame)
return frame
@@ -138,6 +147,7 @@ class RenderJob:
max_frame = max((f.number for f in frames)) if frames else -1
return {
"id": self.id,
"type": self.type,
"name": self.name,
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
@@ -155,6 +165,7 @@ class RenderJob:
job = RenderJob()
job.id = data["id"]
job.type = data["type"]
job.name = data["name"]
job.files = data["files"]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
@@ -167,11 +178,12 @@ class RenderJob:
return job
class RenderFrame:
def __init__(self, number = 0):
def __init__(self, number = 0, command = ""):
self.number = number
self.time = 0
self.status = QUEUED
self.slave = None
self.command = command
def statusText(self):
return STATUS_TEXT[self.status]
@@ -181,7 +193,8 @@ class RenderFrame:
"number": self.number,
"time": self.time,
"status": self.status,
"slave": None if not self.slave else self.slave.serialize()
"slave": None if not self.slave else self.slave.serialize(),
"command": self.command
}
@staticmethod
@@ -194,5 +207,6 @@ class RenderFrame:
frame.time = data["time"]
frame.status = data["status"]
frame.slave = RenderSlave.materialize(data["slave"])
frame.command = data["command"]
return frame

View File

@@ -99,6 +99,8 @@ def render_slave(engine, scene):
if not os.path.exists(JOB_PREFIX):
os.mkdir(JOB_PREFIX)
if job.type == netrender.model.JOB_BLENDER:
job_path = job.files[0][0] # data in files have format (path, start, end)
main_path, main_file = os.path.split(job_path)
@@ -111,25 +113,32 @@ def render_slave(engine, scene):
print("\t", file_path)
testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
frame_args = []
for frame in job.frames:
print("frame", frame.number)
frame_args += ["-f", str(frame.number)]
# announce log to master
logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames])
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id})
response = conn.getresponse()
first_frame = job.frames[0].number
# start render
start_t = time.time()
if job.type == netrender.model.JOB_BLENDER:
frame_args = []
for frame in job.frames:
print("frame", frame.number)
frame_args += ["-f", str(frame.number)]
val = SetErrorMode()
process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
elif job.type == netrender.model.JOB_PROCESS:
command = job.frames[0].command
val = SetErrorMode()
process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
headers = {"job-id":job.id, "slave-id":slave_id}
@@ -155,6 +164,9 @@ def render_slave(engine, scene):
if testCancel(conn, job.id, first_frame):
cancelled = True
# read leftovers if needed
stdout += process.stdout.read()
if cancelled:
# kill process if needed
if process.poll() == None:
@@ -182,11 +194,16 @@ def render_slave(engine, scene):
headers["job-result"] = str(DONE)
for frame in job.frames:
headers["job-frame"] = str(frame.number)
# send result back to server
if job.type == netrender.model.JOB_BLENDER:
# send image back to server
f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
conn.request("PUT", "/render", f, headers=headers)
f.close()
response = conn.getresponse()
elif job.type == netrender.model.JOB_PROCESS:
conn.request("PUT", "/render", headers=headers)
response = conn.getresponse()
else:
headers["job-result"] = str(ERROR)
for frame in job.frames:

View File

@@ -0,0 +1,211 @@
def execute(bcon):
'''
This function has been taken from a BGE console autocomp I wrote a while ago
the dictionaty bcon is not needed but it means I can copy and paste from the old func
which works ok for now.
'bcon' dictionary keys, set by the caller
* 'cursor' - index of the editing character (int)
* 'edit_text' - text string for editing (string)
* 'scrollback' - text to add to the scrollback, options are added here. (text)
* 'namespace' - namespace, (dictionary)
'''
def is_delimiter(ch):
'''
For skipping words
'''
if ch == '_':
return False
if ch.isalnum():
return False
return True
def is_delimiter_autocomp(ch):
'''
When autocompleteing will earch back and
'''
if ch in '._[] "\'':
return False
if ch.isalnum():
return False
return True
def do_autocomp(autocomp_prefix, autocomp_members):
'''
return text to insert and a list of options
'''
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
print("AUTO: '%s'" % autocomp_prefix)
print("MEMBERS: '%s'" % str(autocomp_members))
if not autocomp_prefix:
return '', autocomp_members
elif len(autocomp_members) > 1:
# find a common string between all members after the prefix
# 'ge' [getA, getB, getC] --> 'get'
# get the shortest member
min_len = min([len(v) for v in autocomp_members])
autocomp_prefix_ret = ''
for i in range(len(autocomp_prefix), min_len):
char_soup = set()
for v in autocomp_members:
char_soup.add(v[i])
if len(char_soup) > 1:
break
else:
autocomp_prefix_ret += char_soup.pop()
return autocomp_prefix_ret, autocomp_members
elif len(autocomp_members) == 1:
if autocomp_prefix == autocomp_members[0]:
# the variable matched the prefix exactly
# add a '.' so you can quickly continue.
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
return '.', []
else:
# finish off the of the word word
return autocomp_members[0][len(autocomp_prefix):], []
else:
return '', []
def BCon_PrevChar(bcon):
cursor = bcon['cursor']-1
if cursor<0:
return None
try:
return bcon['edit_text'][cursor]
except:
return None
def BCon_NextChar(bcon):
try:
return bcon['edit_text'][bcon['cursor']]
except:
return None
def BCon_cursorLeft(bcon):
bcon['cursor'] -= 1
if bcon['cursor'] < 0:
bcon['cursor'] = 0
def BCon_cursorRight(bcon):
bcon['cursor'] += 1
if bcon['cursor'] > len(bcon['edit_text']):
bcon['cursor'] = len(bcon['edit_text'])
def BCon_AddScrollback(bcon, text):
bcon['scrollback'] = bcon['scrollback'] + text
def BCon_cursorInsertChar(bcon, ch):
if bcon['cursor']==0:
bcon['edit_text'] = ch + bcon['edit_text']
elif bcon['cursor']==len(bcon['edit_text']):
bcon['edit_text'] = bcon['edit_text'] + ch
else:
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
bcon['cursor']
if bcon['cursor'] > len(bcon['edit_text']):
bcon['cursor'] = len(bcon['edit_text'])
BCon_cursorRight(bcon)
TEMP_NAME = '___tempname___'
cursor_orig = bcon['cursor']
ch = BCon_PrevChar(bcon)
while ch != None and (not is_delimiter(ch)):
ch = BCon_PrevChar(bcon)
BCon_cursorLeft(bcon)
if ch != None:
BCon_cursorRight(bcon)
#print (cursor_orig, bcon['cursor'])
cursor_base = bcon['cursor']
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
print("PREFIX:'%s'" % autocomp_prefix)
# Get the previous word
if BCon_PrevChar(bcon)=='.':
BCon_cursorLeft(bcon)
ch = BCon_PrevChar(bcon)
while ch != None and is_delimiter_autocomp(ch)==False:
ch = BCon_PrevChar(bcon)
BCon_cursorLeft(bcon)
cursor_new = bcon['cursor']
if ch != None:
cursor_new+=1
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
print("AUTOCOMP EVAL: '%s'" % pytxt)
#try:
if pytxt:
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
# print val
else: ##except:
val = None
try:
val = bcon['namespace'][TEMP_NAME]
del bcon['namespace'][TEMP_NAME]
except:
val = None
if val:
autocomp_members = dir(val)
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
bcon['cursor'] = cursor_orig
for v in autocomp_prefix_ret:
BCon_cursorInsertChar(bcon, v)
cursor_orig = bcon['cursor']
if autocomp_members:
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
del val
else:
# Autocomp global namespace
autocomp_members = bcon['namespace'].keys()
if autocomp_prefix:
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
bcon['cursor'] = cursor_orig
for v in autocomp_prefix_ret:
BCon_cursorInsertChar(bcon, v)
cursor_orig = bcon['cursor']
if autocomp_members:
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
bcon['cursor'] = cursor_orig

View File

@@ -0,0 +1,12 @@
import bpy
import os
def expandpath(path):
if path.startswith("//"):
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
return path
import types
bpy.sys = types.ModuleType("bpy.sys")
bpy.sys.expandpath = expandpath

View File

@@ -48,7 +48,7 @@ class BONE_PT_transform(BoneButtonsPanel):
else:
pchan = ob.pose.pose_channels[context.bone.name]
layout.itemR(pchan, "rotation_mode")
row = layout.row()
col = row.column()
@@ -57,20 +57,18 @@ class BONE_PT_transform(BoneButtonsPanel):
col = row.column()
if pchan.rotation_mode == 'QUATERNION':
col.itemR(pchan, "rotation", text="Rotation")
col.itemR(pchan, "rotation_quaternion", text="Rotation")
elif pchan.rotation_mode == 'AXIS_ANGLE':
col.itemL(text="Rotation")
col.itemR(pchan, "rotation_angle", text="Angle")
col.itemR(pchan, "rotation_axis", text="Axis")
#col.itemL(text="Rotation")
#col.itemR(pchan, "rotation_angle", text="Angle")
#col.itemR(pchan, "rotation_axis", text="Axis")
col.itemR(pchan, "rotation_axis_angle", text="Rotation")
else:
col.itemR(pchan, "euler_rotation", text="Rotation")
col.itemR(pchan, "rotation_euler", text="Rotation")
row.column().itemR(pchan, "scale")
if pchan.rotation_mode == 'QUATERNION':
col = layout.column(align=True)
col.itemL(text="Euler:")
col.row().itemR(pchan, "euler_rotation", text="")
layout.itemR(pchan, "rotation_mode")
class BONE_PT_transform_locks(BoneButtonsPanel):
__label__ = "Transform Locks"
@@ -102,8 +100,8 @@ class BONE_PT_transform_locks(BoneButtonsPanel):
row.column().itemR(pchan, "lock_scale")
class BONE_PT_bone(BoneButtonsPanel):
__label__ = "Bone"
class BONE_PT_relations(BoneButtonsPanel):
__label__ = "Relations"
def draw(self, context):
layout = self.layout
@@ -120,6 +118,16 @@ class BONE_PT_bone(BoneButtonsPanel):
split = layout.split()
col = split.column()
col.itemL(text="Layers:")
col.itemR(bone, "layer", text="")
col.itemS()
if ob and pchan:
col.itemL(text="Bone Group:")
col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
col = split.column()
col.itemL(text="Parent:")
if context.bone:
@@ -127,119 +135,46 @@ class BONE_PT_bone(BoneButtonsPanel):
else:
col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
row = col.row()
row.active = bone.parent != None
row.itemR(bone, "connected")
sub = col.column()
sub.active = bone.parent != None
sub.itemR(bone, "connected")
sub.itemR(bone, "hinge", text="Inherit Rotation")
sub.itemR(bone, "inherit_scale", text="Inherit Scale")
col.itemL(text="Layers:")
col.itemR(bone, "layer", text="")
col = split.column()
col.itemL(text="Inherit:")
col.itemR(bone, "hinge", text="Rotation")
col.itemR(bone, "inherit_scale", text="Scale")
col.itemL(text="Display:")
col.itemR(bone, "draw_wire", text="Wireframe")
col.itemR(bone, "hidden", text="Hide")
if ob and pchan:
split = layout.split()
col = split.column()
col.itemL(text="Bone Group:")
col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
col = split.column()
col.itemL(text="Custom Shape:")
col.itemR(pchan, "custom_shape", text="")
class BONE_PT_inverse_kinematics(BoneButtonsPanel):
__label__ = "Inverse Kinematics"
__default_closed__ = True
class BONE_PT_display(BoneButtonsPanel):
__label__ = "Display"
def poll(self, context):
ob = context.object
bone = context.bone
if ob and context.bone:
pchan = ob.pose.pose_channels[context.bone.name]
return pchan.has_ik
return False
return context.bone
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
arm = context.armature
if not bone:
bone = context.edit_bone
pchan = None
else:
pchan = ob.pose.pose_channels[context.bone.name]
row = layout.row()
row.itemR(ob.pose, "ik_solver")
if ob and pchan:
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_x", text="X")
row = split.row()
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
row.active = pchan.ik_dof_x
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_x", text="Limit")
row.active = pchan.ik_dof_x
row = split.row(align=True)
row.itemR(pchan, "ik_min_x", text="")
row.itemR(pchan, "ik_max_x", text="")
row.active = pchan.ik_dof_x and pchan.ik_limit_x
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_y", text="Y")
row = split.row()
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
row.active = pchan.ik_dof_y
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_y", text="Limit")
row.active = pchan.ik_dof_y
row = split.row(align=True)
row.itemR(pchan, "ik_min_y", text="")
row.itemR(pchan, "ik_max_y", text="")
row.active = pchan.ik_dof_y and pchan.ik_limit_y
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_z", text="Z")
row = split.row()
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
row.active = pchan.ik_dof_z
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_z", text="Limit")
row.active = pchan.ik_dof_z
row = split.row(align=True)
row.itemR(pchan, "ik_min_z", text="")
row.itemR(pchan, "ik_max_z", text="")
row.active = pchan.ik_dof_z and pchan.ik_limit_z
split = layout.split()
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
split.itemL()
if ob.pose.ik_solver == "ITASC":
layout.itemL(text="Joint constraint:")
split = layout.split(percentage=0.3)
row = split.row()
row.itemR(pchan, "ik_rot_control", text="Rotation")
row = split.row()
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
row.active = pchan.ik_rot_control
# not supported yet
#split = layout.split(percentage=0.3)
#row = split.row()
#row.itemR(pchan, "ik_lin_control", text="Size")
#row = split.row()
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
#row.active = pchan.ik_lin_control
col = split.column()
col.itemR(bone, "draw_wire", text="Wireframe")
col.itemR(bone, "hidden", text="Hide")
col = split.column()
col.itemL(text="Custom Shape:")
col.itemR(pchan, "custom_shape", text="")
class BONE_PT_deform(BoneButtonsPanel):
__label__ = "Deform"
@@ -289,65 +224,10 @@ class BONE_PT_deform(BoneButtonsPanel):
col.itemL(text="Offset:")
col.itemR(bone, "cyclic_offset")
class BONE_PT_iksolver_itasc(BoneButtonsPanel):
__idname__ = "BONE_PT_iksolver_itasc"
__label__ = "iTaSC parameters"
__default_closed__ = True
def poll(self, context):
ob = context.object
bone = context.bone
if ob and context.bone:
pchan = ob.pose.pose_channels[context.bone.name]
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
return False
def draw(self, context):
layout = self.layout
ob = context.object
itasc = ob.pose.ik_param
layout.row().itemR(itasc, "simulation")
if itasc.simulation:
split = layout.split()
row = split.row()
row.itemR(itasc, "reiteration")
row = split.row()
if itasc.reiteration:
itasc.initial_reiteration = True
row.itemR(itasc, "initial_reiteration")
row.active = not itasc.reiteration
flow = layout.column_flow()
flow.itemR(itasc, "precision")
flow.itemR(itasc, "num_iter")
flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
if itasc.simulation:
layout.itemR(itasc, "auto_step")
row = layout.row()
if itasc.auto_step:
row.itemR(itasc, "min_step")
row.itemR(itasc, "max_step")
else:
row.itemR(itasc, "num_step")
layout.itemR(itasc, "solver")
if itasc.simulation:
layout.itemR(itasc, "feedback")
layout.itemR(itasc, "max_velocity")
if itasc.solver == "DLS":
row = layout.row()
row.itemR(itasc, "dampmax")
row.itemR(itasc, "dampeps")
bpy.types.register(BONE_PT_context_bone)
bpy.types.register(BONE_PT_transform)
bpy.types.register(BONE_PT_transform_locks)
bpy.types.register(BONE_PT_bone)
bpy.types.register(BONE_PT_relations)
bpy.types.register(BONE_PT_display)
bpy.types.register(BONE_PT_deform)
bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_iksolver_itasc)

View File

@@ -249,7 +249,7 @@ class DATA_PT_area(DataButtonsPanel):
split = layout.split()
col = split.column()
col.itemR(lamp, "shape", text="")
col.row().itemR(lamp, "shape", expand=True)
sub = col.column(align=True)
if (lamp.shape == 'SQUARE'):
@@ -273,9 +273,9 @@ class DATA_PT_spot(DataButtonsPanel):
split = layout.split()
col = split.column()
sub = col.column(align=True)
sub = col.column()
sub.itemR(lamp, "spot_size", text="Size")
sub.itemR(lamp, "spot_blend", text="Blend")
sub.itemR(lamp, "spot_blend", text="Blend", slider=True)
col.itemR(lamp, "square")
col = split.column()

View File

@@ -610,6 +610,23 @@ class VolumeButtonsPanel(bpy.types.Panel):
engine = context.scene.render_data.engine
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
class MATERIAL_PT_volume_density(VolumeButtonsPanel):
__label__ = "Density"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
def draw(self, context):
layout = self.layout
mat = context.material
vol = context.material.volume
split = layout.split()
row = split.row()
row.itemR(vol, "density")
row.itemR(vol, "density_scale")
class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
__label__ = "Shading"
__default_closed__ = False
@@ -620,22 +637,23 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
vol = context.material.volume
row = layout.row()
row.itemR(vol, "density")
row.itemR(vol, "scattering")
split = layout.split()
col = split.column()
col.itemR(vol, "absorption")
col.itemR(vol, "absorption_color", text="")
col.itemR(vol, "scattering")
col.itemR(vol, "asymmetry")
col.itemR(vol, "transmission_color")
col = split.column()
col.itemR(vol, "emission")
col.itemR(vol, "emission_color", text="")
sub = col.column(align=True)
sub.itemR(vol, "emission")
sub.itemR(vol, "emission_color", text="")
sub = col.column(align=True)
sub.itemR(vol, "reflection")
sub.itemR(vol, "reflection_color", text="")
class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
__label__ = "Scattering"
class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
__label__ = "Lighting"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
@@ -648,12 +666,19 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
col = split.column()
col.itemR(vol, "scattering_mode", text="")
col = split.column()
if vol.scattering_mode == 'SINGLE_SCATTERING':
col.itemR(vol, "light_cache")
sub = col.column()
sub.active = vol.light_cache
sub.itemR(vol, "cache_resolution")
elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
sub = col.column()
sub.enabled = True
sub.active = False
sub.itemR(vol, "light_cache")
col.itemR(vol, "cache_resolution")
sub = col.column(align=True)
@@ -661,11 +686,6 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
sub.itemR(vol, "ms_spread")
sub.itemR(vol, "ms_intensity")
col = split.column()
# col.itemL(text="Anisotropic Scattering:")
col.itemR(vol, "phase_function", text="")
if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
col.itemR(vol, "asymmetry")
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
__label__= "Transparency"
@@ -693,16 +713,15 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
col = split.column()
col.itemL(text="Step Calculation:")
col.itemR(vol, "step_calculation", text="")
sub = col.column(align=True)
sub.itemR(vol, "step_size")
sub.itemR(vol, "shading_step_size")
col = col.column(align=True)
col.itemR(vol, "step_size")
col = split.column()
col.itemL()
col.itemR(vol, "depth_cutoff")
col.itemR(vol, "density_scale")
bpy.types.register(MATERIAL_PT_volume_density)
bpy.types.register(MATERIAL_PT_volume_shading)
bpy.types.register(MATERIAL_PT_volume_scattering)
bpy.types.register(MATERIAL_PT_volume_lighting)
bpy.types.register(MATERIAL_PT_volume_transp)
bpy.types.register(MATERIAL_PT_volume_integration)

View File

@@ -26,11 +26,50 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
ob = context.object
row = layout.row()
row.column().itemR(ob, "location")
row.column().itemR(ob, "rotation")
if ob.rotation_mode == 'QUATERNION':
row.column().itemR(ob, "rotation_quaternion", text="Rotation")
elif ob.rotation_mode == 'AXIS_ANGLE':
#row.column().itemL(text="Rotation")
#row.column().itemR(pchan, "rotation_angle", text="Angle")
#row.column().itemR(pchan, "rotation_axis", text="Axis")
row.column().itemR(ob, "rotation_axis_angle", text="Rotation")
else:
row.column().itemR(ob, "rotation_euler", text="Rotation")
row.column().itemR(ob, "scale")
layout.itemR(ob, "rotation_mode")
class OBJECT_PT_transform_locks(ObjectButtonsPanel):
__label__ = "Transform Locks"
__default_closed__ = True
def draw(self, context):
layout = self.layout
ob = context.object
row = layout.row()
col = row.column()
col.itemR(ob, "lock_location")
col = row.column()
if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
col.itemR(ob, "lock_rotations_4d", text="Lock Rotation")
if ob.lock_rotations_4d:
col.itemR(ob, "lock_rotation_w", text="W")
col.itemR(ob, "lock_rotation", text="")
else:
col.itemR(ob, "lock_rotation", text="Rotation")
row.column().itemR(ob, "lock_scale")
class OBJECT_PT_relations(ObjectButtonsPanel):
__label__ = "Relations"
@@ -178,6 +217,7 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
bpy.types.register(OBJECT_PT_context_object)
bpy.types.register(OBJECT_PT_transform)
bpy.types.register(OBJECT_PT_transform_locks)
bpy.types.register(OBJECT_PT_relations)
bpy.types.register(OBJECT_PT_groups)
bpy.types.register(OBJECT_PT_display)

View File

@@ -536,6 +536,145 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
for con in ob.constraints:
self.draw_constraint(context, con)
class BONE_PT_inverse_kinematics(ConstraintButtonsPanel):
__label__ = "Inverse Kinematics"
__default_closed__ = True
__context__ = "bone_constraint"
def poll(self, context):
ob = context.object
bone = context.bone
if ob and bone:
pchan = ob.pose.pose_channels[bone.name]
return pchan.has_ik
return False
def draw(self, context):
layout = self.layout
ob = context.object
bone = context.bone
pchan = ob.pose.pose_channels[bone.name]
row = layout.row()
row.itemR(ob.pose, "ik_solver")
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_x", text="X")
row = split.row()
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
row.active = pchan.ik_dof_x
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_x", text="Limit")
row.active = pchan.ik_dof_x
row = split.row(align=True)
row.itemR(pchan, "ik_min_x", text="")
row.itemR(pchan, "ik_max_x", text="")
row.active = pchan.ik_dof_x and pchan.ik_limit_x
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_y", text="Y")
row = split.row()
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
row.active = pchan.ik_dof_y
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_y", text="Limit")
row.active = pchan.ik_dof_y
row = split.row(align=True)
row.itemR(pchan, "ik_min_y", text="")
row.itemR(pchan, "ik_max_y", text="")
row.active = pchan.ik_dof_y and pchan.ik_limit_y
split = layout.split(percentage=0.25)
split.itemR(pchan, "ik_dof_z", text="Z")
row = split.row()
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
row.active = pchan.ik_dof_z
split = layout.split(percentage=0.25)
row = split.row()
row.itemR(pchan, "ik_limit_z", text="Limit")
row.active = pchan.ik_dof_z
row = split.row(align=True)
row.itemR(pchan, "ik_min_z", text="")
row.itemR(pchan, "ik_max_z", text="")
row.active = pchan.ik_dof_z and pchan.ik_limit_z
split = layout.split()
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
split.itemL()
if ob.pose.ik_solver == "ITASC":
layout.itemL(text="Joint constraint:")
split = layout.split(percentage=0.3)
row = split.row()
row.itemR(pchan, "ik_rot_control", text="Rotation")
row = split.row()
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
row.active = pchan.ik_rot_control
# not supported yet
#split = layout.split(percentage=0.3)
#row = split.row()
#row.itemR(pchan, "ik_lin_control", text="Size")
#row = split.row()
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
#row.active = pchan.ik_lin_control
class BONE_PT_iksolver_itasc(ConstraintButtonsPanel):
__label__ = "iTaSC parameters"
__default_closed__ = True
__context__ = "bone_constraint"
def poll(self, context):
ob = context.object
bone = context.bone
if ob and bone:
pchan = ob.pose.pose_channels[bone.name]
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
return False
def draw(self, context):
layout = self.layout
ob = context.object
itasc = ob.pose.ik_param
layout.itemR(itasc, "mode", expand=True)
simulation = itasc.mode == "SIMULATION"
if simulation:
layout.itemL(text="Reiteration:")
layout.itemR(itasc, "reiteration", expand=True)
flow = layout.column_flow()
flow.itemR(itasc, "precision", text="Prec")
flow.itemR(itasc, "num_iter", text="Iter")
flow.active = not simulation or itasc.reiteration != "NEVER"
if simulation:
layout.itemR(itasc, "auto_step")
row = layout.row()
if itasc.auto_step:
row.itemR(itasc, "min_step", text="Min")
row.itemR(itasc, "max_step", text="Max")
else:
row.itemR(itasc, "num_step")
layout.itemR(itasc, "solver")
if simulation:
layout.itemR(itasc, "feedback")
layout.itemR(itasc, "max_velocity")
if itasc.solver == "DLS":
row = layout.row()
row.itemR(itasc, "dampmax", text="Damp", slider=True)
row.itemR(itasc, "dampeps", text="Eps", slider=True)
class BONE_PT_constraints(ConstraintButtonsPanel):
__label__ = "Constraints"
__context__ = "bone_constraint"
@@ -558,4 +697,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel):
self.draw_constraint(context, con)
bpy.types.register(OBJECT_PT_constraints)
bpy.types.register(BONE_PT_iksolver_itasc)
bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_constraints)

View File

@@ -1,6 +1,11 @@
import bpy
from buttons_physics_common import point_cache_ui
from buttons_physics_common import effector_weights_ui
from buttons_physics_common import basic_force_field_settings_ui
from buttons_physics_common import basic_force_field_falloff_ui
def particle_panel_enabled(psys):
return psys.point_cache.baked==False and psys.edited==False
@@ -10,72 +15,6 @@ def particle_panel_poll(context):
if psys.settings==None: return False
return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
def point_cache_ui(self, cache, enabled, particles, smoke):
layout = self.layout
layout.set_context_pointer("PointCache", cache)
row = layout.row()
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
col = row.column(align=True)
col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
row = layout.row()
row.itemL(text="File Name:")
if particles:
row.itemR(cache, "external")
if cache.external:
split = layout.split(percentage=0.80)
split.itemR(cache, "name", text="")
split.itemR(cache, "index", text="")
layout.itemL(text="File Path:")
layout.itemR(cache, "filepath", text="")
layout.itemL(text=cache.info)
else:
layout.itemR(cache, "name", text="")
if not particles:
row = layout.row()
row.enabled = enabled
row.itemR(cache, "start_frame")
row.itemR(cache, "end_frame")
row = layout.row()
if cache.baked == True:
row.itemO("ptcache.free_bake", text="Free Bake")
else:
row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
sub = row.row()
sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
row = layout.row()
row.enabled = enabled
row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
if not smoke:
row.itemR(cache, "step");
if not smoke:
row = layout.row()
sub = row.row()
sub.enabled = enabled
sub.itemR(cache, "quick_cache")
row.itemR(cache, "disk_cache")
layout.itemL(text=cache.info)
layout.itemS()
row = layout.row()
row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
row.itemO("ptcache.free_bake_all", text="Free All Bakes")
layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
class ParticleButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
@@ -244,24 +183,23 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
split = layout.split()
col = split.column()
col.itemL(text="Quality:")
col.itemR(cloth, "quality", text="Steps",slider=True)
col.itemL(text="Gravity:")
col.itemR(cloth, "gravity", text="")
col = split.column()
col.itemL(text="Material:")
sub = col.column(align=True)
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
sub.itemR(cloth, "mass")
sub.itemR(cloth, "bending_stiffness", text="Bending")
sub.itemR(cloth, "internal_friction", slider="True")
col = split.column()
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
layout.itemR(cloth, "internal_friction", slider="True")
col.itemL(text="Quality:")
col.itemR(cloth, "quality", text="Steps",slider=True)
class PARTICLE_PT_cache(ParticleButtonsPanel):
__label__ = "Cache"
@@ -385,9 +323,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
sub.itemR(part, "brownian_factor")
sub.itemR(part, "drag_factor", slider=True)
sub.itemR(part, "damp_factor", slider=True)
sub.itemR(part, "integrator")
sub = split.column()
sub.itemR(part, "acceleration")
sub.itemR(part, "size_deflect")
sub.itemR(part, "die_on_collision")
sub.itemR(part, "integrator")
sub.itemR(part, "time_tweak")
elif part.physics_type == 'KEYED':
split = layout.split()
@@ -445,14 +385,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
col = row.column()
col.itemL(text="Misc:")
col.itemR(part, "gravity")
col.itemR(boids, "banking", slider=True)
col.itemR(boids, "height", slider=True)
if part.physics_type=='NEWTON':
sub.itemR(part, "size_deflect")
sub.itemR(part, "die_on_collision")
elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
if part.physics_type=='KEYED' or part.physics_type=='BOIDS':
if part.physics_type=='BOIDS':
layout.itemL(text="Relations:")
@@ -505,18 +441,18 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
boids = context.particle_system.settings.boids
layout = self.layout
layout.enabled = particle_panel_enabled(psys)
layout.enabled = particle_panel_enabled(context.particle_system)
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
#col = row.row()
#subrow = col.row(align=True)
#subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
#subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
#subrow.itemO("boid.state_add", icon='ICON_ZOOMIN', text="")
#subrow.itemO("boid.state_del", icon='ICON_ZOOMOUT', text="")
#subrow = row.row(align=True)
#subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
#subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
#subrow.itemO("boid.state_move_up", icon='VICON_MOVE_UP', text="")
#subrow.itemO("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
state = boids.active_boid_state
@@ -535,12 +471,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
col = row.column()
subrow = col.row()
subcol = subrow.column(align=True)
subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
subcol.item_menu_enumO("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
subcol.itemO("boid.rule_del", icon='ICON_ZOOMOUT', text="")
subrow = col.row()
subcol = subrow.column(align=True)
subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
subcol.itemO("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
subcol.itemO("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
rule = state.active_boid_rule
@@ -857,30 +793,41 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
sub = split.column()
sub.itemR(part, "kink_shape", slider=True)
class PARTICLE_PT_effectors(ParticleButtonsPanel):
__label__ = "Effectors"
class PARTICLE_PT_field_weights(ParticleButtonsPanel):
__label__ = "Field Weights"
__default_closed__ = True
def draw(self, context):
part = context.particle_system.settings
effector_weights_ui(self, part.effector_weights)
if part.type == 'HAIR':
self.layout.itemR(part.effector_weights, "do_growing_hair")
class PARTICLE_PT_force_fields(ParticleButtonsPanel):
__label__ = "Force Field Settings"
__default_closed__ = True
def draw(self, context):
layout = self.layout
part = context.particle_system.settings
psys = context.particle_system
part = psys.settings
layout.itemR(part, "self_effect")
layout.itemR(part, "effector_group")
split = layout.split(percentage=0.2)
split.itemL(text="Type 1:")
split.itemR(part.force_field_1, "type",text="")
basic_force_field_settings_ui(self, part.force_field_1)
basic_force_field_falloff_ui(self, part.force_field_1)
layout.itemR(part, "eweight_all", slider=True)
if part.force_field_1.type != 'NONE':
layout.itemL(text="")
layout.itemS()
layout.itemR(part, "eweight_spherical", slider=True)
layout.itemR(part, "eweight_vortex", slider=True)
layout.itemR(part, "eweight_magnetic", slider=True)
layout.itemR(part, "eweight_wind", slider=True)
layout.itemR(part, "eweight_curveguide", slider=True)
layout.itemR(part, "eweight_texture", slider=True)
layout.itemR(part, "eweight_harmonic", slider=True)
layout.itemR(part, "eweight_charge", slider=True)
layout.itemR(part, "eweight_lennardjones", slider=True)
split = layout.split(percentage=0.2)
split.itemL(text="Type 2:")
split.itemR(part.force_field_2, "type",text="")
basic_force_field_settings_ui(self, part.force_field_2)
basic_force_field_falloff_ui(self, part.force_field_2)
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
__label__ = "Vertexgroups"
@@ -957,5 +904,6 @@ bpy.types.register(PARTICLE_PT_boidbrain)
bpy.types.register(PARTICLE_PT_render)
bpy.types.register(PARTICLE_PT_draw)
bpy.types.register(PARTICLE_PT_children)
bpy.types.register(PARTICLE_PT_effectors)
bpy.types.register(PARTICLE_PT_field_weights)
bpy.types.register(PARTICLE_PT_force_fields)
bpy.types.register(PARTICLE_PT_vertexgroups)

View File

@@ -1,7 +1,8 @@
import bpy
from buttons_particle import point_cache_ui
from buttons_physics_common import point_cache_ui
from buttons_physics_common import effector_weights_ui
def cloth_panel_enabled(md):
return md.point_cache.baked==False
@@ -49,10 +50,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
split = layout.split()
col = split.column()
col.itemL(text="Quality:")
col.itemR(cloth, "quality", text="Steps",slider=True)
col.itemL(text="Gravity:")
col.itemR(cloth, "gravity", text="")
col.itemL(text="Material:")
sub = col.column(align=True)
sub.itemR(cloth, "mass")
sub.itemR(cloth, "structural_stiffness", text="Structural")
sub.itemR(cloth, "bending_stiffness", text="Bending")
col.itemR(cloth, "pin_cloth", text="Pin")
sub = col.column(align=True)
@@ -61,18 +63,18 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
col = split.column()
col.itemL(text="Presets...")
col.itemL(text="TODO!")
col.itemL(text="Material:")
sub = col.column(align=True)
sub.itemR(cloth, "mass")
sub.itemR(cloth, "structural_stiffness", text="Structural")
sub.itemR(cloth, "bending_stiffness", text="Bending")
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
col.itemL(text="Presets...")
col.itemL(text="TODO!")
col.itemL(text="Quality:")
col.itemR(cloth, "quality", text="Steps",slider=True)
# Disabled for now
"""
if cloth.mass_vertex_group:
@@ -166,7 +168,19 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
sub.itemR(cloth, "bending_stiffness_max", text="Max")
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel):
__label__ = "Cloth Field Weights"
__default_closed__ = True
def poll(self, context):
return (context.cloth)
def draw(self, context):
cloth = context.cloth.settings
effector_weights_ui(self, cloth.effector_weights)
bpy.types.register(PHYSICS_PT_cloth)
bpy.types.register(PHYSICS_PT_cloth_cache)
bpy.types.register(PHYSICS_PT_cloth_collision)
bpy.types.register(PHYSICS_PT_cloth_stiffness)
bpy.types.register(PHYSICS_PT_cloth_field_weights)

View File

@@ -0,0 +1,153 @@
import bpy
def point_cache_ui(self, cache, enabled, particles, smoke):
layout = self.layout
layout.set_context_pointer("PointCache", cache)
row = layout.row()
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
col = row.column(align=True)
col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
row = layout.row()
row.itemL(text="File Name:")
if particles:
row.itemR(cache, "external")
if cache.external:
split = layout.split(percentage=0.80)
split.itemR(cache, "name", text="")
split.itemR(cache, "index", text="")
layout.itemL(text="File Path:")
layout.itemR(cache, "filepath", text="")
layout.itemL(text=cache.info)
else:
layout.itemR(cache, "name", text="")
if not particles:
row = layout.row()
row.enabled = enabled
row.itemR(cache, "start_frame")
row.itemR(cache, "end_frame")
row = layout.row()
if cache.baked == True:
row.itemO("ptcache.free_bake", text="Free Bake")
else:
row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
sub = row.row()
sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
row = layout.row()
row.enabled = enabled
row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
if not smoke:
row.itemR(cache, "step");
if not smoke:
row = layout.row()
sub = row.row()
sub.enabled = enabled
sub.itemR(cache, "quick_cache")
row.itemR(cache, "disk_cache")
layout.itemL(text=cache.info)
layout.itemS()
row = layout.row()
row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
row.itemO("ptcache.free_bake_all", text="Free All Bakes")
layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
def effector_weights_ui(self, weights):
layout = self.layout
layout.itemR(weights, "group")
split = layout.split()
split.itemR(weights, "gravity", slider=True)
split.itemR(weights, "all", slider=True)
layout.itemS()
flow = layout.column_flow()
flow.itemR(weights, "spherical", slider=True)
flow.itemR(weights, "vortex", slider=True)
flow.itemR(weights, "magnetic", slider=True)
flow.itemR(weights, "wind", slider=True)
flow.itemR(weights, "curveguide", slider=True)
flow.itemR(weights, "texture", slider=True)
flow.itemR(weights, "harmonic", slider=True)
flow.itemR(weights, "charge", slider=True)
flow.itemR(weights, "lennardjones", slider=True)
flow.itemR(weights, "turbulence", slider=True)
flow.itemR(weights, "drag", slider=True)
flow.itemR(weights, "boid", slider=True)
def basic_force_field_settings_ui(self, field):
layout = self.layout
split = layout.split()
if not field or field.type == 'NONE':
return
col = split.column()
if field.type == 'DRAG':
col.itemR(field, "linear_drag", text="Linear")
else:
col.itemR(field, "strength")
if field.type == 'TURBULENCE':
col.itemR(field, "size")
col.itemR(field, "flow")
elif field.type == 'HARMONIC':
col.itemR(field, "harmonic_damping", text="Damping")
elif field.type == 'VORTEX' and field.shape == 'PLANE':
col.itemR(field, "inflow")
elif field.type == 'DRAG':
col.itemR(field, "quadratic_drag", text="Quadratic")
else:
col.itemR(field, "flow")
col = split.column()
col.itemR(field, "noise")
col.itemR(field, "seed")
if field.type == 'TURBULENCE':
col.itemR(field, "global_coordinates", text="Global")
row = layout.row()
row.itemL(text="Effect point:")
row.itemR(field, "do_location")
row.itemR(field, "do_rotation")
def basic_force_field_falloff_ui(self, field):
layout = self.layout
split = layout.split(percentage=0.35)
if not field or field.type == 'NONE':
return
col = split.column()
col.itemR(field, "z_direction", text="")
col.itemR(field, "use_min_distance", text="Use Minimum")
col.itemR(field, "use_max_distance", text="Use Maximum")
col = split.column()
col.itemR(field, "falloff_power", text="Power")
sub = col.column()
sub.active = field.use_min_distance
sub.itemR(field, "minimum_distance", text="Distance")
sub = col.column()
sub.active = field.use_max_distance
sub.itemR(field, "maximum_distance", text="Distance")

View File

@@ -1,6 +1,9 @@
import bpy
from buttons_physics_common import basic_force_field_settings_ui
from buttons_physics_common import basic_force_field_falloff_ui
class PhysicButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
@@ -12,7 +15,6 @@ class PhysicButtonsPanel(bpy.types.Panel):
class PHYSICS_PT_field(PhysicButtonsPanel):
__label__ = "Force Fields"
__default_closed__ = True
def draw(self, context):
layout = self.layout
@@ -20,53 +22,48 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
ob = context.object
field = ob.field
#layout.active = field.enabled
split = layout.split(percentage=0.2)
split.itemL(text="Type:")
split.itemR(field, "type",text="")
if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
split = layout.split(percentage=0.2)
#split = layout.row()
split.itemL(text="Shape:")
split.itemR(field, "shape", text="")
split = layout.split()
if field.type == 'GUIDE':
layout.itemR(field, "guide_path_add")
elif field.type == 'WIND':
split.itemR(field, "strength")
if field.type == 'NONE':
return # nothing to draw
elif field.type == 'GUIDE':
col = split.column()
col.itemR(field, "guide_minimum")
col.itemR(field, "guide_free")
col.itemR(field, "falloff_power")
col.itemR(field, "guide_path_add")
col = split.column()
col.itemR(field, "noise")
col.itemR(field, "seed")
col.itemL(text="Clumping:")
col.itemR(field, "guide_clump_amount")
col.itemR(field, "guide_clump_shape")
elif field.type == 'VORTEX':
split.itemR(field, "strength")
split.itemL()
row = layout.row()
row.itemR(field, "use_max_distance")
sub = row.row()
sub.active = field.use_max_distance
sub.itemR(field, "maximum_distance")
elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
split.itemR(field, "strength")
layout.itemS()
col = split.column()
col.itemR(field, "planar")
col.itemR(field, "surface")
elif field.type == 'BOID':
split.itemR(field, "strength")
split.itemR(field, "surface")
elif field.type == 'MAGNET':
split.itemR(field, "strength")
split.itemR(field, "planar")
elif field.type == 'HARMONIC':
col = split.column()
col.itemR(field, "strength")
col.itemR(field, "harmonic_damping", text="Damping")
col = split.column()
col.itemR(field, "planar")
col.itemR(field, "surface")
layout.itemR(field, "guide_kink_type")
if (field.guide_kink_type != "NONE"):
layout.itemR(field, "guide_kink_axis")
flow = layout.column_flow()
flow.itemR(field, "guide_kink_frequency")
flow.itemR(field, "guide_kink_shape")
flow.itemR(field, "guide_kink_amplitude")
elif field.type == 'TEXTURE':
col = split.column()
col.itemR(field, "strength")
@@ -78,29 +75,15 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
col.itemR(field, "use_coordinates")
col.itemR(field, "root_coordinates")
col.itemR(field, "force_2d")
else :
basic_force_field_settings_ui(self, field)
if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'):
if field.type not in ('NONE', 'GUIDE'):
layout.itemL(text="Falloff:")
layout.itemR(field, "falloff_type", expand=True)
split = layout.split(percentage=0.35)
col = split.column()
col.itemR(field, "positive_z", text="Positive Z")
col.itemR(field, "use_min_distance", text="Use Minimum")
col.itemR(field, "use_max_distance", text="Use Maximum")
col = split.column()
col.itemR(field, "falloff_power", text="Power")
sub = col.column()
sub.active = field.use_min_distance
sub.itemR(field, "minimum_distance", text="Distance")
sub = col.column()
sub.active = field.use_max_distance
sub.itemR(field, "maximum_distance", text="Distance")
basic_force_field_falloff_ui(self, field)
if field.falloff_type == 'CONE':
layout.itemS()
@@ -144,20 +127,9 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
sub.active = field.use_radial_max
sub.itemR(field, "radial_maximum", text="Distance")
#if ob.type in 'CURVE':
#if field.type == 'GUIDE':
#colsub = col.column(align=True)
#if field.type != 'NONE':
#layout.itemR(field, "strength")
#if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"):
#if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'):
#layout.itemR(field, "surface")
class PHYSICS_PT_collision(PhysicButtonsPanel):
__label__ = "Collision"
__default_closed__ = True
#__default_closed__ = True
def poll(self, context):
ob = context.object
@@ -182,16 +154,18 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
#row.itemR(md, "render", text="")
#row.itemR(md, "realtime", text="")
settings = md.settings
coll = md.settings
else:
# add modifier
split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add")
split.itemL()
settings = None
coll = None
if coll:
settings = context.object.collision
if settings:
layout.active = settings.enabled
split = layout.split()

View File

@@ -1,7 +1,8 @@
import bpy
from buttons_particle import point_cache_ui
from buttons_physics_common import point_cache_ui
from buttons_physics_common import effector_weights_ui
def softbody_panel_enabled(md):
return md.point_cache.baked==False
@@ -55,7 +56,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
col = split.column()
col.itemL(text="Simulation:")
col.itemR(softbody, "gravity")
col.itemR(softbody, "speed")
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
@@ -223,9 +223,22 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
layout.itemL(text="Diagnostics:")
layout.itemR(softbody, "diagnose")
class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
__label__ = "Soft Body Field Weights"
__default_closed__ = True
def poll(self, context):
return (context.soft_body)
def draw(self, context):
md = context.soft_body
softbody = md.settings
effector_weights_ui(self, softbody.effector_weights)
bpy.types.register(PHYSICS_PT_softbody)
bpy.types.register(PHYSICS_PT_softbody_cache)
bpy.types.register(PHYSICS_PT_softbody_goal)
bpy.types.register(PHYSICS_PT_softbody_edge)
bpy.types.register(PHYSICS_PT_softbody_collision)
bpy.types.register(PHYSICS_PT_softbody_solver)
bpy.types.register(PHYSICS_PT_softbody_field_weights)

View File

@@ -1,6 +1,14 @@
import bpy
class SceneButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
__context__ = "scene"
def poll(self, context):
return (context.scene != None)
class RenderButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
@@ -254,12 +262,11 @@ class SCENE_PT_output(RenderButtonsPanel):
split = layout.split()
col = split.column()
col.itemL(text="Depth:")
col.row().itemR(rd, "jpeg_depth", expand=True)
col.row().itemR(rd, "jpeg2k_depth", expand=True)
col = split.column()
col.itemR(rd, "jpeg_preset", text="")
col.itemR(rd, "jpeg_ycc")
col.itemR(rd, "exr_preview")
col.itemR(rd, "jpeg2k_preset", text="")
col.itemR(rd, "jpeg2k_ycc")
elif rd.file_format in ('CINEON', 'DPX'):
split = layout.split()
@@ -452,6 +459,101 @@ class SCENE_PT_unit(RenderButtonsPanel):
row.itemR(unit, "scale_length", text="Scale")
row.itemR(unit, "use_separate")
class SCENE_PT_keying_sets(SceneButtonsPanel):
__label__ = "Keying Sets"
__default_closed__ = True
def draw(self, context):
layout = self.layout
scene = context.scene
row = layout.row()
col = row.column()
col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
col = row.column(align=True)
col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
ks = scene.active_keying_set
if ks:
row = layout.row()
col = row.column()
col.itemR(ks, "name")
col.itemR(ks, "absolute")
col = row.column()
col.itemL(text="Keyframing Settings:")
col.itemR(ks, "insertkey_needed", text="Needed")
col.itemR(ks, "insertkey_visual", text="Visual")
class SCENE_PT_keying_set_paths(SceneButtonsPanel):
__label__ = "Active Keying Set"
__default_closed__ = True
def poll(self, context):
return (context.scene != None) and (context.scene.active_keying_set != None)
def draw(self, context):
layout = self.layout
scene = context.scene
ks = scene.active_keying_set
row = layout.row()
col = row.column()
col.template_list(ks, "paths", ks, "active_path_index", rows=2)
col = row.column(align=True)
col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
ksp = ks.active_path
if ksp:
col = layout.column()
col.itemL(text="Target:")
col.itemR(ksp, "id")
col.itemR(ksp, "rna_path")
row = layout.row()
col = row.column()
col.itemL(text="Array Target:")
col.itemR(ksp, "entire_array")
if ksp.entire_array == False:
col.itemR(ksp, "array_index")
col = row.column()
col.itemL(text="F-Curve Grouping:")
col.itemR(ksp, "grouping")
if ksp.grouping == 'NAMED':
col.itemR(ksp, "group")
class SCENE_PT_physics(RenderButtonsPanel):
__label__ = "Gravity"
COMPAT_ENGINES = set(['BLENDER_RENDER'])
def draw_header(self, context):
self.layout.itemR(context.scene, "use_gravity", text="")
def draw(self, context):
layout = self.layout
scene = context.scene
layout.active = scene.use_gravity
layout.itemR(scene, "gravity", text="")
bpy.types.register(SCENE_PT_render)
bpy.types.register(SCENE_PT_layers)
bpy.types.register(SCENE_PT_dimensions)
@@ -463,3 +565,6 @@ bpy.types.register(SCENE_PT_performance)
bpy.types.register(SCENE_PT_post_processing)
bpy.types.register(SCENE_PT_stamp)
bpy.types.register(SCENE_PT_unit)
bpy.types.register(SCENE_PT_keying_sets)
bpy.types.register(SCENE_PT_keying_set_paths)
bpy.types.register(SCENE_PT_physics)

View File

@@ -175,14 +175,14 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
row.itemR(tex, "z_mapping", text="")
if br:
layout.itemR(tex, "brush_map_mode", expand=True)
layout.itemR(tex, "map_mode", expand=True)
row = layout.row()
row.active = tex.brush_map_mode in ('FIXED', 'TILED')
row.active = tex.map_mode in ('FIXED', 'TILED')
row.itemR(tex, "angle")
row = layout.row()
row.active = tex.brush_map_mode in ('TILED', '3D')
row.active = tex.map_mode in ('TILED', '3D')
row.column().itemR(tex, "size")
else:
row = layout.row()
@@ -246,13 +246,14 @@ class TEXTURE_PT_influence(TextureSlotPanel):
col = split.column()
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
factor_but(col, tex.map_absorption, "map_absorption", "absorption_factor", "Absorption")
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
col = split.column()
col.itemL(text=" ")
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color")
factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
elif la:
row = layout.row()
@@ -642,6 +643,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
row.itemR(vd, "still_frame_number")
layout.itemR(vd, "interpolation")
layout.itemR(vd, "extension")
layout.itemR(vd, "intensity")
class TEXTURE_PT_pointdensity(TextureButtonsPanel):

View File

@@ -1,9 +1,5 @@
import bpy
import bpy_ops # XXX - should not need to do this
del bpy_ops
class CONSOLE_HT_header(bpy.types.Header):
__space_type__ = 'CONSOLE'
@@ -184,212 +180,6 @@ class CONSOLE_OT_exec(bpy.types.Operator):
return ('FINISHED',)
def autocomp(bcon):
'''
This function has been taken from a BGE console autocomp I wrote a while ago
the dictionaty bcon is not needed but it means I can copy and paste from the old func
which works ok for now.
could be moved into its own module.
'''
def is_delimiter(ch):
'''
For skipping words
'''
if ch == '_':
return False
if ch.isalnum():
return False
return True
def is_delimiter_autocomp(ch):
'''
When autocompleteing will earch back and
'''
if ch in '._[] "\'':
return False
if ch.isalnum():
return False
return True
def do_autocomp(autocomp_prefix, autocomp_members):
'''
return text to insert and a list of options
'''
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
print("AUTO: '%s'" % autocomp_prefix)
print("MEMBERS: '%s'" % str(autocomp_members))
if not autocomp_prefix:
return '', autocomp_members
elif len(autocomp_members) > 1:
# find a common string between all members after the prefix
# 'ge' [getA, getB, getC] --> 'get'
# get the shortest member
min_len = min([len(v) for v in autocomp_members])
autocomp_prefix_ret = ''
for i in range(len(autocomp_prefix), min_len):
char_soup = set()
for v in autocomp_members:
char_soup.add(v[i])
if len(char_soup) > 1:
break
else:
autocomp_prefix_ret += char_soup.pop()
return autocomp_prefix_ret, autocomp_members
elif len(autocomp_members) == 1:
if autocomp_prefix == autocomp_members[0]:
# the variable matched the prefix exactly
# add a '.' so you can quickly continue.
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
return '.', []
else:
# finish off the of the word word
return autocomp_members[0][len(autocomp_prefix):], []
else:
return '', []
def BCon_PrevChar(bcon):
cursor = bcon['cursor']-1
if cursor<0:
return None
try:
return bcon['edit_text'][cursor]
except:
return None
def BCon_NextChar(bcon):
try:
return bcon['edit_text'][bcon['cursor']]
except:
return None
def BCon_cursorLeft(bcon):
bcon['cursor'] -= 1
if bcon['cursor'] < 0:
bcon['cursor'] = 0
def BCon_cursorRight(bcon):
bcon['cursor'] += 1
if bcon['cursor'] > len(bcon['edit_text']):
bcon['cursor'] = len(bcon['edit_text'])
def BCon_AddScrollback(bcon, text):
bcon['scrollback'] = bcon['scrollback'] + text
def BCon_cursorInsertChar(bcon, ch):
if bcon['cursor']==0:
bcon['edit_text'] = ch + bcon['edit_text']
elif bcon['cursor']==len(bcon['edit_text']):
bcon['edit_text'] = bcon['edit_text'] + ch
else:
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
bcon['cursor']
if bcon['cursor'] > len(bcon['edit_text']):
bcon['cursor'] = len(bcon['edit_text'])
BCon_cursorRight(bcon)
TEMP_NAME = '___tempname___'
cursor_orig = bcon['cursor']
ch = BCon_PrevChar(bcon)
while ch != None and (not is_delimiter(ch)):
ch = BCon_PrevChar(bcon)
BCon_cursorLeft(bcon)
if ch != None:
BCon_cursorRight(bcon)
#print (cursor_orig, bcon['cursor'])
cursor_base = bcon['cursor']
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
print("PREFIX:'%s'" % autocomp_prefix)
# Get the previous word
if BCon_PrevChar(bcon)=='.':
BCon_cursorLeft(bcon)
ch = BCon_PrevChar(bcon)
while ch != None and is_delimiter_autocomp(ch)==False:
ch = BCon_PrevChar(bcon)
BCon_cursorLeft(bcon)
cursor_new = bcon['cursor']
if ch != None:
cursor_new+=1
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
print("AUTOCOMP EVAL: '%s'" % pytxt)
#try:
if pytxt:
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
# print val
else: ##except:
val = None
try:
val = bcon['namespace'][TEMP_NAME]
del bcon['namespace'][TEMP_NAME]
except:
val = None
if val:
autocomp_members = dir(val)
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
bcon['cursor'] = cursor_orig
for v in autocomp_prefix_ret:
BCon_cursorInsertChar(bcon, v)
cursor_orig = bcon['cursor']
if autocomp_members:
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
del val
else:
# Autocomp global namespace
autocomp_members = bcon['namespace'].keys()
if autocomp_prefix:
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
bcon['cursor'] = cursor_orig
for v in autocomp_prefix_ret:
BCon_cursorInsertChar(bcon, v)
cursor_orig = bcon['cursor']
if autocomp_members:
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
bcon['cursor'] = cursor_orig
class CONSOLE_OT_autocomplete(bpy.types.Operator):
'''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.'''
__idname__ = "console.autocomplete"
@@ -425,7 +215,8 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator):
# This function isnt aware of the text editor or being an operator
# just does the autocomp then copy its results back
autocomp(bcon)
import autocomplete
autocomplete.execute(bcon)
# Now we need to copy back the line from blender back into the text editor.
# This will change when we dont use the text editor anymore

View File

@@ -145,6 +145,10 @@ class INFO_MT_add(bpy.types.Menu):
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
layout.itemS()
layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
class INFO_MT_game(bpy.types.Menu):
__space_type__ = 'INFO'
__label__ = "Game"
@@ -211,9 +215,6 @@ bpy.types.register(INFO_MT_help)
# Help operators
import bpy_ops # XXX - should not need to do this
del bpy_ops
class HelpOperator(bpy.types.Operator):
def execute(self, context):
try: import webbrowser

View File

@@ -314,6 +314,7 @@ class USERPREF_PT_system(bpy.types.Panel):
sub1.itemL(text="OpenGL:")
sub1.itemR(system, "clip_alpha", slider=True)
sub1.itemR(system, "use_mipmaps")
sub1.itemR(system, "use_vbos")
sub1.itemL(text="Window Draw Method:")
sub1.row().itemR(system, "window_draw_method", expand=True)
sub1.itemL(text="Textures:")

View File

@@ -1285,6 +1285,26 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
col.itemR(bg, "offset_x", text="X")
col.itemR(bg, "offset_y", text="Y")
class VIEW3D_PT_transform_orientations(bpy.types.Panel):
__space_type__ = 'VIEW_3D'
__region_type__ = 'UI'
__label__ = "Transform Orientations"
__default_closed__ = True
def poll(self, context):
view = context.space_data
return (view)
def draw(self, context):
layout = self.layout
view = context.space_data
col = layout.column()
col.itemO("TFM_OT_select_orientation", text="Select")
col.itemO("TFM_OT_create_orientation", text="Create")
col.itemO("TFM_OT_delete_orientation", text="Delete")
bpy.types.register(VIEW3D_HT_header) # Header
bpy.types.register(VIEW3D_MT_view) #View Menus
@@ -1360,3 +1380,4 @@ bpy.types.register(VIEW3D_PT_3dview_display)
bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
bpy.types.register(VIEW3D_PT_background_image)
bpy.types.register(VIEW3D_PT_transform_orientations)

View File

@@ -249,7 +249,7 @@ PULIB += $(OCGDIR)/blender/ed_graph/$(DEBUG_DIR)libed_graph.a
PULIB += $(OCGDIR)/blender/ed_node/$(DEBUG_DIR)libed_node.a
PULIB += $(OCGDIR)/blender/ed_outliner/$(DEBUG_DIR)libed_outliner.a
PULIB += $(OCGDIR)/blender/ed_time/$(DEBUG_DIR)libed_time.a
PULIB += $(OCGDIR)/blender/ed_preview/$(DEBUG_DIR)libed_preview.a
PULIB += $(OCGDIR)/blender/ed_render/$(DEBUG_DIR)libed_render.a
PULIB += $(OCGDIR)/blender/ed_view3d/$(DEBUG_DIR)libed_view3d.a
PULIB += $(OCGDIR)/blender/ed_interface/$(DEBUG_DIR)libed_interface.a
PULIB += $(OCGDIR)/blender/ed_object/$(DEBUG_DIR)libed_object.a

View File

@@ -58,6 +58,7 @@ struct ModifierData;
struct MCol;
struct ColorBand;
struct GPUVertexAttribs;
struct GPUDrawObject;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
@@ -72,6 +73,7 @@ struct DerivedMesh {
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
BVHCache bvhCache;
struct GPUDrawObject *drawObject;
/* Misc. Queries */

View File

@@ -103,6 +103,9 @@ void armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], flo
void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc);
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode);
/* B-Bone support */
typedef struct Mat4 {
float mat[4][4];

View File

@@ -43,7 +43,7 @@ struct bContext;
struct ReportList;
#define BLENDER_VERSION 250
#define BLENDER_SUBVERSION 3
#define BLENDER_SUBVERSION 4
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0

View File

@@ -141,6 +141,15 @@ void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3],
/////////////////////////////////////////////////
Object **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj);
typedef struct ColliderCache {
struct ColliderCache *next, *prev;
struct Object *ob;
struct CollisionModifierData *collmd;
} ColliderCache;
struct ListBase *get_collider_cache(struct Scene *scene, Object *self);
void free_collider_cache(struct ListBase **colliders);
/////////////////////////////////////////////////

View File

@@ -116,4 +116,7 @@ void DAG_ids_flush_update(int time);
/* (re)-create dependency graph for armature pose */
void DAG_pose_sort(struct Object *ob);
/* callback for editors module to do updates */
void DAG_editors_update_cb(void (*func)(struct Main *bmain, struct ID *id));
#endif

View File

@@ -32,6 +32,7 @@
#define BKE_EFFECT_H
#include "DNA_object_types.h"
#include "DNA_modifier_types.h"
struct Object;
struct Scene;
@@ -40,20 +41,72 @@ struct ListBase;
struct Particle;
struct Group;
struct RNG;
struct ParticleSimulationData;
struct ParticleData;
struct ParticleKey;
struct PartDeflect *object_add_collision_fields(void);
struct EffectorWeights *BKE_add_effector_weights(struct Group *group);
struct PartDeflect *object_add_collision_fields(int type);
typedef struct pEffectorCache {
struct pEffectorCache *next, *prev;
Object *ob;
/* Input to effector code */
typedef struct EffectedPoint {
float *loc;
float *vel;
float *ave; /* angular velocity for particles with dynamic rotation */
float *rot; /* rotation quaternion for particles with dynamic rotation */
float vel_to_frame;
float vel_to_sec;
/* precalculated variables */
float oldloc[3], oldspeed[3];
float scale, time_scale;
float guide_dist;
/* only for particles */
float size, charge;
Object obcopy; /* for restoring transformation data */
} pEffectorCache;
unsigned int flag;
int index;
struct ParticleSystem *psys; /* particle system the point belongs to */
} EffectedPoint;
typedef struct GuideEffectorData {
float vec_to_point[3];
float strength;
} GuideEffectorData;
typedef struct EffectorData {
/* Effector point */
float loc[3];
float nor[3];
float vel[3];
float vec_to_point[3];
float distance, falloff;
/* only for effector particles */
float size, charge;
/* only for vortex effector with surface falloff */
float nor2[3], vec_to_point2[3];
int *index; /* point index */
} EffectorData;
/* used for calculating the effector force */
typedef struct EffectorCache {
struct EffectorCache *next, *prev;
struct Scene *scene;
struct Object *ob;
struct ParticleSystem *psys;
struct SurfaceModifierData *surmd;
struct PartDeflect *pd;
/* precalculated for guides */
struct GuideEffectorData *guide_data;
float guide_loc[4], guide_dir[3], guide_radius;
float frame;
int flag;
} EffectorCache;
void free_effect(struct Effect *eff);
void free_effects(struct ListBase *lb);
@@ -61,23 +114,33 @@ struct Effect *copy_effect(struct Effect *eff);
void copy_effects(struct ListBase *lbn, struct ListBase *lb);
void deselectall_eff(struct Object *ob);
/* particle deflector */
#define PE_WIND_AS_SPEED 0x00000001
struct PartEff *give_parteff(struct Object *ob);
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *obsrc, struct Group *group);
void pdEndEffectors(struct ListBase *lb);
void pdDoEffectors(struct Scene *scene, struct ListBase *lb, float *opco, float *force,
float *speed, float cur_time, float loc_time, unsigned int flags);
void free_partdeflect(struct PartDeflect *pd);
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights);
void pdEndEffectors(struct ListBase **effectors);
void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
/* needed for boids */
float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights);
int closest_point_on_surface(struct SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel);
int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity);
/* required for particle_system.c */
void do_physical_effector(struct Scene *scene, struct Object *ob, float *opco, short type, float force_val, float distance,
float falloff, float size, float damp, float *eff_velocity, float *vec_to_part,
float *velocity, float *field, int planar, struct RNG *rng, float noise_factor,
float charge, float pa_size);
float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part);
//void do_physical_effector(struct EffectorData *eff, struct EffectorPoint *point, float *total_force);
//float effector_falloff(struct EffectorData *eff, struct EffectorPoint *point, struct EffectorWeights *weights);
/* EffectedPoint->flag */
#define PE_WIND_AS_SPEED 1
#define PE_DYNAMIC_ROTATION 2
/* EffectorData->flag */
#define PE_VELOCITY_TO_IMPULSE 1
#endif

View File

@@ -107,6 +107,11 @@ struct RenderResult;
/* always call to make signals work */
struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
/* same as above, but can be used to retrieve images being rendered in
* a thread safe way, always call both acquire and release */
struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r);
void BKE_image_release_ibuf(struct Image *ima, void *lock);
/* returns existing Image when filename/type is same (frame optional) */
struct Image *BKE_add_image_file(const char *name, int frame);
@@ -135,7 +140,8 @@ void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser);
/* for multilayer images as well as for render-viewer */
struct RenderResult *BKE_image_get_renderresult(struct Scene *scene, struct Image *ima);
struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
/* goes over all textures that use images */
void BKE_image_free_all_textures(void);

View File

@@ -426,7 +426,7 @@ extern struct ListBase node_all_textures;
/* API */
int ntreeTexTagAnimated(struct bNodeTree *ntree);
void ntreeTexSetPreviewFlag(int);
void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, short thread, struct Tex *tex, short which_output, int cfra);
void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, short thread, struct Tex *tex, short which_output, int cfra, int preview);
void ntreeTexCheckCyclics(struct bNodeTree *ntree);
char* ntreeTexOutputMenu(struct bNodeTree *ntree);

View File

@@ -88,6 +88,8 @@ typedef struct SculptSession {
struct SculptStroke *stroke;
struct StrokeCache *cache;
struct GPUDrawObject *drawobject;
} SculptSession;
void free_sculptsession(SculptSession **);

View File

@@ -76,39 +76,18 @@ typedef struct ParticleSimulationData {
struct Object *ob;
struct ParticleSystem *psys;
struct ParticleSystemModifierData *psmd;
float timestep;
struct ListBase *colliders;
} ParticleSimulationData;
typedef struct ParticleEffectorCache {
struct ParticleEffectorCache *next, *prev;
struct Object *ob;
/* precalculated variables for guides */
float firstloc[4], firstdir[3];
float *distances;
float *locations;
/* precalculated variables for deflection */
float ob_minmax[6];
float *face_minmax;
float *vert_cos;
/* precalculated variables for boids */
struct KDTree *tree;
short type, psys_nbr;
struct Object obcopy; /* for restoring transformation data */
struct RNG *rng; /* random noise generator for e.g. wind */
} ParticleEffectorCache;
typedef struct ParticleReactEvent {
struct ParticleReactEvent *next, *prev;
int event, pa_num;
Object *ob;
struct ParticleSystem *psys;
struct ParticleKey state;
float time, size;
}ParticleReactEvent;
//typedef struct ParticleReactEvent {
// struct ParticleReactEvent *next, *prev;
// int event, pa_num;
// Object *ob;
// struct ParticleSystem *psys;
// struct ParticleKey state;
//
// float time, size;
//}ParticleReactEvent;
typedef struct ParticleTexture{
float ivel; /* used in reset */
@@ -185,8 +164,8 @@ typedef struct ParticleBillboardData
/* container for moving data between deflet_particle and particle_intersect_face */
typedef struct ParticleCollision
{
struct Object *ob, *ob_t; // collided and current objects
struct CollisionModifierData *md; // collision modifier for ob_t;
struct Object *ob, *hit_ob; // collided and current objects
struct CollisionModifierData *md, *hit_md; // collision modifiers for current and hit object;
float nor[3]; // normal at collision point
float vel[3]; // velocity of collision point
float co1[3], co2[3]; // ray start and end points
@@ -244,7 +223,6 @@ void object_add_particle_system(struct Scene *scene, struct Object *ob);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
void make_local_particlesettings(struct ParticleSettings *part);
void psys_reset(struct ParticleSystem *psys, int mode);
@@ -254,7 +232,8 @@ void psys_find_parents(struct ParticleSimulationData *sim);
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
@@ -273,9 +252,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
/* particle_system.c */
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
void psys_count_keyed_targets(struct ParticleSimulationData *sim);
//void psys_get_reactor_target(struct ParticleSimulationData *sim, struct Object **target_ob, struct ParticleSystem **target_psys);
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc);
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);
@@ -316,29 +293,17 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_
/* particle_system.c */
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p);
int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index);
void do_effectors(struct ParticleSimulationData *sim, int pa_no, struct ParticleData *pa, struct ParticleKey *state, float *texco, float *force_field, float *vel,float framestep, float cfra);
void psys_end_effectors(struct ParticleSystem *psys);
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
/* psys_reset */
#define PSYS_RESET_ALL 1
#define PSYS_RESET_DEPSGRAPH 2
#define PSYS_RESET_CHILDREN 3
#define PSYS_RESET_CACHE_MISS 4
/* ParticleEffectorCache->type */
#define PSYS_EC_EFFECTOR 1
#define PSYS_EC_DEFLECT 2
#define PSYS_EC_PARTICLE 4
#define PSYS_EC_REACTOR 8
/* index_dmcache */
#define DMCACHE_NOTFOUND -1
#define DMCACHE_ISCHILD -2

View File

@@ -84,6 +84,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "gpu_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -218,7 +219,7 @@ int DM_release(DerivedMesh *dm)
{
if (dm->needsFree) {
bvhcache_free(&dm->bvhCache);
GPU_drawobject_free( dm );
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numFaceData);
@@ -490,6 +491,44 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
glEnd();
} else {
GPUBuffer *buffer = 0;
float *varray;
if( setDrawOptions == 0 ) {
buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 );
}
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0;
int numedges = 0;
int draw = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
varray = GPU_buffer_lock_stream( buffer );
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
draw = 1;
} else {
draw = 0;
}
if( prevdraw != draw && prevdraw != 0 && numedges > 0) {
GPU_buffer_unlock( buffer );
glDrawArrays(GL_LINES,0,numedges*2);
varray = GPU_buffer_lock_stream( buffer );
numedges = 0;
}
if( draw != 0 ) {
VECCOPY(&varray[numedges*6],eed->v1->co);
VECCOPY(&varray[numedges*6+3],eed->v2->co);
numedges++;
}
prevdraw = draw;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numedges > 0) {
glDrawArrays(GL_LINES,0,numedges*2);
}
GPU_buffer_unbind();
} else {
glBegin(GL_LINES);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
@@ -500,6 +539,9 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
glEnd();
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
{
@@ -658,6 +700,97 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
glDisable(GL_POLYGON_STIPPLE);
}
}
} else {
GPUBuffer *buffer = 0;
float *varray;
if( setDrawOptions == 0 ) {
/* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
buffer = GPU_buffer_alloc( sizeof(float)*6*emdm->em->totface*3*2, 0 );
}
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0;
int numfaces = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
glShadeModel(GL_SMOOTH);
varray = GPU_buffer_lock_stream( buffer );
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
GPU_buffer_unlock( buffer );
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
varray = GPU_buffer_lock_stream( buffer );
numfaces = 0;
}
if( draw != 0 ) {
if(!drawSmooth) {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
}
}
else {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->v1->no);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->v2->no);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->v3->no);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->v3->no);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->v4->no);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->v1->no);
numfaces++;
}
}
}
prevdraw = draw;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
}
GPU_buffer_unbind();
} else {
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
@@ -695,6 +828,9 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}
static void emDM_drawFacesTex_common(DerivedMesh *dm,

View File

@@ -511,16 +511,21 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
outPose= MEM_callocN(sizeof(bPose), "pose");
BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
outPose->iksolver = src->iksolver;
outPose->ikdata = NULL;
outPose->ikparam = MEM_dupallocN(src->ikparam);
// TODO: rename this argument...
if (copycon) {
for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
pchan->constraints= listb;
pchan->path= NULL;
}
/* for now, duplicate Bone Groups too when doing this */
BLI_duplicatelist(&outPose->agroups, &src->agroups);
}
*dst=outPose;
@@ -535,7 +540,7 @@ void init_pose_itasc(bItasc *itasc)
itasc->numiter = 100;
itasc->numstep = 4;
itasc->precision = 0.005f;
itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION|ITASC_SIMULATION;
itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION;
itasc->feedback = 20.f;
itasc->maxvel = 50.f;
itasc->solver = ITASC_SOLVER_SDLS;

View File

@@ -280,17 +280,27 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
if (quat) {
float totfac, q1[4], q2[4];
/* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero
* to more then one index in data which can give divide by zero error */
/*
totfac= data[0]+data[1];
QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
if(totfac>0.000001) QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
else QUATCOPY(q1, p1->quat);
NormalQuat(q1);
totfac= data[2]+data[3];
QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
if(totfac>0.000001) QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
else QUATCOPY(q1, p3->quat);
NormalQuat(q2);
totfac = data[0]+data[1]+data[2]+data[3];
QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
if(totfac>0.000001) QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
else QUATCOPY(quat, q2);
NormalQuat(quat);
*/
// XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases.
QUATCOPY(quat, p1->quat);
}
if(radius)

View File

@@ -187,8 +187,6 @@ AnimData *BKE_copy_animdata (AnimData *adt)
dadt= MEM_dupallocN(adt);
/* make a copy of action - at worst, user has to delete copies... */
// XXX review this... it might not be optimal behaviour yet...
//id_us_plus((ID *)dadt->action);
dadt->action= copy_action(adt->action);
dadt->tmpact= copy_action(adt->tmpact);
@@ -213,7 +211,7 @@ static void make_local_strips(ListBase *strips)
for (strip=strips->first; strip; strip=strip->next) {
if (strip->act) make_local_action(strip->act);
//if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
make_local_strips(&strip->strips);
}
@@ -1467,6 +1465,10 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt, float ct
* Unresolved things:
* - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids or nodal system? but stored where?
* - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
*
* Current Status:
* - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides.
* However, the code fo this is relatively harmless, so is left in the code for now.
*/
/* Evaluation loop for evaluation animation data
@@ -1623,9 +1625,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
* this tagged by Depsgraph on framechange
* this tagged by Depsgraph on framechange. This optimisation means that objects
* linked from other (not-visible) scenes will not need their data calculated.
*/
EVAL_ANIM_IDS(main->object.first, /*ADT_RECALC_ANIM*/0);
EVAL_ANIM_IDS(main->object.first, 0);
/* worlds */
EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM);

View File

@@ -1279,6 +1279,65 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
Mat4MulMat4(delta_mat, pose_mat, imat);
}
/* **************** Rotation Mode Conversions ****************************** */
/* Used for Objects and Pose Channels, since both can have multiple rotation representations */
/* Called from RNA when rotation mode changes
* - the result should be that the rotations given in the provided pointers have had conversions
* applied (as appropriate), such that the rotation of the element hasn't 'visually' changed
*
* - as in SDNA data, quat is used to store quaternions AND axis-angle rotations...
*/
void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode)
{
/* check if any change - if so, need to convert data */
if (newMode > 0) { /* to euler */
if (oldMode == ROT_MODE_AXISANGLE) {
/* axis-angle to euler */
AxisAngleToEulO(&quat[1], quat[0], eul, newMode);
}
else if (oldMode == ROT_MODE_QUAT) {
/* quat to euler */
QuatToEulO(quat, eul, newMode);
}
/* else { no conversion needed } */
}
else if (newMode == ROT_MODE_QUAT) { /* to quat */
if (oldMode == ROT_MODE_AXISANGLE) {
/* axis angle to quat */
float q[4];
/* copy to temp var first, since quats and axis-angle are stored in same place */
QuatCopy(q, quat);
AxisAngleToQuat(q, &quat[1], quat[0]);
}
else if (oldMode > 0) {
/* euler to quat */
EulOToQuat(eul, oldMode, quat);
}
/* else { no conversion needed } */
}
else { /* to axis-angle */
if (oldMode > 0) {
/* euler to axis angle */
EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]);
}
else if (oldMode == ROT_MODE_QUAT) {
/* quat to axis angle */
float q[4];
/* copy to temp var first, since quats and axis-angle are stored in same place */
QuatCopy(q, quat);
QuatToAxisAngle(q, &quat[1], &quat[0]);
}
/* when converting to axis-angle, we need a special exception for the case when there is no axis */
if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
quat[2]= 1.0f;
}
}
}
/* **************** The new & simple (but OK!) armature evaluation ********* */
@@ -1591,7 +1650,7 @@ void chan_calc_mat(bPoseChannel *chan)
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
EulOToMat3(chan->eul, chan->rotmode, rmat);
}
else if (chan->rotmode == PCHAN_ROT_AXISANGLE) {
else if (chan->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
}

View File

@@ -47,6 +47,7 @@
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
#include "BKE_collision.h"
#include "BKE_effect.h"
#include "BKE_boids.h"
#include "BKE_particle.h"
@@ -72,112 +73,91 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
{
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
BoidSettings *boids = bbd->part->boids;
ParticleEffectorCache *ec;
Object *priority_ob = NULL;
BoidParticle *bpa = pa->boid;
EffectedPoint epoint;
ListBase *effectors = bbd->sim->psys->effectors;
EffectorCache *cur, *eff = NULL;
EffectorData efd, cur_efd;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
float priority = 0.0f, len = 0.0f;
int ret = 0;
pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
/* first find out goal/predator with highest priority */
/* if rule->ob specified use it */
if(effectors) for(cur = effectors->first; cur; cur=cur->next) {
Object *eob = cur->ob;
PartDeflect *pd = cur->pd;
if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
PartDeflect *pd = gabr->ob->pd;
float vec_to_part[3];
if(pd && pd->forcefield == PFIELD_BOID) {
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
VecSubf(vec_to_part, pa->prev_state.co, loc);
priority = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
}
if(gabr->ob == eob) {
/* TODO: objects without any effector and effectors with multiple points */
if(get_effector_data(cur, &efd, &epoint, 0)) {
if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
else
priority = 1.0;
priority = 1.0;
priority_ob = gabr->ob;
eff = cur;
}
else for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
if(ec->type & PSYS_EC_EFFECTOR) {
Object *eob = ec->ob;
PartDeflect *pd = eob->pd;
/* skip current object */
if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
continue;
if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
float vec_to_part[3], temp;
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
VecSubf(vec_to_part, pa->prev_state.co, loc);
temp = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
break;
}
}
else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
; /* skip current object */
else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(eff, &efd, &epoint, 0)) {
float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
if(temp == 0.0f)
; /* do nothing */
else if(temp > priority) {
priority = temp;
priority_ob = eob;
len = VecLength(vec_to_part);
eff = cur;
efd = cur_efd;
len = efd.distance;
}
/* choose closest object with same priority */
else if(temp == priority) {
float len2 = VecLength(vec_to_part);
if(len2 < len) {
priority_ob = eob;
len = len2;
}
}
else if(temp == priority && efd.distance < len) {
eff = cur;
efd = cur_efd;
len = efd.distance;
}
}
}
/* then use that effector */
if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
Object *eob = priority_ob;
Object *eob = eff->ob;
PartDeflect *pd = eob->pd;
float vec_to_part[3];
float surface = 0.0f;
float nor[3];
float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f;
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
/* estimate future location of target */
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL);
get_effector_data(eff, &efd, &epoint, 1);
VecSubf(vec_to_part, pa->prev_state.co, loc);
len = Normalize(vec_to_part);
VecMulf(vec, len / (val->max_speed * bbd->timestep));
VecAddf(loc, loc, vec);
VecSubf(vec_to_part, pa->prev_state.co, loc);
}
else {
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
VecSubf(vec_to_part, pa->prev_state.co, loc);
len = VecLength(vec_to_part);
VecMulf(efd.vel, efd.distance / (val->max_speed * bbd->timestep));
VecAddf(efd.loc, efd.loc, efd.vel);
VecSubf(efd.vec_to_point, pa->prev_state.co, efd.loc);
efd.distance = VecLength(efd.vec_to_point);
}
if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) {
if(!bbd->goal_ob || bbd->goal_priority < priority) {
bbd->goal_ob = eob;
VECCOPY(bbd->goal_co, loc);
VECCOPY(bbd->goal_nor, nor);
VECCOPY(bbd->goal_co, efd.loc);
VECCOPY(bbd->goal_nor, efd.nor);
}
}
else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
priority > 2.0f * gabr->fear_factor) {
/* detach from surface and try to fly away from danger */
VECCOPY(vec_to_part, bpa->gravity);
VecMulf(vec_to_part, -1.0f);
VECCOPY(efd.vec_to_point, bpa->gravity);
VecMulf(efd.vec_to_point, -1.0f);
}
VECCOPY(bbd->wanted_co, vec_to_part);
VECCOPY(bbd->wanted_co, efd.vec_to_point);
VecMulf(bbd->wanted_co, mul);
bbd->wanted_speed = val->max_speed * priority;
@@ -188,8 +168,8 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
surface *= pa->size * boids->height;
if(len2 > 0.0f && len - surface < len2) {
len2 = (len - surface)/len2;
if(len2 > 0.0f && efd.distance - surface < len2) {
len2 = (efd.distance - surface)/len2;
bbd->wanted_speed *= pow(len2, boids->landing_smoothness);
}
}
@@ -204,9 +184,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
{
BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule;
KDTreeNearest *ptn = NULL;
ParticleEffectorCache *ec;
ParticleTarget *pt;
BoidParticle *bpa = pa->boid;
ColliderCache *coll;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
float co1[3], vel1[3], co2[3], vel2[3];
float len, t, inp, t_min = 2.0f;
@@ -214,7 +194,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
int ret = 0;
//check deflector objects first
if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS) {
if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) {
ParticleCollision col;
BVHTreeRayHit hit;
float radius = val->personal_space * pa->size, ray_dir[3];
@@ -228,21 +208,17 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
hit.dist = col.ray_len = VecLength(ray_dir);
/* find out closest deflector object */
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
if(ec->type & PSYS_EC_DEFLECT) {
Object *eob = ec->ob;
for(coll = bbd->sim->colliders->first; coll; coll=coll->next) {
/* don't check with current ground object */
if(eob == bpa->ground)
if(coll->ob == bpa->ground)
continue;
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
col.ob_t = eob;
col.ob = coll->ob;
col.md = coll->collmd;
if(col.md && col.md->bvhtree)
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
}
/* then avoid that object */
if(hit.index>=0) {
/* TODO: not totally happy with this part */
@@ -760,21 +736,24 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface );
/* take surface velocity into account */
effector_find_co(bbd->sim->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
closest_point_on_surface(surmd, pa->state.co, x, NULL, v);
VecAddf(x, x, v);
/* get actual position on surface */
effector_find_co(bbd->sim->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL);
return bpa->ground;
}
else {
float zvec[3] = {0.0f, 0.0f, 2000.0f};
ParticleCollision col;
ColliderCache *coll;
BVHTreeRayHit hit;
ParticleEffectorCache *ec;
float radius = 0.0f, t, ray_dir[3];
if(!bbd->sim->colliders)
return NULL;
VECCOPY(col.co1, pa->state.co);
VECCOPY(col.co2, pa->state.co);
VecAddf(col.co1, col.co1, zvec);
@@ -785,24 +764,20 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
hit.dist = col.ray_len = VecLength(ray_dir);
/* find out upmost deflector object */
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
if(ec->type & PSYS_EC_DEFLECT) {
Object *eob = ec->ob;
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
col.ob_t = eob;
for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
col.ob = coll->ob;
col.md = coll->collmd;
if(col.md && col.md->bvhtree)
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
}
/* then use that object */
if(hit.index>=0) {
t = hit.dist/col.ray_len;
VecLerpf(ground_co, col.co1, col.co2, t);
VECCOPY(ground_nor, col.nor);
Normalize(ground_nor);
return col.ob;
return col.hit_ob;
}
else {
/* default to z=0 */
@@ -1068,6 +1043,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
BoidSettings *boids = bbd->part->boids;
BoidParticle *bpa = pa->boid;
BoidValues val;
EffectedPoint epoint;
float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
float dvec[3], bvec[3];
float new_dir[3], new_speed;
@@ -1208,7 +1184,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
}
/* account for effectors */
do_effectors(bbd->sim, p, pa, &pa->state, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
float length = Normalize(force);

View File

@@ -60,6 +60,7 @@
#include "MEM_guardedalloc.h"
#include "gpu_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -176,11 +177,20 @@ static void cdDM_drawVerts(DerivedMesh *dm)
MVert *mv = cddm->mvert;
int i;
if( GPU_buffer_legacy(dm) ) {
glBegin(GL_POINTS);
for(i = 0; i < dm->numVertData; i++, mv++)
glVertex3fv(mv->co);
glEnd();
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
GPU_vertex_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
glDrawArrays(GL_POINTS,0,dm->drawObject->nelements);
}
GPU_buffer_unbind();
}
}
static void cdDM_drawUVEdges(DerivedMesh *dm)
{
@@ -190,6 +200,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
int i;
if(mf) {
if( GPU_buffer_legacy(dm) ) {
glBegin(GL_LINES);
for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
if(!(mf->flag&ME_HIDE)) {
@@ -213,6 +224,42 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
}
glEnd();
}
else {
int prevstart = 0;
int prevdraw = 1;
int draw = 1;
int curpos = 0;
GPU_uvedge_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(i = 0; i < dm->numFaceData; i++, mf++) {
if(mf->flag&ME_LOOSEEDGE) {
draw = 1;
}
else {
draw = 0;
}
if( prevdraw != draw ) {
if( prevdraw > 0 && (curpos-prevstart) > 0) {
glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
}
prevstart = curpos;
}
if( mf->v4 ) {
curpos += 8;
}
else {
curpos += 6;
}
prevdraw = draw;
}
if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
}
}
GPU_buffer_unbind();
}
}
}
static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
@@ -222,6 +269,8 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
MEdge *medge = cddm->medge;
int i;
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
glBegin(GL_LINES);
for(i = 0; i < dm->numEdgeData; i++, medge++) {
if((medge->flag&ME_EDGEDRAW)
@@ -232,6 +281,36 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
}
glEnd();
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int prevstart = 0;
int prevdraw = 1;
int draw = 1;
GPU_edge_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(i = 0; i < dm->numEdgeData; i++, medge++) {
if((medge->flag&ME_EDGEDRAW)
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
draw = 1;
}
else {
draw = 0;
}
if( prevdraw != draw ) {
if( prevdraw > 0 && (i-prevstart) > 0 ) {
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
}
prevstart = i;
}
prevdraw = draw;
}
if( prevdraw > 0 && (i-prevstart) > 0 ) {
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
}
}
GPU_buffer_unbind();
}
}
static void cdDM_drawLooseEdges(DerivedMesh *dm)
{
@@ -240,6 +319,8 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
MEdge *medge = cddm->medge;
int i;
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
glBegin(GL_LINES);
for(i = 0; i < dm->numEdgeData; i++, medge++) {
if(medge->flag&ME_LOOSEEDGE) {
@@ -249,6 +330,35 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
}
glEnd();
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int prevstart = 0;
int prevdraw = 1;
int draw = 1;
GPU_edge_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(i = 0; i < dm->numEdgeData; i++, medge++) {
if(medge->flag&ME_LOOSEEDGE) {
draw = 1;
}
else {
draw = 0;
}
if( prevdraw != draw ) {
if( prevdraw > 0 && (i-prevstart) > 0) {
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
}
prevstart = i;
}
prevdraw = draw;
}
if( prevdraw > 0 && (i-prevstart) > 0 ) {
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
}
}
GPU_buffer_unbind();
}
}
static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
{
@@ -266,6 +376,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a
glVertex3fv(mvert[index].co); \
}
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
glBegin(glmode = GL_QUADS);
for(a = 0; a < dm->numFaceData; a++, mface++) {
int new_glmode, new_matnr, new_shademodel;
@@ -315,9 +427,22 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a
if(nors) nors += 3;
}
glEnd();
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
GPU_vertex_setup( dm );
GPU_normal_setup( dm );
if( !GPU_buffer_legacy(dm) ) {
glShadeModel(GL_SMOOTH);
for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
}
}
GPU_buffer_unbind( );
}
glShadeModel(GL_FLAT);
#undef PASSVERT
glShadeModel(GL_FLAT);
}
static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
@@ -342,6 +467,8 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
if(col1 && col2)
glEnable(GL_CULL_FACE);
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
glShadeModel(GL_SMOOTH);
glBegin(glmode = GL_QUADS);
for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
@@ -378,6 +505,25 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
if(col2) cp2 += 16;
}
glEnd();
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
GPU_color4_upload(dm,cp1);
GPU_vertex_setup(dm);
GPU_color_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
glShadeModel(GL_SMOOTH);
glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
if( useTwoSided ) {
GPU_color4_upload(dm,cp2);
GPU_color_setup(dm);
glCullFace(GL_FRONT);
glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
glCullFace(GL_BACK);
}
}
GPU_buffer_unbind();
}
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
@@ -390,12 +536,18 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mv = cddm->mvert;
MFace *mf = cddm->mface;
MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL);
MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
int startFace = 0, lastFlag = 0xdeadbeef;
MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
if(!mcol)
mcol = dm->getFaceDataArray(dm, CD_MCOL);
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
for(i = 0; i < dm->numFaceData; i++, mf++) {
MVert *mvert;
int flag;
@@ -416,7 +568,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
else { if(nors) nors += 3; continue; }
}
if(flag != 0) { /* if the flag is 0 it means the face is hidden or invisible */
if(flag != 0) {
if (flag==1 && mcol)
cp= (unsigned char*) &mcol[i*4];
@@ -425,7 +577,6 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
glNormal3fv(nors);
}
else {
/* TODO make this better (cache facenormals as layer?) */
float nor[3];
if(mf->v4) {
CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
@@ -470,6 +621,88 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if(nors) nors += 3;
}
} else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
MCol *col = realcol;
if(!col)
col = mcol;
GPU_vertex_setup( dm );
GPU_normal_setup( dm );
GPU_uv_setup( dm );
if( col != 0 ) {
/*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) {
col = 0;
} else if( mcol && dm->drawObject->colType == CD_MCOL ) {
col = 0;
}
if( col != 0 ) {*/
unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
for( i=0; i < dm->getNumFaces(dm); i++ ) {
for( j=0; j < 4; j++ ) {
colors[i*12+j*3] = col[i*4+j].r;
colors[i*12+j*3+1] = col[i*4+j].g;
colors[i*12+j*3+2] = col[i*4+j].b;
}
}
GPU_color3_upload(dm,colors);
MEM_freeN(colors);
if(realcol)
dm->drawObject->colType = CD_TEXTURE_MCOL;
else if(mcol)
dm->drawObject->colType = CD_MCOL;
//}
GPU_color_setup( dm );
}
if( !GPU_buffer_legacy(dm) ) {
glShadeModel( GL_SMOOTH );
for(i = 0; i < dm->drawObject->nelements/3; i++) {
int actualFace = dm->drawObject->faceRemap[i];
int flag = 1;
unsigned char *cp = NULL;
if(drawParams) {
flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr);
}
else {
if(index) {
orig = index[actualFace];
if(drawParamsMapped)
flag = drawParamsMapped(userData, orig);
}
else
if(drawParamsMapped)
flag = drawParamsMapped(userData, actualFace);
}
if( flag != lastFlag ) {
if( startFace < i ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
if (lastFlag==1 && mcol)
GPU_color_switch(1);
else
GPU_color_switch(0);
glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
}
}
lastFlag = flag;
startFace = i;
}
}
if( startFace < dm->drawObject->nelements/3 ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
if (lastFlag==1 && mcol)
GPU_color_switch(1);
else
GPU_color_switch(0);
glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
}
}
}
GPU_buffer_unbind();
glShadeModel( GL_FLAT );
}
}
static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
@@ -486,10 +719,15 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
mc = DM_get_face_data_layer(dm, CD_ID_MCOL);
if(!mc)
mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
if(!mc)
mc = DM_get_face_data_layer(dm, CD_MCOL);
if( GPU_buffer_legacy(dm) ) {
DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
for(i = 0; i < dm->numFaceData; i++, mf++) {
int drawSmooth = (mf->flag & ME_SMOOTH);
@@ -515,7 +753,6 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
glNormal3fv(nors);
}
else {
/* TODO make this better (cache facenormals as layer?) */
float nor[3];
if(mf->v4) {
CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
@@ -561,6 +798,54 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
if (nors) nors += 3;
}
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int state = 1;
int prevstate = 1;
int prevstart = 0;
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if( useColors && mc )
GPU_color_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
glShadeModel(GL_SMOOTH);
for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
int actualFace = dm->drawObject->faceRemap[i];
int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
int dontdraw = 0;
if(index) {
orig = index[actualFace];
if(setDrawOptions && orig == ORIGINDEX_NONE)
dontdraw = 1;
}
else
orig = i;
if( dontdraw ) {
state = 0;
}
else {
if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
state = 1;
}
else {
state = 0;
}
}
if( prevstate != state && prevstate == 1 ) {
if( i-prevstart > 0 ) {
glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
}
prevstart = i;
}
prevstate = state;
}
if(state==1) {
glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
}
glShadeModel(GL_FLAT);
}
GPU_buffer_unbind();
}
}
static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
{
@@ -586,9 +871,12 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
transp = GPU_get_material_blend_mode();
orig_transp = transp;
glShadeModel(GL_SMOOTH);
if( GPU_buffer_legacy(dm) || setDrawOptions != 0 ) {
DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
memset(&attribs, 0, sizeof(attribs));
glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
for(a = 0; a < dm->numFaceData; a++, mface++) {
@@ -686,6 +974,206 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
#undef PASSVERT
}
glEnd();
}
else {
GPUBuffer *buffer = 0;
char *varray = 0;
int numdata = 0, elementsize = 0, offset;
int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
GPUAttrib datatypes[32];
memset(&attribs, 0, sizeof(attribs));
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(a = 0; a < dm->numFaceData; a++, mface++) {
new_matnr = mface->mat_nr + 1;
if(new_matnr != matnr ) {
numfaces = curface - start;
if( numfaces > 0 ) {
if( prevdraw ) {
GPU_buffer_unlock(buffer);
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
GPU_buffer_free(buffer,0);
}
}
start = curface;
prevdraw = dodraw;
dodraw = setMaterial(matnr = new_matnr, &gattribs);
if(dodraw) {
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
if(attribs.totorco) {
datatypes[numdata].index = attribs.orco.glIndex;
datatypes[numdata].size = 3;
datatypes[numdata].type = GL_FLOAT;
numdata++;
}
for(b = 0; b < attribs.tottface; b++) {
datatypes[numdata].index = attribs.tface[b].glIndex;
datatypes[numdata].size = 2;
datatypes[numdata].type = GL_FLOAT;
numdata++;
}
for(b = 0; b < attribs.totmcol; b++) {
datatypes[numdata].index = attribs.mcol[b].glIndex;
datatypes[numdata].size = 4;
datatypes[numdata].type = GL_UNSIGNED_BYTE;
numdata++;
}
if(attribs.tottang) {
datatypes[numdata].index = attribs.tang.glIndex;
datatypes[numdata].size = 3;
datatypes[numdata].type = GL_FLOAT;
numdata++;
}
if( numdata != 0 ) {
elementsize = GPU_attrib_element_size( datatypes, numdata );
buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, 0 );
if( buffer == 0 ) {
GPU_buffer_unbind();
dm->drawObject->legacy = 1;
return;
}
varray = GPU_buffer_lock_stream(buffer);
if( varray == 0 ) {
GPU_buffer_unbind();
GPU_buffer_free(buffer, 0);
dm->drawObject->legacy = 1;
return;
}
}
}
}
if(!dodraw) {
continue;
}
if(tf) {
new_transp = tf[a].transp;
if(new_transp != transp) {
numfaces = curface - start;
if( numfaces > 0 ) {
if( dodraw ) {
if( numdata != 0 ) {
GPU_buffer_unlock(buffer);
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
}
glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
if( numdata != 0 ) {
varray = GPU_buffer_lock_stream(buffer);
}
}
}
start = curface;
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
GPU_set_material_blend_mode(orig_transp);
else
GPU_set_material_blend_mode(new_transp);
transp = new_transp;
}
}
if( numdata != 0 ) {
offset = 0;
if(attribs.totorco) {
VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
offset += sizeof(float)*3;
}
for(b = 0; b < attribs.tottface; b++) {
MTFace *tf = &attribs.tface[b].array[a];
VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
offset += sizeof(float)*2;
}
for(b = 0; b < attribs.totmcol; b++) {
MCol *cp = &attribs.mcol[b].array[a*4 + 0];
GLubyte col[4];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
cp = &attribs.mcol[b].array[a*4 + 1];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
cp = &attribs.mcol[b].array[a*4 + 2];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
offset += sizeof(unsigned char)*4;
}
if(attribs.tottang) {
float *tang = attribs.tang.array[a*4 + 0];
VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
tang = attribs.tang.array[a*4 + 1];
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
tang = attribs.tang.array[a*4 + 2];
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
offset += sizeof(float)*3;
}
}
curface++;
if(mface->v4) {
if( numdata != 0 ) {
offset = 0;
if(attribs.totorco) {
VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
offset += sizeof(float)*3;
}
for(b = 0; b < attribs.tottface; b++) {
MTFace *tf = &attribs.tface[b].array[a];
VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
offset += sizeof(float)*2;
}
for(b = 0; b < attribs.totmcol; b++) {
MCol *cp = &attribs.mcol[b].array[a*4 + 2];
GLubyte col[4];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
cp = &attribs.mcol[b].array[a*4 + 3];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
cp = &attribs.mcol[b].array[a*4 + 0];
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
offset += sizeof(unsigned char)*4;
}
if(attribs.tottang) {
float *tang = attribs.tang.array[a*4 + 2];
VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
tang = attribs.tang.array[a*4 + 3];
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
tang = attribs.tang.array[a*4 + 0];
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
offset += sizeof(float)*3;
}
}
curface++;
}
}
numfaces = curface - start;
if( numfaces > 0 ) {
if( dodraw ) {
if( numdata != 0 ) {
GPU_buffer_unlock(buffer);
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
}
glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
}
}
GPU_buffer_unbind();
}
GPU_buffer_free( buffer, 0 );
}
glShadeModel(GL_FLAT);
}

View File

@@ -153,6 +153,9 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->defgoal = 0.0f;
clmd->sim_parms->goalspring = 1.0f;
clmd->sim_parms->goalfrict = 0.0f;
if(!clmd->sim_parms->effector_weights)
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
}
static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
@@ -403,6 +406,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
Mat4MulVecfl(ob->obmat, verts->xconst);
}
effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights);
tstart();
/* call the solver. */
@@ -411,6 +416,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
tend();
pdEndEffectors(&effectors);
// printf ( "%f\n", ( float ) tval() );
return ret;

View File

@@ -45,9 +45,9 @@
#include "BKE_modifier.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
#ifdef USE_BULLET
#include "Bullet-C-Api.h"
#endif
#include "BLI_kdopbvh.h"
#include "BKE_collision.h"
@@ -1392,6 +1392,97 @@ Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj)
return objs;
}
ListBase *get_collider_cache(Scene *scene, Object *self)
{
Base *base=NULL;
ListBase *objs = NULL;
Object *coll_ob = NULL;
CollisionModifierData *collmd = NULL;
ColliderCache *col;
// check all collision objects
for ( base = scene->base.first; base; base = base->next )
{
/*Only proceed for mesh object in same layer */
if(base->object->type!=OB_MESH)
continue;
if(self && (base->lay & self->lay)==0)
continue;
coll_ob = base->object;
if(coll_ob == self)
continue;
if(coll_ob->pd && coll_ob->pd->deflect)
{
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
}
else
collmd = NULL;
if ( collmd )
{
if(objs == NULL)
objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
col->ob = coll_ob;
col->collmd = collmd;
/* make sure collider is properly set up */
collision_move_object(collmd, 1.0, 0.0);
BLI_addtail(objs, col);
}
else if ( coll_ob->dup_group )
{
GroupObject *go;
Group *group = coll_ob->dup_group;
for ( go= group->gobject.first; go; go= go->next )
{
coll_ob = go->ob;
collmd = NULL;
if(coll_ob == self)
continue;
if(coll_ob->pd && coll_ob->pd->deflect)
{
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
}
else
collmd = NULL;
if ( !collmd )
continue;
if( !collmd->bvhtree)
continue;
if(objs == NULL)
objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
col->ob = coll_ob;
col->collmd = collmd;
/* make sure collider is properly set up */
collision_move_object(collmd, 1.0, 0.0);
BLI_addtail(objs, col);
}
}
}
return objs;
}
void free_collider_cache(ListBase **colliders)
{
if(*colliders) {
BLI_freelistN(*colliders);
MEM_freeN(*colliders);
*colliders = NULL;
}
}
static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;

View File

@@ -692,9 +692,11 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
}\
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \
ct->type = CONSTRAINT_OBTYPE_VERT; \
ct->rotOrder = EULER_ORDER_DEFAULT; \
} \
else {\
ct->type = CONSTRAINT_OBTYPE_OBJECT; \
ct->rotOrder= ct->tar->rotmode; \
} \
} \
\

View File

@@ -726,6 +726,10 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL},
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {

View File

@@ -521,8 +521,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* softbody collision */
if((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE))
if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob))
dag_add_collision_field_relation(dag, scene, ob, node);
if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob) || ob->particlesystem.first)
dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */
if (ob->type==OB_MBALL) {
Object *mom= find_basis_mball(scene, ob);
@@ -554,14 +554,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
psys= ob->particlesystem.first;
if(psys) {
ParticleEffectorCache *nec;
GroupObject *go;
for(; psys; psys=psys->next) {
BoidRule *rule = NULL;
BoidState *state = NULL;
ParticleSimulationData sim = {scene, ob, psys, NULL};
ParticleSettings *part= psys->part;
ListBase *effectors = NULL;
EffectorCache *eff;
dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
@@ -593,32 +593,16 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
psys_update_effectors(&sim, 0.0, 0);
effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
for(nec= psys->effectors.first; nec; nec= nec->next) {
Object *ob1= nec->ob;
if(nec->type & PSYS_EC_EFFECTOR) {
node2 = dag_get_node(dag, ob1);
if(ob1->pd->forcefield==PFIELD_GUIDE)
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
if(eff->psys) {
node2 = dag_get_node(dag, eff->ob);
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field");
else
dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Particle Field");
}
else if(nec->type & PSYS_EC_DEFLECT) {
node2 = dag_get_node(dag, ob1);
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Collision");
}
else if(nec->type & PSYS_EC_PARTICLE) {
node2 = dag_get_node(dag, ob1);
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Field");
}
if(nec->type & PSYS_EC_REACTOR) {
node2 = dag_get_node(dag, ob1);
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Reactor");
}
}
pdEndEffectors(&effectors);
if(part->boids) {
for(state = part->boids->states.first; state; state=state->next) {
@@ -1607,6 +1591,21 @@ void graph_print_adj_list(void)
/* ************************ API *********************** */
/* mechanism to allow editors to be informed of depsgraph updates,
to do their own updates based on changes... */
static void (*EditorsUpdateCb)(Main *bmain, ID *id)= NULL;
void DAG_editors_update_cb(void (*func)(Main *bmain, ID *id))
{
EditorsUpdateCb= func;
}
static void dag_editors_update(Main *bmain, ID *id)
{
if(EditorsUpdateCb)
EditorsUpdateCb(bmain, id);
}
/* groups with objects in this scene need to be put in the right order as well */
static void scene_sort_groups(Scene *sce)
{
@@ -2202,7 +2201,7 @@ void DAG_id_flush_update(ID *id, short flag)
/* set flags & pointcache for object */
if(GS(id->name) == ID_OB) {
ob= (Object*)id;
ob->recalc |= flag;
ob->recalc |= (flag & OB_RECALC);
BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
if(flag & OB_RECALC_DATA) {
@@ -2239,6 +2238,23 @@ void DAG_id_flush_update(ID *id, short flag)
}
}
}
/* set flags based on particle settings */
if(idtype == ID_PA) {
ParticleSystem *psys;
for(obt=bmain->object.first; obt; obt= obt->id.next) {
for(psys=obt->particlesystem.first; psys; psys=psys->next) {
if(&psys->part->id == id) {
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
obt->recalc |= (flag & OB_RECALC);
psys->recalc |= (flag & PSYS_RECALC);
}
}
}
}
/* update editors */
dag_editors_update(bmain, id);
}
/* flush to other objects that depend on this one */

File diff suppressed because it is too large Load Diff

View File

@@ -1564,15 +1564,22 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
return rpass;
}
RenderResult *BKE_image_get_renderresult(struct Scene *scene, Image *ima)
RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
{
if(ima->rr)
return ima->rr;
if(ima->type==IMA_TYPE_R_RESULT)
return RE_GetResult(RE_GetRender(scene->id.name));
else if(ima->type==IMA_TYPE_R_RESULT)
return RE_AcquireResultRead(RE_GetRender(scene->id.name));
return NULL;
}
void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
{
if(ima->rr);
else if(ima->type==IMA_TYPE_R_RESULT)
RE_ReleaseResult(RE_GetRender(scene->id.name));
}
/* after imbuf load, openexr type can return with a exrhandle open */
/* in that case we have to build a render-result */
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
@@ -1873,16 +1880,25 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
/* showing RGBA result itself (from compo/sequence) or
like exr, using layers etc */
/* always returns a single ibuf, also during render progress */
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_r)
{
Render *re= NULL;
RenderResult *rr= NULL;
/* if we the caller is not going to release the lock, don't give the image */
if(!lock_r)
return NULL;
if(iuser && iuser->scene) {
re= RE_GetRender(iuser->scene->id.name);
rr= RE_GetResult(re);
rr= RE_AcquireResultRead(re);
/* release is done in BKE_image_release_ibuf using lock_r */
*lock_r= re;
}
if(rr==NULL) return NULL;
if(rr==NULL)
return NULL;
if(RE_RenderInProgress(re)) {
ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
@@ -1893,6 +1909,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
}
return ibuf;
}
else {
@@ -1907,7 +1924,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
pass= (iuser)? iuser->pass: 0;
/* this gives active layer, composite or seqence result */
RE_GetResultImage(RE_GetRender(iuser->scene->id.name), &rres);
RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres);
rect= (unsigned int *)rres.rect32;
rectf= rres.rectf;
dither= iuser->scene->r.dither_intensity;
@@ -1955,9 +1972,13 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf->flags |= IB_zbuffloat;
ibuf->dither= dither;
RE_ReleaseResultImage(re);
ima->ok= IMA_OK_LOADED;
return ibuf;
}
RE_ReleaseResultImage(re);
}
return NULL;
@@ -2011,8 +2032,9 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
}
/* Checks optional ImageUser and verifies/creates ImBuf. */
/* returns ibuf */
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
/* use this one if you want to get a render result in progress,
* if not, use BKE_image_get_ibuf which doesn't require a release */
ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf= NULL;
float color[] = {0, 0, 0, 1};
@@ -2029,6 +2051,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
* That means, the last two steps must be, 1) add the ibuf to the list and
* 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
if(lock_r)
*lock_r= NULL;
/* quick reject tests */
if(ima==NULL)
return NULL;
@@ -2103,8 +2128,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
}
else if(ima->source == IMA_SRC_VIEWER) {
if(ima->type==IMA_TYPE_R_RESULT) {
/* always verify entirely */
ibuf= image_get_render_result(ima, iuser);
/* always verify entirely, and potentially
returns pointer to release later */
ibuf= image_get_render_result(ima, iuser, lock_r);
}
else if(ima->type==IMA_TYPE_COMPOSITE) {
/* Composite Viewer, all handled in compositor */
@@ -2126,6 +2152,17 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
return ibuf;
}
void BKE_image_release_ibuf(Image *ima, void *lock)
{
/* for getting image during threaded render, need to release */
if(lock)
RE_ReleaseResult(lock);
}
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
{
return BKE_image_acquire_ibuf(ima, iuser, NULL);
}
void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
{

View File

@@ -33,6 +33,7 @@
#include "DNA_cloth_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_force.h"
#include "BKE_effect.h"
#include "BKE_global.h"
@@ -1482,15 +1483,19 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
Cloth *cloth = clmd->clothObject;
int i = 0;
float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
float gravity[3];
float gravity[3] = {0.0f, 0.0f, 0.0f};
float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
MFace *mfaces = cloth->mfaces;
unsigned int numverts = cloth->numverts;
LinkNode *search = cloth->springs;
lfVector *winvec;
EffectedPoint epoint;
VECCOPY(gravity, clmd->sim_parms->gravity);
mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
/* global acceleration (gravitation) */
if(clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
VECCOPY(gravity, clmd->scene->physics_settings.gravity);
mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */
}
/* set dFdX jacobi matrix to zero */
init_bfmatrix(dFdX, ZERO);
@@ -1526,9 +1531,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
// precalculate wind forces
for(i = 0; i < cloth->numverts; i++)
{
float speed[3] = {0.0f, 0.0f,0.0f};
pdDoEffectors(clmd->scene, effectors, lX[i], winvec[i], speed, frame, 0.0f, 0);
pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint);
pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
}
for(i = 0; i < cloth->numfaces; i++)
@@ -1656,9 +1660,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
while(step < tf)
{
// calculate forces
effectors= pdInitEffectors(clmd->scene, ob, NULL);
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M);
if(effectors) pdEndEffectors(effectors);
// calculate new velocity
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
@@ -1741,9 +1743,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
cp_lfvector(id->V, id->Vnew, numverts);
// calculate
effectors= pdInitEffectors(clmd->scene, ob, NULL);
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
if(effectors) pdEndEffectors(effectors);
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
}

View File

@@ -213,17 +213,17 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
*array_index= 2; return "delta_location";
case OB_ROT_X:
*array_index= 0; return "rotation";
*array_index= 0; return "rotation_euler";
case OB_ROT_Y:
*array_index= 1; return "rotation";
*array_index= 1; return "rotation_euler";
case OB_ROT_Z:
*array_index= 2; return "rotation";
*array_index= 2; return "rotation_euler";
case OB_DROT_X:
*array_index= 0; return "delta_rotation";
*array_index= 0; return "delta_rotation_euler";
case OB_DROT_Y:
*array_index= 1; return "delta_rotation";
*array_index= 1; return "delta_rotation_euler";
case OB_DROT_Z:
*array_index= 2; return "delta_rotation";
*array_index= 2; return "delta_rotation_euler";
case OB_SIZE_X:
*array_index= 0; return "scale";
@@ -281,23 +281,23 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
/* result depends on adrcode */
switch (adrcode) {
case AC_QUAT_W:
*array_index= 0; return "rotation";
*array_index= 0; return "rotation_quaternion";
case AC_QUAT_X:
*array_index= 1; return "rotation";
*array_index= 1; return "rotation_quaternion";
case AC_QUAT_Y:
*array_index= 2; return "rotation";
*array_index= 2; return "rotation_quaternion";
case AC_QUAT_Z:
*array_index= 3; return "rotation";
*array_index= 3; return "rotation_quaternion";
case AC_EUL_X:
*array_index= 0; return "euler_rotation";
*array_index= 0; return "rotation_euler";
case AC_EUL_Y:
*array_index= 1; return "euler_rotation";
*array_index= 1; return "rotation_euler";
case AC_EUL_Z:
*array_index= 2; return "euler_rotation";
*array_index= 2; return "rotation_euler";
case -1: /* special case for euler-rotations used by old drivers */
*array_index= 0; return "euler_rotation";
*array_index= 0; return "rotation_euler";
case AC_LOC_X:
*array_index= 0; return "location";
@@ -1047,10 +1047,6 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
}
}
/* free old driver */
MEM_freeN(idriver);
/* return the new one */
return cdriver;
}
@@ -1122,11 +1118,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* allocate memory for a new F-Curve */
fcu= MEM_callocN(sizeof(FCurve), "FCurve");
/* convert driver - will free the old one... */
if (icu->driver) {
/* convert driver */
if (icu->driver)
fcu->driver= idriver_to_cdriver(icu->driver);
icu->driver= NULL;
}
/* copy flags */
if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE;
@@ -1233,10 +1227,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* add new F-Curve to list */
fcurve_add_to_list(groups, list, fcurve, actname);
}
/* free old data of curve now that it's no longer needed for converting any more curves */
if (icu->bezt) MEM_freeN(icu->bezt);
if (icu->bp) MEM_freeN(icu->bezt);
}
else {
/* get rna-path
@@ -1302,9 +1292,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
}
}
}
/* free this data now */
MEM_freeN(icu->bezt);
}
else if (icu->bp) {
/* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
@@ -1325,7 +1312,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
*/
static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase *animgroups, ListBase *anim, ListBase *drivers)
{
IpoCurve *icu, *icn;
IpoCurve *icu;
/* sanity check */
if (ELEM3(NULL, ipo, anim, drivers))
@@ -1347,27 +1334,46 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
}
/* loop over IPO-Curves, freeing as we progress */
for (icu= ipo->curve.first; icu; icu= icn) {
/* get link to next (for later) */
icn= icu->next;
for (icu= ipo->curve.first; icu; icu= icu->next) {
/* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves),
* we figure out the best place to put the channel, then tell the curve-converter to just dump there
*/
if (icu->driver) {
/* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */
if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON))
if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
icu_to_fcurves(NULL, drivers, icu, actname, constname);
else
}
else {
MEM_freeN(icu->driver);
icu->driver= NULL;
}
}
else
icu_to_fcurves(animgroups, anim, icu, actname, constname);
}
/* free this IpoCurve now that it's been converted */
/* if this IPO block doesn't have any users after this one, free... */
ipo->id.us--;
if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) )
{
IpoCurve *icn;
for (icu= ipo->curve.first; icu; icu= icn) {
icn= icu->next;
/* free driver */
if (icu->driver)
MEM_freeN(icu->driver);
/* free old data of curve now that it's no longer needed for converting any more curves */
if (icu->bezt) MEM_freeN(icu->bezt);
if (icu->bp) MEM_freeN(icu->bezt);
/* free this IPO-Curve */
BLI_freelinkN(&ipo->curve, icu);
}
}
}
/* Convert Action-block to new system, separating animation and drivers
* New curves may not be converted directly into the given Action (i.e. for Actions linked

View File

@@ -524,30 +524,13 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
{
Curve *cu= par->data;
float fac, loc[4], dir[3], cent[3], radius;
short upflag, index;
float fac, loc[4], dir[3], new_quat[4], radius;
short /*upflag, */ index;
index= axis-1;
if(index>2)
index -= 3; /* negative */
if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
upflag= OB_POSZ;
cent[0]= 0.0;
cent[1]= co[1];
cent[2]= co[2];
index= 0;
}
else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) {
upflag= OB_POSZ;
cent[0]= co[0];
cent[1]= 0.0;
cent[2]= co[2];
index= 1;
}
else {
upflag= OB_POSY;
cent[0]= co[0];
cent[1]= co[1];
cent[2]= 0.0;
index= 2;
}
/* to be sure, mostly after file load */
if(cu->path==NULL) {
makeDispListCurveTypes(scene, par, 0);
@@ -555,7 +538,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
}
/* options */
if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) {
if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
if(cu->flag & CU_STRETCH)
fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
else
@@ -579,9 +562,10 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
}
#endif // XXX old animation system
if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */
float q[4], mat[3][3], quat[4];
if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
float quat[4], cent[3];
#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt.
if(cd->no_rot_axis) /* set by caller */
dir[cd->no_rot_axis-1]= 0.0f;
@@ -598,17 +582,99 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
q[3]= -fac*dir[2];
QuatMul(quat, q, quat);
}
QuatToMat3(quat, mat);
#endif
if(cu->flag & CU_PATH_RADIUS) {
float tmat[3][3], rmat[3][3];
Mat3Scale(tmat, radius);
Mat3MulMat3(rmat, mat, tmat);
Mat3CpyMat3(mat, rmat);
static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
if(cd->no_rot_axis) { /* set by caller */
/* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then
* changing the axis before calculating the tilt but serves much the same purpose */
float dir_flat[3]={0,0,0}, q[4];
VECCOPY(dir_flat, dir);
dir_flat[cd->no_rot_axis-1]= 0.0f;
Normalize(dir);
Normalize(dir_flat);
RotationBetweenVectorsToQuat(q, dir, dir_flat); /* Could this be done faster? */
QuatMul(new_quat, q, new_quat);
}
/* Logic for 'cent' orientation *
*
* The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
*
* Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
* view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
* Notice X,Y,Z Up all have light colors and each ordered CCW.
*
* Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
* */
switch(axis) {
case MOD_CURVE_POSX:
QuatMul(quat, new_quat, q_y90d);
cent[0]= 0.0;
cent[1]= co[2];
cent[2]= co[1];
break;
case MOD_CURVE_NEGX:
QuatMul(quat, new_quat, q_ny90d);
cent[0]= 0.0;
cent[1]= -co[1];
cent[2]= co[2];
break;
case MOD_CURVE_POSY:
QuatMul(quat, new_quat, q_x90d);
cent[0]= co[2];
cent[1]= 0.0;
cent[2]= -co[0];
break;
case MOD_CURVE_NEGY:
QuatMul(quat, new_quat, q_nx90d);
cent[0]= -co[0];
cent[1]= 0.0;
cent[2]= -co[2];
break;
case MOD_CURVE_POSZ:
QuatMul(quat, new_quat, q_z90d);
cent[0]= co[1];
cent[1]= -co[0];
cent[2]= 0.0;
break;
case MOD_CURVE_NEGZ:
QuatMul(quat, new_quat, q_nz90d);
cent[0]= co[0];
cent[1]= -co[1];
cent[2]= 0.0;
break;
}
/* scale if enabled */
if(cu->flag & CU_PATH_RADIUS)
VecMulf(cent, radius);
/* local rotation */
Mat3MulVecfl(mat, cent);
NormalQuat(quat);
QuatMulVecf(quat, cent);
/* translation */
VECADD(co, cent, loc);

View File

@@ -640,42 +640,15 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
}
/* by spec, animdata is first item after ID */
/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
static void id_copy_animdata(ID *id)
{
switch(GS(id->name)) {
case ID_OB:
((Object *)id)->adt= BKE_copy_animdata(((Object *)id)->adt);
break;
case ID_CU:
((Curve *)id)->adt= BKE_copy_animdata(((Curve *)id)->adt);
break;
case ID_CA:
((Camera *)id)->adt= BKE_copy_animdata(((Camera *)id)->adt);
break;
case ID_KE:
((Key *)id)->adt= BKE_copy_animdata(((Key *)id)->adt);
break;
case ID_LA:
((Lamp *)id)->adt= BKE_copy_animdata(((Lamp *)id)->adt);
break;
case ID_MA:
((Material *)id)->adt= BKE_copy_animdata(((Material *)id)->adt);
break;
case ID_NT:
((bNodeTree *)id)->adt= BKE_copy_animdata(((bNodeTree *)id)->adt);
break;
case ID_SCE:
((Scene *)id)->adt= BKE_copy_animdata(((Scene *)id)->adt);
break;
case ID_TE:
((Tex *)id)->adt= BKE_copy_animdata(((Tex *)id)->adt);
break;
case ID_WO:
((World *)id)->adt= BKE_copy_animdata(((World *)id)->adt);
break;
}
AnimData *adt= BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
iat->adt= BKE_copy_animdata(iat->adt);
}
}
/* used everywhere in blenkernel and text.c */
@@ -706,7 +679,8 @@ void *copy_libblock(void *rt)
idn->flag |= LIB_NEW;
if (id->properties) idn->properties = IDP_CopyProperty(id->properties);
id_copy_animdata(id);
/* the duplicate should get a copy of the animdata */
id_copy_animdata(idn);
return idn;
}

View File

@@ -172,15 +172,15 @@ void init_material(Material *ma)
ma->vol.density = 1.0f;
ma->vol.emission = 0.0f;
ma->vol.absorption = 1.0f;
ma->vol.scattering = 1.0f;
ma->vol.reflection = 1.0f;
ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
ma->vol.density_scale = 1.0f;
ma->vol.depth_cutoff = 0.01f;
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
ma->vol.stepsize = 0.2f;
ma->vol.shade_stepsize = 0.2f;
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
ma->vol.precache_resolution = 50;

View File

@@ -5971,6 +5971,8 @@ static void clothModifier_copyData(ModifierData *md, ModifierData *target)
tclmd->point_cache = NULL;
tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
if(clmd->sim_parms->effector_weights)
tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
tclmd->clothObject = NULL;
@@ -5992,8 +5994,11 @@ static void clothModifier_freeData(ModifierData *md)
cloth_free_modifier_extern (clmd);
if(clmd->sim_parms)
if(clmd->sim_parms) {
if(clmd->sim_parms->effector_weights)
MEM_freeN(clmd->sim_parms->effector_weights);
MEM_freeN(clmd->sim_parms);
}
if(clmd->coll_parms)
MEM_freeN(clmd->coll_parms);

View File

@@ -219,6 +219,9 @@ void copy_nladata (ListBase *dst, ListBase *src)
if ELEM(NULL, dst, src)
return;
/* clear out the destination list first for precautions... */
dst->first= dst->last= NULL;
/* copy each NLA-track, one at a time */
for (nlt= src->first; nlt; nlt= nlt->next) {
/* make a copy, and add the copy to the destination list */

View File

@@ -1953,6 +1953,7 @@ static void composit_end_exec(bNodeTree *ntree, int is_group)
if(ns->data) {
printf("freed leftover buffer from stack\n");
free_compbuf(ns->data);
ns->data= NULL;
}
}
}

View File

@@ -91,6 +91,7 @@
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
#include "BKE_icons.h"
@@ -127,8 +128,8 @@ void clear_workob(Object *workob)
{
memset(workob, 0, sizeof(Object));
workob->size[0]= workob->size[1]= workob->size[2]= 1.0;
workob->size[0]= workob->size[1]= workob->size[2]= 1.0f;
workob->rotmode= ROT_MODE_EUL;
}
void copy_baseflags(struct Scene *scene)
@@ -298,11 +299,8 @@ void free_object(Object *ob)
free_constraints(&ob->constraints);
if(ob->pd){
if(ob->pd->tex)
ob->pd->tex->id.us--;
MEM_freeN(ob->pd);
}
free_partdeflect(ob->pd);
if(ob->soft) sbFree(ob->soft);
if(ob->bsoft) bsbFree(ob->bsoft);
if(ob->gpulamp.first) GPU_lamp_free(ob);
@@ -1039,6 +1037,11 @@ Object *add_object(struct Scene *scene, int type)
ob->lay= scene->lay;
/* objects should default to having Euler XYZ rotations,
* but rotations default to quaternions
*/
ob->rotmode= ROT_MODE_EUL;
base= scene_add_base(scene, ob);
scene_select_base(scene, base);
ob->recalc |= OB_RECALC;
@@ -1064,6 +1067,9 @@ SoftBody *copy_softbody(SoftBody *sb)
sbn->pointcache= BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
if(sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
return sbn;
}
@@ -1124,11 +1130,9 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->pathcache= NULL;
psysn->childcache= NULL;
psysn->edit= NULL;
psysn->effectors.first= psysn->effectors.last= 0;
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
psysn->reactevents.first = psysn->reactevents.last = NULL;
psysn->renderdata = NULL;
psysn->pointcache= BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
@@ -1263,7 +1267,7 @@ Object *copy_object(Object *ob)
/* increase user numbers */
id_us_plus((ID *)obn->data);
id_us_plus((ID *)obn->dup_group);
// FIXME: add this for animdata too...
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
@@ -1273,6 +1277,8 @@ Object *copy_object(Object *ob)
obn->pd= MEM_dupallocN(ob->pd);
if(obn->pd->tex)
id_us_plus(&(obn->pd->tex->id));
if(obn->pd->rng)
obn->pd->rng = MEM_dupallocN(ob->pd->rng);
}
obn->soft= copy_softbody(ob->soft);
obn->bsoft = copy_bulletsoftbody(ob->bsoft);
@@ -1582,12 +1588,34 @@ void object_scale_to_mat3(Object *ob, float mat[][3])
// TODO: this should take rotation orders into account later...
void object_rot_to_mat3(Object *ob, float mat[][3])
{
float vec[3];
float rmat[3][3], dmat[3][3];
vec[0]= ob->rot[0]+ob->drot[0];
vec[1]= ob->rot[1]+ob->drot[1];
vec[2]= ob->rot[2]+ob->drot[2];
EulToMat3(vec, mat);
/* initialise the delta-rotation matrix, which will get (pre)multiplied
* with the rotation matrix to yield the appropriate rotation
*/
Mat3One(dmat);
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
if (ob->rotmode > 0) {
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
EulOToMat3(ob->rot, ob->rotmode, rmat);
EulOToMat3(ob->drot, ob->rotmode, dmat);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat);
AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat);
}
else {
/* quats are normalised before use to eliminate scaling issues */
NormalQuat(ob->quat);
QuatToMat3(ob->quat, rmat);
QuatToMat3(ob->dquat, dmat);
}
/* combine these rotations */
// XXX is this correct? if errors, change the order of multiplication...
Mat3MulMat3(mat, dmat, rmat);
}
void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
@@ -1600,14 +1628,7 @@ void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
object_scale_to_mat3(ob, smat);
/* rot */
/* Quats arnt used yet */
/*if(ob->transflag & OB_QUAT) {
QuatMul(q1, ob->quat, ob->dquat);
QuatToMat3(q1, rmat);
}
else {*/
object_rot_to_mat3(ob, rmat);
/*}*/
Mat3MulMat3(mat, rmat, smat);
}
@@ -1902,31 +1923,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
if(ob==NULL) return;
#if 0 // XXX old animation system
/* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
stime= bsystem_time(scene, ob, ctime, 0.0);
if(stime != ob->ctime) {
ob->ctime= stime;
if(ob->ipo) {
calc_ipo(ob->ipo, stime);
execute_ipo((ID *)ob, ob->ipo);
}
else
do_all_object_actions(scene, ob);
/* do constraint ipos ..., note it needs stime (0 = all ipos) */
do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0);
}
else {
/* but, the drivers have to be done */
if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime);
/* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */
do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1);
}
#endif // XXX old animation system
/* execute drivers only, as animation has already been done */
BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);

View File

@@ -53,7 +53,7 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_kdtree.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
@@ -61,6 +61,7 @@
#include "BKE_boids.h"
#include "BKE_cloth.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_lattice.h"
@@ -96,8 +97,7 @@ int count_particles(ParticleSystem *psys){
int tot=0;
LOOP_SHOWN_PARTICLES {
if(pa->alive == PARS_KILLED);
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
else tot++;
}
@@ -109,8 +109,7 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
int tot=0;
LOOP_SHOWN_PARTICLES {
if(pa->alive == PARS_KILLED);
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
else if(p%totgr==cur) tot++;
}
@@ -302,15 +301,11 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
/************************************************/
void psys_free_settings(ParticleSettings *part)
{
if(part->pd) {
MEM_freeN(part->pd);
part->pd = NULL;
}
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
if(part->pd2) {
MEM_freeN(part->pd2);
part->pd2 = NULL;
}
if(part->effector_weights)
MEM_freeN(part->effector_weights);
boid_free_settings(part->boids);
}
@@ -428,6 +423,7 @@ void psys_free_particles(ParticleSystem *psys)
}
void psys_free_pdd(ParticleSystem *psys)
{
if(psys->pdd) {
if(psys->pdd->cdata)
MEM_freeN(psys->pdd->cdata);
psys->pdd->cdata = NULL;
@@ -444,6 +440,7 @@ void psys_free_pdd(ParticleSystem *psys)
MEM_freeN(psys->pdd->vedata);
psys->pdd->vedata = NULL;
}
}
/* free everything */
void psys_free(Object *ob, ParticleSystem * psys)
{
@@ -466,9 +463,6 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->totchild = 0;
}
if(psys->effectors.first)
psys_end_effectors(psys);
// check if we are last non-visible particle system
for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){
if(tpsys->part)
@@ -493,10 +487,11 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->pointcache = NULL;
BLI_freelistN(&psys->targets);
BLI_freelistN(&psys->reactevents);
BLI_kdtree_free(psys->tree);
pdEndEffectors(&psys->effectors);
if(psys->frand)
MEM_freeN(psys->frand);
@@ -1896,125 +1891,136 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu
VecLerpf(state->co,state->co,par->co,clump);
}
}
int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb)
void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
{
EffectedPoint point;
ParticleKey state;
EffectorData efd;
EffectorCache *eff;
ParticleSystem *psys = sim->psys;
EffectorWeights *weights = sim->psys->part->effector_weights;
GuideEffectorData *data;
PARTICLE_P;
if(!effectors)
return;
LOOP_PARTICLES {
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0);
pd_point_from_particle(sim, pa, &state, &point);
for(eff = effectors->first; eff; eff=eff->next) {
if(eff->pd->forcefield != PFIELD_GUIDE)
continue;
if(!eff->guide_data)
eff->guide_data = MEM_callocN(sizeof(GuideEffectorData)*psys->totpart, "GuideEffectorData");
data = eff->guide_data + p;
VECSUB(efd.vec_to_point, state.co, eff->guide_loc);
VECCOPY(efd.nor, eff->guide_dir);
efd.distance = VecLength(efd.vec_to_point);
VECCOPY(data->vec_to_point, efd.vec_to_point);
data->strength = effector_falloff(eff, &efd, &point, weights);
}
}
}
int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
{
EffectorCache *eff;
PartDeflect *pd;
ParticleEffectorCache *ec;
Object *eob;
Curve *cu;
ParticleKey key, par;
GuideEffectorData *data;
float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0;
float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f};
float veffect[3]={0.0,0.0,0.0}, guidetime;
float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
float guidevec[4], guidedir[3], rot2[4], temp[3];
float guidetime, radius, angle, totstrength = 0.0f;
float vec_to_point[3];
effect[0]=effect[1]=effect[2]=0.0;
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
pd = eff->pd;
if(lb->first){
for(ec = lb->first; ec; ec= ec->next){
eob= ec->ob;
if(ec->type & PSYS_EC_EFFECTOR){
pd=eob->pd;
if(pd->forcefield==PFIELD_GUIDE){
cu = (Curve*)eob->data;
if(pd->forcefield != PFIELD_GUIDE)
continue;
distance=ec->distances[pa_num];
mindist=pd->f_strength;
data = eff->guide_data + index;
VECCOPY(pa_loc, ec->locations+3*pa_num);
VECCOPY(pa_zero,pa_loc);
VECADD(pa_zero,pa_zero,ec->firstloc);
if(data->strength <= 0.0f)
continue;
guidetime = time / (1.0 - pd->free_end);
/* WARNING: bails out with continue here */
if(((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) || guidetime>1.0f) continue;
if(guidetime>1.0f)
continue;
if(guidetime>1.0f) continue;
cu = (Curve*)eff->ob->data;
/* calculate contribution factor for this guide */
f_force=1.0f;
if(distance<=mindist);
else if(pd->flag & PFIELD_USEMAX) {
if(mindist>=pd->maxdist) f_force= 0.0f;
else if(pd->f_power!=0.0f){
f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
f_force = (float)pow(f_force, pd->f_power);
if(pd->flag & PFIELD_GUIDE_PATH_ADD) {
if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0)
return 0;
}
}
else if(pd->f_power!=0.0f){
f_force= 1.0f/(1.0f + distance-mindist);
f_force = (float)pow(f_force, pd->f_power);
else {
if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0)
return 0;
}
if(pd->flag & PFIELD_GUIDE_PATH_ADD)
where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius);
else
where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius);
Mat4MulVecfl(ec->ob->obmat,guidevec);
Mat4Mul3Vecfl(ec->ob->obmat,guidedir);
Mat4MulVecfl(eff->ob->obmat, guidevec);
Mat4Mul3Vecfl(eff->ob->obmat, guidedir);
Normalize(guidedir);
VECCOPY(vec_to_point, data->vec_to_point);
if(guidetime != 0.0){
/* curve direction */
Crossf(temp, ec->firstdir, guidedir);
angle=Inpf(ec->firstdir,guidedir)/(VecLength(ec->firstdir));
Crossf(temp, eff->guide_dir, guidedir);
angle = Inpf(eff->guide_dir, guidedir)/(VecLength(eff->guide_dir));
angle = saacos(angle);
VecRotToQuat(temp, angle, rot2);
QuatMulVecf(rot2,pa_loc);
QuatMulVecf(rot2, vec_to_point);
/* curve tilt */
VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2);
QuatMulVecf(rot2,pa_loc);
//vectoquat(guidedir, pd->kink_axis, (pd->kink_axis+1)%3, q);
//QuatMul(par.rot,rot2,q);
VecRotToQuat(guidedir, guidevec[3] - eff->guide_loc[3], rot2);
QuatMulVecf(rot2, vec_to_point);
}
//else{
// par.rot[0]=1.0f;
// par.rot[1]=par.rot[2]=par.rot[3]=0.0f;
//}
/* curve taper */
if(cu->taperobj)
VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
VecMulf(vec_to_point, calc_taper(eff->scene, cu->taperobj, (int)(data->strength*guidetime*100.0), 100));
else{ /* curve size*/
if(cu->flag & CU_PATH_RADIUS) {
VecMulf(pa_loc, radius);
VecMulf(vec_to_point, radius);
}
}
par.co[0] = par.co[1] = par.co[2] = 0.0f;
VECCOPY(key.co,pa_loc);
VECCOPY(key.co, vec_to_point);
do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0);
do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
VECCOPY(pa_loc,key.co);
VECCOPY(vec_to_point, key.co);
VECADD(pa_loc,pa_loc,guidevec);
VECSUB(pa_loc,pa_loc,pa_zero);
VECADDFAC(effect,effect,pa_loc,f_force);
VECADDFAC(veffect,veffect,guidedir,f_force);
totforce+=f_force;
}
}
VECADD(vec_to_point, vec_to_point, guidevec);
//VECSUB(pa_loc,pa_loc,pa_zero);
VECADDFAC(effect, effect, vec_to_point, data->strength);
VECADDFAC(veffect, veffect, guidedir, data->strength);
totstrength += data->strength;
}
if(totforce!=0.0){
if(totforce>1.0)
VecMulf(effect,1.0f/totforce);
CLAMP(totforce,0.0,1.0);
VECADD(effect,effect,pa_zero);
VecLerpf(state->co,state->co,effect,totforce);
if(totstrength != 0.0){
if(totstrength > 1.0)
VecMulf(effect, 1.0f / totstrength);
CLAMP(totstrength, 0.0, 1.0);
//VECADD(effect,effect,pa_zero);
VecLerpf(state->co, state->co, effect, totstrength);
Normalize(veffect);
VecMulf(veffect, VecLength(state->vel));
VECCOPY(state->vel, veffect);
return 1;
}
}
return 0;
}
static void do_rough(float *loc, float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
@@ -2051,16 +2057,20 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
}
static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
{
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
float force[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
ParticleData *pa;
EffectedPoint epoint;
/* Don't apply effectors for dynamic hair, otherwise the effectors don't get applied twice. */
if(sim->psys->flag & PSYS_HAIR_DYNAMICS)
return;
VECCOPY(eff_key.co,(ca-1)->co);
VECCOPY(eff_key.vel,(ca-1)->vel);
QUATCOPY(eff_key.rot,(ca-1)->rot);
pa= sim->psys->particles+i;
do_effectors(sim, i, pa, &eff_key, rootco, force, vel, dfra, cfra);
pd_point_from_particle(sim, sim->psys->particles+i, &eff_key, &epoint);
pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL);
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps);
@@ -2777,9 +2787,9 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec);
/* apply guide curves to path data */
if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
if(sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT)==0)
/* ca is safe to cast, since only co and vel are used */
do_guide(sim->scene, (ParticleKey*)ca, p, (float)k/(float)steps, &psys->effectors);
do_guides(sim->psys->effectors, (ParticleKey*)ca, p, (float)k/(float)steps);
/* apply lattice */
if(psys->lattice)
@@ -3187,8 +3197,6 @@ void object_remove_particle_system(Scene *scene, Object *ob)
}
static void default_particle_settings(ParticleSettings *part)
{
int i;
part->type= PART_EMITTER;
part->distr= PART_DISTR_JIT;
part->draw_as = PART_DRAW_REND;
@@ -3199,7 +3207,7 @@ static void default_particle_settings(ParticleSettings *part)
part->flag=PART_REACT_MULTIPLE|PART_HAIR_GEOMETRY|PART_EDISTR|PART_TRAND;
part->sta= 1.0;
part->end= 100.0;
part->end= 200.0;
part->lifetime= 50.0;
part->jitfac= 1.0;
part->totpart= 1000;
@@ -3249,10 +3257,6 @@ static void default_particle_settings(ParticleSettings *part)
part->keyed_loops = 1;
for(i=0; i<10; i++)
part->effector_weight[i]=1.0f;
#if 0 // XXX old animation system
part->ipo = NULL;
#endif // XXX old animation system
@@ -3261,6 +3265,9 @@ static void default_particle_settings(ParticleSettings *part)
part->simplify_rate= 1.0f;
part->simplify_transition= 0.1f;
part->simplify_viewport= 0.8;
if(!part->effector_weights)
part->effector_weights = BKE_add_effector_weights(NULL);
}
@@ -3348,24 +3355,6 @@ void make_local_particlesettings(ParticleSettings *part)
}
}
}
void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
{
Base *base = scene->base.first;
ParticleSystem *psys;
int flush;
for(base = scene->base.first; base; base = base->next) {
flush = 0;
for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
if(psys->part == part) {
psys->recalc |= recalc;
flush++;
}
}
if(flush)
DAG_id_flush_update(&base->object->id, OB_RECALC_DATA);
}
}
/************************************************/
/* Textures */
@@ -3421,9 +3410,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
mtex=ma->mtex[m];
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
float def=mtex->def_var;
float var=mtex->varfac;
short blend=mtex->blendtype;
short neg=mtex->pmaptoneg;
if((mtex->texco & TEXCO_UV) && fw) {
if(!get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texco))
@@ -3438,18 +3425,18 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
ptex->time=0.0;
setvars|=MAP_PA_TIME;
}
ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,var,blend,neg & MAP_PA_TIME);
ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,mtex->timefac,blend);
}
if((event & mtex->pmapto) & MAP_PA_LENGTH)
ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
if((event & mtex->pmapto) & MAP_PA_CLUMP)
ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
if((event & mtex->pmapto) & MAP_PA_KINK)
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
if((event & mtex->pmapto) & MAP_PA_ROUGH)
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,var,blend,neg & MAP_PA_ROUGH);
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,mtex->roughfac,blend);
if((event & mtex->pmapto) & MAP_PA_DENS)
ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3473,10 +3460,8 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
if(ma) for(m=0; m<MAX_MTEX; m++){
mtex=ma->mtex[m];
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
float var=mtex->varfac;
float def=mtex->def_var;
short blend=mtex->blendtype;
short neg=mtex->pmaptoneg;
if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
@@ -3493,29 +3478,31 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
if((event & mtex->pmapto) & MAP_PA_TIME){
/* the first time has to set the base value for time regardless of blend mode */
if((setvars&MAP_PA_TIME)==0){
ptex->time *= 1.0f - var;
ptex->time += var * ((neg & MAP_PA_TIME)? 1.0f - value : value);
int flip= (mtex->timefac < 0.0f);
float timefac= fabsf(mtex->timefac);
ptex->time *= 1.0f - timefac;
ptex->time += timefac * ((flip)? 1.0f - value : value);
setvars |= MAP_PA_TIME;
}
else
ptex->time= texture_value_blend(def,ptex->time,value,var,blend,neg & MAP_PA_TIME);
ptex->time= texture_value_blend(def,ptex->time,value,mtex->timefac,blend);
}
if((event & mtex->pmapto) & MAP_PA_LIFE)
ptex->life= texture_value_blend(def,ptex->life,value,var,blend,neg & MAP_PA_LIFE);
ptex->life= texture_value_blend(def,ptex->life,value,mtex->lifefac,blend);
if((event & mtex->pmapto) & MAP_PA_DENS)
ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
if((event & mtex->pmapto) & MAP_PA_SIZE)
ptex->size= texture_value_blend(def,ptex->size,value,var,blend,neg & MAP_PA_SIZE);
ptex->size= texture_value_blend(def,ptex->size,value,mtex->sizefac,blend);
if((event & mtex->pmapto) & MAP_PA_IVEL)
ptex->ivel= texture_value_blend(def,ptex->ivel,value,var,blend,neg & MAP_PA_IVEL);
ptex->ivel= texture_value_blend(def,ptex->ivel,value,mtex->ivelfac,blend);
if((event & mtex->pmapto) & MAP_PA_PVEL)
texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,var,blend);
texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,mtex->pvelfac,blend);
if((event & mtex->pmapto) & MAP_PA_LENGTH)
ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
if((event & mtex->pmapto) & MAP_PA_CLUMP)
ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
if((event & mtex->pmapto) & MAP_PA_KINK)
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_CLUMP);
ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3646,7 +3633,7 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte
if(part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
guided = do_guide(sim->scene, (ParticleKey*)state, cpa->parent, t, &(sim->psys->effectors));
guided = do_guides(sim->psys->effectors, (ParticleKey*)state, cpa->parent, t);
if(guided==0){
if(part->kink)
@@ -3716,8 +3703,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
Mat4MulVecfl(hairmat, state->co);
Mat4Mul3Vecfl(hairmat, state->vel);
if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
do_guide(sim->scene, state, p, state->time, &psys->effectors);
if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) {
do_guides(sim->psys->effectors, state, p, state->time);
/* TODO: proper velocity handling */
}
@@ -3905,8 +3892,6 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
}
if(pa) {
if(pa->alive == PARS_KILLED) return 0;
if(!always)
if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))

View File

@@ -58,7 +58,7 @@
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BKE_anim.h"
@@ -132,9 +132,6 @@ void psys_reset(ParticleSystem *psys, int mode)
psys->totkeyed= 0;
psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
if(psys->reactevents.first)
BLI_freelistN(&psys->reactevents);
if(psys->edit && psys->free_edit) {
psys->free_edit(psys->edit);
psys->edit = NULL;
@@ -1796,8 +1793,9 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* and gravity in r_ve */
bpa->gravity[0] = bpa->gravity[1] = 0.0f;
bpa->gravity[2] = -1.0f;
if(part->acc[2]!=0.0f)
bpa->gravity[2] = part->acc[2];
if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
&& sim->scene->physics_settings.gravity[2]!=0.0f)
bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
/* calculate rotation matrix */
Projf(dvec, r_vel, pa->state.ave);
@@ -1936,8 +1934,12 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
pa->dietime = pa->time + pa->lifetime;
if(pa->time >= cfra)
if(pa->time > cfra)
pa->alive = PARS_UNBORN;
else if(pa->dietime <= cfra)
pa->alive = PARS_DEAD;
else
pa->alive = PARS_ALIVE;
pa->state.time = cfra;
}
@@ -2203,556 +2205,37 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
/************************************************/
/* Effectors */
/************************************************/
static void update_particle_tree(ParticleSystem *psys)
void psys_update_particle_tree(ParticleSystem *psys, float cfra)
{
if(psys) {
PARTICLE_P;
if(!psys->tree || psys->tree_frame != psys->cfra) {
if(!psys->tree || psys->tree_frame != cfra) {
BLI_kdtree_free(psys->tree);
psys->tree = BLI_kdtree_new(psys->totpart);
LOOP_SHOWN_PARTICLES {
if(pa->alive == PARS_ALIVE)
if(pa->alive == PARS_ALIVE) {
if(pa->state.time == cfra)
BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
else
BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
}
}
BLI_kdtree_balance(psys->tree);
psys->tree_frame = psys->cfra;
}
}
}
static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
static void psys_update_effectors(ParticleSimulationData *sim)
{
TexResult result[4];
float tex_co[3], strength, mag_vec[3];
int hasrgb;
if(tex==NULL) return;
result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
strength= force_val*falloff;
VECCOPY(tex_co,pa_co);
if(is_2d){
float fac=-Inpf(tex_co,obmat[2]);
VECADDFAC(tex_co,tex_co,obmat[2],fac);
}
if(object){
VecSubf(tex_co,tex_co,obmat[3]);
Mat4Mul3Vecfl(obmat,tex_co);
}
hasrgb = multitex_ext(tex, tex_co, NULL,NULL, 1, result);
if(hasrgb && mode==PFIELD_TEX_RGB){
mag_vec[0]= (0.5f-result->tr)*strength;
mag_vec[1]= (0.5f-result->tg)*strength;
mag_vec[2]= (0.5f-result->tb)*strength;
}
else{
strength/=nabla;
tex_co[0]+= nabla;
multitex_ext(tex, tex_co, NULL,NULL, 1, result+1);
tex_co[0]-= nabla;
tex_co[1]+= nabla;
multitex_ext(tex, tex_co, NULL,NULL, 1, result+2);
tex_co[1]-= nabla;
tex_co[2]+= nabla;
multitex_ext(tex, tex_co, NULL,NULL, 1, result+3);
if(mode==PFIELD_TEX_GRAD || !hasrgb){ /* if we dont have rgb fall back to grad */
mag_vec[0]= (result[0].tin-result[1].tin)*strength;
mag_vec[1]= (result[0].tin-result[2].tin)*strength;
mag_vec[2]= (result[0].tin-result[3].tin)*strength;
}
else{ /*PFIELD_TEX_CURL*/
float dbdy,dgdz,drdz,dbdx,dgdx,drdy;
dbdy= result[2].tb-result[0].tb;
dgdz= result[3].tg-result[0].tg;
drdz= result[3].tr-result[0].tr;
dbdx= result[1].tb-result[0].tb;
dgdx= result[1].tg-result[0].tg;
drdy= result[2].tr-result[0].tr;
mag_vec[0]=(dbdy-dgdz)*strength;
mag_vec[1]=(drdz-dbdx)*strength;
mag_vec[2]=(dgdx-drdy)*strength;
}
}
if(is_2d){
float fac=-Inpf(mag_vec,obmat[2]);
VECADDFAC(mag_vec,mag_vec,obmat[2],fac);
}
VecAddf(field,field,mag_vec);
}
static void add_to_effectors(ParticleSimulationData *sim, ListBase *lb, Object *ob)
{
ParticleEffectorCache *ec;
PartDeflect *pd= ob->pd;
short type=0,i;
if(pd && ob != sim->ob){
if(pd->forcefield == PFIELD_GUIDE) {
if(ob->type==OB_CURVE) {
Curve *cu= ob->data;
if(cu->flag & CU_PATH) {
if(cu->path==NULL || cu->path->data==NULL)
makeDispListCurveTypes(sim->scene, ob, 0);
if(cu->path && cu->path->data) {
type |= PSYS_EC_EFFECTOR;
}
}
}
}
else if(pd->forcefield)
{
type |= PSYS_EC_EFFECTOR;
}
}
if(pd && pd->deflect)
type |= PSYS_EC_DEFLECT;
if(type){
ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
ec->ob= ob;
ec->type=type;
ec->distances=0;
ec->locations=0;
ec->rng = rng_new(1);
rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
BLI_addtail(lb, ec);
}
type=0;
/* add particles as different effectors */
if(ob->particlesystem.first){
ParticleSystem *epsys=ob->particlesystem.first;
ParticleSettings *epart=0;
//Object *tob;
for(i=0; epsys; epsys=epsys->next,i++){
if(!psys_check_enabled(ob, epsys))
continue;
type=0;
if(epsys!=sim->psys || (sim->psys->part->flag & PART_SELF_EFFECT)){
epart=epsys->part;
if((epsys->part->pd && epsys->part->pd->forcefield)
|| (epsys->part->pd2 && epsys->part->pd2->forcefield))
{
type=PSYS_EC_PARTICLE;
}
//if(epart->type==PART_REACTOR) {
// tob=epsys->target_ob;
// if(tob==0)
// tob=ob;
// if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==sim->psys)
// type|=PSYS_EC_REACTOR;
//}
if(type){
ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
ec->ob= ob;
ec->type=type;
ec->psys_nbr=i;
ec->rng = rng_new(1);
rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer())));
BLI_addtail(lb, ec);
}
}
}
}
}
static void psys_init_effectors_recurs(ParticleSimulationData *sim, Object *ob, ListBase *listb, int level)
{
Group *group;
GroupObject *go;
unsigned int layer= sim->ob->lay;
if(level>MAX_DUPLI_RECUR) return;
if(ob->lay & layer) {
if(ob->pd || ob->particlesystem.first)
add_to_effectors(sim, listb, ob);
if(ob->dup_group) {
group= ob->dup_group;
for(go= group->gobject.first; go; go= go->next)
psys_init_effectors_recurs(sim, go->ob, listb, level+1);
}
}
}
static void psys_init_effectors(ParticleSimulationData *sim, Group *group)
{
ListBase *listb= &sim->psys->effectors;
Base *base;
listb->first=listb->last=0;
if(group) {
GroupObject *go;
for(go= group->gobject.first; go; go= go->next)
psys_init_effectors_recurs(sim, go->ob, listb, 0);
}
else {
for(base = sim->scene->base.first; base; base= base->next)
psys_init_effectors_recurs(sim, base->object, listb, 0);
}
}
void psys_end_effectors(ParticleSystem *psys)
{
/* NOTE:
ec->ob is not valid in here anymore! - dg
*/
ParticleEffectorCache *ec = psys->effectors.first;
for(; ec; ec= ec->next){
if(ec->distances)
MEM_freeN(ec->distances);
if(ec->locations)
MEM_freeN(ec->locations);
if(ec->face_minmax)
MEM_freeN(ec->face_minmax);
if(ec->vert_cos)
MEM_freeN(ec->vert_cos);
if(ec->tree)
BLI_kdtree_free(ec->tree);
if(ec->rng)
rng_free(ec->rng);
}
BLI_freelistN(&psys->effectors);
}
/* precalcs effectors and returns 1 if there were any collision object
* so collision checks can be avoided as quickly as possible */
static int precalc_effectors(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ListBase *lb=&psys->effectors;
ParticleEffectorCache *ec;
ParticleSettings *part=psys->part;
PARTICLE_P;
int totpart, collision = 0;
float vec2[3],loc[3],radius,*co=0;
for(ec= lb->first; ec; ec= ec->next) {
PartDeflect *pd= ec->ob->pd;
co = NULL;
if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE
&& part->phystype!=PART_PHYS_BOIDS) {
float vec[4];
where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius);
Mat4MulVecfl(ec->ob->obmat,vec);
Mat4Mul3Vecfl(ec->ob->obmat,vec2);
QUATCOPY(ec->firstloc,vec);
VECCOPY(ec->firstdir,vec2);
/* TODO - use 'radius' to adjust the effector */
totpart=psys->totpart;
if(totpart){
ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
LOOP_PARTICLES {
if(part->from == PART_FROM_PARTICLE) {
VECCOPY(loc, pa->fuv);
}
else
psys_particle_on_emitter(sim->psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
Mat4MulVecfl(sim->ob->obmat,loc);
ec->distances[p]=VecLenf(loc,vec);
VECSUB(loc,loc,vec);
VECCOPY(ec->locations+3*p,loc);
}
}
}
else if(ec->type==PSYS_EC_PARTICLE){
ParticleSimulationData esim = {sim->scene, ec->ob, BLI_findlink(&ec->ob->particlesystem, ec->psys_nbr), NULL};
ParticleSettings *epart = esim.psys->part;
ParticleData *epa;
int p, totepart = esim.psys->totpart;
if(psys->part->phystype==PART_PHYS_BOIDS){
ParticleKey state;
PartDeflect *pd;
pd= epart->pd;
if(pd->forcefield==PFIELD_FORCE && totepart){
KDTree *tree;
tree=BLI_kdtree_new(totepart);
ec->tree=tree;
for(p=0, epa=esim.psys->particles; p<totepart; p++,epa++)
if(epa->alive==PARS_ALIVE && psys_get_particle_state(&esim,p,&state,0))
BLI_kdtree_insert(tree, p, state.co, NULL);
BLI_kdtree_balance(tree);
}
}
}
else if(ec->type==PSYS_EC_DEFLECT) {
CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
if(collmd) {
collision_move_object(collmd, 1.0, 0.0);
collision = 1;
}
}
}
return collision;
}
/* updates particle effectors and returns if any collision objects were found */
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc)
{
psys_end_effectors(sim->psys);
psys_init_effectors(sim, sim->psys->part->eff_group);
return (precalc ? precalc_effectors(sim, cfra) : 0);
}
int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index)
{
SurfaceModifierData *surmd = NULL;
int ret = 0;
if(sur)
surmd = sur;
else if(pd && pd->flag&PFIELD_SURFACE)
{
surmd = (SurfaceModifierData *)modifiers_findByType ( ob, eModifierType_Surface );
}
if(surmd) {
/* closest point in the object surface is an effector */
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist = FLT_MAX;
BLI_bvhtree_find_nearest(surmd->bvhtree->tree, pco, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
if(nearest.index != -1) {
VECCOPY(co, nearest.co);
if(nor) {
VECCOPY(nor, nearest.no);
}
if(vel) {
MFace *mface = CDDM_get_face(surmd->dm, nearest.index);
VECCOPY(vel, surmd->v[mface->v1].co);
VecAddf(vel, vel, surmd->v[mface->v2].co);
VecAddf(vel, vel, surmd->v[mface->v3].co);
if(mface->v4)
VecAddf(vel, vel, surmd->v[mface->v4].co);
VecMulf(vel, mface->v4 ? 0.25f : 0.333f);
}
if(index)
*index = nearest.index;
ret = 1;
}
else {
co[0] = co[1] = co[2] = 0.0f;
if(nor)
nor[0] = nor[1] = nor[2] = 0.0f;
if(vel)
vel[0] = vel[1] = vel[2] = 0.0f;
}
}
else {
/* use center of object for distance calculus */
VECCOPY(co, ob->obmat[3]);
if(nor) {
VECCOPY(nor, ob->obmat[2]);
}
if(vel) {
Object obcopy = *ob;
VECCOPY(vel, ob->obmat[3]);
where_is_object_time(scene, ob, scene->r.cfra - 1.0);
VecSubf(vel, vel, ob->obmat[3]);
*ob = obcopy;
}
}
return ret;
}
/* calculate forces that all effectors apply to a particle*/
void do_effectors(ParticleSimulationData *sim, int pa_no, ParticleData *pa, ParticleKey *state, float *rootco, float *force_field, float *vel,float framestep, float cfra)
{
Object *eob;
ParticleSystem *psys = sim->psys;
ParticleSettings *epart;
ParticleData *epa;
ParticleKey estate;
PartDeflect *pd;
ListBase *lb=&psys->effectors;
ParticleEffectorCache *ec;
float distance, vec_to_part[3], pco[3], co[3];
float falloff, charge = 0.0f, strength;
int p, face_index=-1;
/* check all effector objects for interaction */
if(lb->first){
if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
/* Only the charge of the effected particle is used for
interaction, not fall-offs. If the fall-offs aren't the
same this will be unphysical, but for animation this
could be the wanted behavior. If you want physical
correctness the fall-off should be spherical 2.0 anyways.
*/
charge = psys->part->pd->f_strength;
}
if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){
charge += psys->part->pd2->f_strength;
}
for(ec = lb->first; ec; ec= ec->next){
eob= ec->ob;
if(ec->type & PSYS_EC_EFFECTOR){
pd=eob->pd;
if(psys->part->type!=PART_HAIR && psys->part->integrator)
where_is_object_time(sim->scene, eob, cfra);
if(pd && pd->flag&PFIELD_SURFACE) {
float velocity[3];
/* using velocity corrected location allows for easier sliding over effector surface */
VecCopyf(velocity, state->vel);
VecMulf(velocity, psys_get_timestep(sim));
VecAddf(pco, state->co, velocity);
}
else
VECCOPY(pco, state->co);
effector_find_co(sim->scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index);
VecSubf(vec_to_part, state->co, co);
distance = VecLength(vec_to_part);
falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
if(falloff<=0.0f)
; /* don't do anything */
else if(pd->forcefield==PFIELD_TEXTURE) {
do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla,
pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
strength, falloff, force_field);
} else {
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size);
}
}
if(ec->type & PSYS_EC_PARTICLE){
ParticleSimulationData esim = {sim->scene, eob, BLI_findlink(&eob->particlesystem,ec->psys_nbr), NULL};
int totepart, i;
epart = esim.psys->part;
pd = epart->pd;
totepart = esim.psys->totpart;
if(totepart <= 0)
continue;
if(pd && pd->forcefield==PFIELD_HARMONIC){
/* every particle is mapped to only one harmonic effector particle */
p= pa_no%esim.psys->totpart;
totepart= p+1;
}
else{
p=0;
}
esim.psys->lattice= psys_get_lattice(sim);
for(; p<totepart; p++){
/* particle skips itself as effector */
if(esim.psys == psys && p == pa_no) continue;
epa = esim.psys->particles + p;
estate.time = cfra;
if(psys_get_particle_state(&esim, p, &estate, 0)){
VECSUB(vec_to_part, state->co, estate.co);
distance = VecLength(vec_to_part);
for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
if(pd==NULL || pd->forcefield==0) continue;
falloff = effector_falloff(pd, estate.vel, vec_to_part);
strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
if(falloff<=0.0f)
; /* don't do anything */
else
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size);
}
}
else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
/* first step after key release */
psys_get_particle_state(&esim, p, &estate, 1);
VECADD(vel, vel, estate.vel);
/* TODO: add rotation handling here too */
}
}
if(esim.psys->lattice){
end_latt_deform(esim.psys->lattice);
esim.psys->lattice= NULL;
}
}
}
}
pdEndEffectors(&sim->psys->effectors);
sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
precalc_guides(sim, sim->psys->effectors);
}
/************************************************/
@@ -2763,9 +2246,10 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
{
ParticleSettings *part = sim->psys->part;
ParticleData *pa = sim->psys->particles + p;
EffectedPoint epoint;
ParticleKey states[5], tkey;
float timestep = psys_get_timestep(sim);
float force[3],tvel[3],dx[4][3],dv[4][3];
float force[3],impulse[3],dx[4][3],dv[4][3];
float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra;
int i, steps=1;
@@ -2791,10 +2275,11 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
for(i=0; i<steps; i++){
force[0]=force[1]=force[2]=0.0;
tvel[0]=tvel[1]=tvel[2]=0.0;
impulse[0]=impulse[1]=impulse[2]=0.0;
/* add effectors */
if(part->type != PART_HAIR)
do_effectors(sim, p, pa, states+i, states->co, force, tvel, dfra, fra);
pd_point_from_particle(sim, pa, states+i, &epoint);
if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
/* calculate air-particle interaction */
if(part->dragfac!=0.0f){
@@ -2813,10 +2298,17 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
VecMulf(force,1.0f/pa_mass);
/* add global acceleration (gravitation) */
VECADD(force,force,part->acc);
if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY
/* normal gravity is too strong for hair so it's disabled by default */
&& (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
float gravity[3];
VECCOPY(gravity, sim->scene->physics_settings.gravity);
VecMulf(gravity, part->effector_weights->global_gravity);
VECADD(force,force,gravity);
}
/* calculate next state */
VECADD(states[i].vel,states[i].vel,tvel);
VECADD(states[i].vel,states[i].vel,impulse);
switch(part->integrator){
case PART_INT_EULER:
@@ -2889,6 +2381,8 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
if(part->dampfac!=0.0)
VecMulf(pa->state.vel,1.0f-part->dampfac);
VECCOPY(pa->state.ave, states->ave);
/* finally we do guides */
time=(cfra-pa->time)/pa->lifetime;
CLAMP(time,0.0,1.0);
@@ -2898,7 +2392,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
tkey.time=pa->state.time;
if(part->type != PART_HAIR) {
if(do_guide(sim->scene, &tkey, p, time, &sim->psys->effectors)) {
if(do_guides(sim->psys->effectors, &tkey, p, time)) {
VECCOPY(pa->state.co,tkey.co);
/* guides don't produce valid velocity */
VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
@@ -3129,7 +2623,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
VECCOPY(col->vel,vel);
col->ob = col->ob_t;
col->hit_ob = col->ob;
col->hit_md = col->md;
}
}
}
@@ -3146,7 +2641,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
VECCOPY(col->vel,vel);
col->ob = col->ob_t;
col->hit_ob = col->ob;
col->hit_md = col->md;
}
}
}
@@ -3163,13 +2659,11 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
/* 1. check for all possible deflectors for closest intersection on particle path */
/* 2. if deflection was found kill the particle or calculate new coordinates */
static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
Object *ob = NULL, *skip_ob = NULL;
Object *ground_ob = NULL;
ParticleSettings *part = sim->psys->part;
ListBase *lb=&sim->psys->effectors;
ParticleEffectorCache *ec;
ParticleKey reaction_state;
ParticleCollision col;
ParticleData *pa = sim->psys->particles + p;
ParticleCollision col;
ColliderCache *coll;
BVHTreeRayHit hit;
float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
@@ -3185,11 +2679,11 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
BoidParticle *bpa = pa->boid;
radius = pa->size;
boid_z = pa->state.co[2];
skip_ob = bpa->ground;
ground_ob = bpa->ground;
}
/* 10 iterations to catch multiple deflections */
if(lb->first) while(deflections < max_deflections){
if(sim->colliders) while(deflections < max_deflections){
/* 1. */
VECSUB(ray_dir, col.co2, col.co1);
@@ -3201,32 +2695,25 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
if(hit.dist == 0.0f)
hit.dist = col.ray_len = 0.000001f;
for(ec=lb->first; ec; ec=ec->next){
if(ec->type & PSYS_EC_DEFLECT){
ob= ec->ob;
for(coll = sim->colliders->first; coll; coll=coll->next){
/* for boids: don't check with current ground object */
if(ob==skip_ob)
if(coll->ob == ground_ob)
continue;
/* particles should not collide with emitter at birth */
if(ob==sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
if(coll->ob == sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
continue;
if(part->type!=PART_HAIR)
where_is_object_time(sim->scene, sim->ob, cfra);
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
col.ob_t = ob;
col.ob = coll->ob;
col.md = coll->collmd;
if(col.md && col.md->bvhtree)
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
}
/* 2. */
if(hit.index>=0) {
PartDeflect *pd = col.ob->pd;
PartDeflect *pd = col.hit_ob->pd;
int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
float co[3]; /* point of collision */
float vec[3]; /* movement through collision */
@@ -3253,9 +2740,6 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
/* particle is dead so we don't need to calculate further */
deflections=max_deflections;
/* store for reactors */
copy_particle_key(&reaction_state, &pa->state, 0);
}
else {
float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
@@ -3416,7 +2900,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
skip = 1; /* only hair, keyed and baked stuff can have paths */
else if(part->ren_as != PART_DRAW_PATH)
else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
skip = 1; /* particle visualization must be set as path */
else if(!psys->renderdata) {
if(part->draw_as != PART_DRAW_REND)
@@ -3555,8 +3039,11 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
psys->hair_out_dm->release(psys->hair_out_dm);
psys->clmd->point_cache = psys->pointcache;
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0);
psys->clmd->sim_parms->effector_weights = NULL;
}
static void hair_step(ParticleSimulationData *sim, float cfra)
{
@@ -3586,7 +3073,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
do_hair_dynamics(sim);
psys_update_effectors(sim, cfra, 1);
psys_update_effectors(sim);
psys_update_path_cache(sim, cfra);
@@ -3648,12 +3135,12 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
ParticleSystem *psys = sim->psys;
ParticleSettings *part=psys->part;
KDTree *tree=0;
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
//IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
/* Material *ma=give_current_material(sim->ob, part->omat); */
BoidBrainData bbd;
PARTICLE_P;
float timestep;
int totpart, check_collisions = 0;
int totpart;
/* current time */
float ctime, ipotime; // XXX old animation system
/* frame & time changes */
@@ -3703,15 +3190,6 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
}
else{
pa->loop = 0;
if(cfra <= pa->time)
pa->alive = PARS_UNBORN;
/* without dynamics the state is allways known so no need to kill */
else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)){
if(cfra < pa->dietime)
pa->alive = PARS_ALIVE;
}
else
pa->alive = PARS_KILLED;
}
}
@@ -3721,7 +3199,10 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
else{
BLI_srandom(31415926 + (int)cfra + psys->seed);
psys_update_effectors(sim, cfra, 1);
psys_update_effectors(sim);
if(part->type != PART_HAIR)
sim->colliders = get_collider_cache(sim->scene, NULL);
if(part->phystype==PART_PHYS_BOIDS){
ParticleTarget *pt = psys->targets.first;
@@ -3731,13 +3212,13 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
bbd.dfra = dfra;
bbd.timestep = timestep;
update_particle_tree(psys);
psys_update_particle_tree(psys, cfra);
boids_precalc_rules(part, cfra);
for(; pt; pt=pt->next) {
if(pt->ob)
update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1));
psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
}
}
@@ -3798,7 +3279,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
apply_particle_forces(sim, p, pa_dfra, cfra);
/* deflection */
if(check_collisions)
if(sim->colliders)
deflect_particle(sim, p, pa_dfra, cfra);
/* rotations */
@@ -3812,6 +3293,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
boid_body(&bbd, pa);
/* deflection */
if(sim->colliders)
deflect_particle(sim, p, pa_dfra, cfra);
}
break;
@@ -3837,9 +3319,9 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
//push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
}
}
free_collider_cache(&sim->colliders);
}
if(psys->reactevents.first)
BLI_freelistN(&psys->reactevents);
if(tree)
BLI_kdtree_free(tree);
@@ -3850,7 +3332,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
//IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
/* Material *ma = give_current_material(sim->ob,part->omat); */
PARTICLE_P;
float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
@@ -3860,7 +3342,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
if(part->from!=PART_FROM_PARTICLE)
vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
psys_update_effectors(sim, cfra, 1);
psys_update_effectors(sim);
disp= (float)get_current_display_percentage(psys)/100.0f;
@@ -4195,6 +3677,13 @@ static void system_step(ParticleSimulationData *sim, float cfra)
else if(framenr > endframe) {
framenr= endframe;
}
if(framenr == startframe) {
BKE_ptcache_id_reset(sim->scene, &pid, PTCACHE_RESET_OUTDATED);
cache->simframe= framenr;
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->flag &= ~PTCACHE_REDO_NEEDED;
}
}
/* verify if we need to reallocate */
@@ -4226,7 +3715,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
if(alloc) {
realloc_particles(sim, totpart);
if(usecache && !only_children_changed) {
if(oldtotpart && usecache && !only_children_changed) {
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
}
@@ -4286,7 +3775,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
pa->alive = PARS_ALIVE;
}
}
else if(sim->ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) {
psys_reset(psys, PSYS_RESET_CACHE_MISS);
psys->cfra=cfra;
psys->recalc = 0;
@@ -4383,7 +3872,7 @@ static int hair_needs_recalc(ParticleSystem *psys)
/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSimulationData sim = {scene, ob, psys, NULL};
ParticleSimulationData sim = {scene, ob, psys, NULL, NULL};
float cfra;
/* drawdata is outdated after ANY change */

View File

@@ -292,6 +292,9 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
else
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
if(cfra > pa->time)
cfra1 = MAX2(cfra1, pa->time);
dfra = cfra2 - cfra1;
VecMulf(keys[1].vel, dfra / frs_sec);
@@ -2266,6 +2269,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
}
}
}
BLI_freelistN(&pidlist2);
}
if(bake || cache->flag & PTCACHE_REDO_NEEDED)

View File

@@ -402,6 +402,10 @@ Scene *add_scene(char *name)
sce->toolsettings->proportional_size = 1.0f;
sce->physics_settings.gravity[0] = 0.0f;
sce->physics_settings.gravity[1] = 0.0f;
sce->physics_settings.gravity[2] = -9.81f;
sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
sce->unit.scale_length = 1.0f;

View File

@@ -2067,7 +2067,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(rendering)
BLI_strncpy(sce->id.name+2, scenename, 64);
RE_GetResultImage(re, &rres);
RE_AcquireResultImage(re, &rres);
if(rres.rectf) {
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
@@ -2081,6 +2081,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
}
RE_ReleaseResultImage(re);
BIF_end_render_callbacks();
/* restore */

View File

@@ -126,6 +126,7 @@ struct SmokeModifierData;
// forward declerations
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs);
#define TRI_UVOFFSET (1./4.)
@@ -279,6 +280,26 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
{
// init collision points
SmokeCollSettings *scs = smd->coll;
// copy obmat
Mat4CpyMat4(scs->mat, ob->obmat);
Mat4CpyMat4(scs->mat_old, ob->obmat);
fill_scs_points(ob, dm, scs);
}
if(!smd->coll->bvhtree)
{
smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
}
return 1;
}
return 1;
}
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs)
{
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getFaceArray(dm);
int i = 0, divs = 0;
@@ -287,10 +308,6 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
int newdivs = 0;
int quads = 0, facecounter = 0;
// copy obmat
Mat4CpyMat4(scs->mat, ob->obmat);
Mat4CpyMat4(scs->mat_old, ob->obmat);
// count quads
for(i = 0; i < dm->getNumFaces(dm); i++)
{
@@ -416,16 +433,6 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
MEM_freeN(tridivs);
}
if(!smd->coll->bvhtree)
{
smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
}
return 1;
}
return 1;
}
/*! init triangle divisions */
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len)
{
@@ -832,8 +839,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
size_t i = 0;
size_t index = 0;
int badcell = 0;
if(pa->alive == PARS_KILLED) continue;
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
// VECCOPY(pos, pa->state.co);
@@ -1184,7 +1190,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
// simulate the actual smoke (c++ code in intern/smoke)
// DG: interesting commenting this line + deactivating loading of noise files
if(framenr!=startframe)
{
if(sds->flags & MOD_SMOKE_DISSOLVE)
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
smoke_step(sds->fluid, smd->time);
}
// create shadows before writing cache so we get nice shadows for sstartframe, too
if(get_lamp(scene, light))
@@ -1195,7 +1205,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(sds->wt)
{
if(framenr!=startframe)
{
if(sds->flags & MOD_SMOKE_DISSOLVE)
smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
smoke_turbulence_step(sds->wt, sds->fluid);
}
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
cache_wt->simframe= framenr;

View File

@@ -1550,11 +1550,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
float f,windfactor = 0.25f;
/*see if we have wind*/
if(do_effector) {
EffectedPoint epoint;
float speed[3]={0.0f,0.0f,0.0f};
float pos[3];
VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
pdDoEffectors(scene, do_effector, pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
pd_point_from_soft(scene, pos, vel, -1, &epoint);
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
VecMulf(speed,windfactor);
VecAddf(vel,vel,speed);
}
@@ -1591,12 +1594,11 @@ static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
SoftBody *sb = ob->soft;
ListBase *do_effector = NULL;
do_effector= pdInitEffectors(scene, ob,NULL);
do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
if (sb){
_scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
}
if(do_effector)
pdEndEffectors(do_effector);
pdEndEffectors(&do_effector);
}
static void *exec_scan_for_ext_spring_forces(void *data)
@@ -1614,7 +1616,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
int i, totthread,left,dec;
int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
do_effector= pdInitEffectors(scene, ob,NULL);
do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
/* figure the number of threads while preventing pretty pointless threading overhead */
if(scene->r.mode & R_FIXED_THREADS)
@@ -1662,8 +1664,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
/* clean up */
MEM_freeN(sb_threads);
if(do_effector)
pdEndEffectors(do_effector);
pdEndEffectors(&do_effector);
}
@@ -2226,19 +2227,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* done goal stuff */
/* gravitation */
if (sb){
float gravity = sb->grav * sb_grav_force_scale(ob);
bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
float gravity[3];
VECCOPY(gravity, scene->physics_settings.gravity);
VecMulf(gravity, sb_grav_force_scale(ob)*bp->mass*sb->effector_weights->global_gravity); /* individual mass of node here */
VecAddf(bp->force, bp->force, gravity);
}
/* particle field & vortex */
if(do_effector) {
EffectedPoint epoint;
float kd;
float force[3]= {0.0f, 0.0f, 0.0f};
float speed[3]= {0.0f, 0.0f, 0.0f};
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
/* apply forcefield*/
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
@@ -2341,6 +2345,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
left = totpoint;
dec = totpoint/totthread +1;
for(i=0; i<totthread; i++) {
sb_threads[i].scene = scene;
sb_threads[i].ob = ob;
sb_threads[i].forcetime = forcetime;
sb_threads[i].timenow = timenow;
@@ -2381,7 +2386,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
*/
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bproot;
ListBase *do_effector;
ListBase *do_effector = NULL;
float iks, gravity;
float fieldfactor = -1.0f, windfactor = 0.25;
int do_deflector,do_selfcollision,do_springcollision,do_aero;
@@ -2401,7 +2406,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL);
/* after spring scan because it uses Effoctors too */
do_effector= pdInitEffectors(scene, ob,NULL);
do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights);
if (do_deflector) {
float defforce[3];
@@ -2414,7 +2419,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
/* finish matrix and solve */
if(do_effector) pdEndEffectors(do_effector);
pdEndEffectors(&do_effector);
}
@@ -2443,8 +2448,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
BodyPoint *bp;
BodyPoint *bproot;
BodySpring *bs;
ListBase *do_effector;
float iks, ks, kd, gravity;
ListBase *do_effector = NULL;
float iks, ks, kd, gravity[3] = {0.0f,0.0f,0.0f};
float fieldfactor = -1.0f, windfactor = 0.25f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
@@ -2460,7 +2465,10 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
*/
gravity = sb->grav * sb_grav_force_scale(ob);
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
VECCOPY(gravity, scene->physics_settings.gravity);
VecMulf(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity);
}
/* check conditions for various options */
do_deflector= query_external_colliders(scene, ob);
@@ -2473,7 +2481,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow);
/* after spring scan because it uses Effoctors too */
do_effector= pdInitEffectors(scene, ob,NULL);
do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
if (do_deflector) {
float defforce[3];
@@ -2631,16 +2639,17 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* gravitation */
bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
VECADDFAC(bp->force, bp->force, gravity, bp->mass); /* individual mass of node here */
/* particle field & vortex */
if(do_effector) {
EffectedPoint epoint;
float force[3]= {0.0f, 0.0f, 0.0f};
float speed[3]= {0.0f, 0.0f, 0.0f};
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
/* apply forcefield*/
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
@@ -2819,7 +2828,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* cleanup */
#endif
if(do_effector) pdEndEffectors(do_effector);
pdEndEffectors(&do_effector);
}
}
@@ -3635,6 +3644,9 @@ SoftBody *sbNew(Scene *scene)
sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
if(!sb->effector_weights)
sb->effector_weights = BKE_add_effector_weights(NULL);
return sb;
}
@@ -3644,6 +3656,8 @@ void sbFree(SoftBody *sb)
free_softbody_intern(sb);
BKE_ptcache_free_list(&sb->ptcaches);
sb->pointcache = NULL;
if(sb->effector_weights)
MEM_freeN(sb->effector_weights);
MEM_freeN(sb);
}
@@ -3684,6 +3698,9 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
BodyPoint *bp;
int a;
if(!sb || !sb->bpoint)
return;
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
/* store where goals are now */
VECCOPY(bp->origS, bp->origE);

View File

@@ -559,6 +559,36 @@ void default_mtex(MTex *mtex)
mtex->norfac= 1.0;
mtex->varfac= 1.0;
mtex->dispfac=0.2;
mtex->colspecfac= 1.0f;
mtex->mirrfac= 1.0f;
mtex->alphafac= 1.0f;
mtex->difffac= 1.0f;
mtex->specfac= 1.0f;
mtex->emitfac= 1.0f;
mtex->hardfac= 1.0f;
mtex->raymirrfac= 1.0f;
mtex->translfac= 1.0f;
mtex->ambfac= 1.0f;
mtex->colemitfac= 1.0f;
mtex->colreflfac= 1.0f;
mtex->coltransfac= 1.0f;
mtex->densfac= 1.0f;
mtex->scatterfac= 1.0f;
mtex->reflfac= 1.0f;
mtex->shadowfac= 1.0f;
mtex->zenupfac= 1.0f;
mtex->zendownfac= 1.0f;
mtex->blendfac= 1.0f;
mtex->timefac= 1.0f;
mtex->lengthfac= 1.0f;
mtex->clumpfac= 1.0f;
mtex->kinkfac= 1.0f;
mtex->roughfac= 1.0f;
mtex->padensfac= 1.0f;
mtex->lifefac= 1.0f;
mtex->sizefac= 1.0f;
mtex->ivelfac= 1.0f;
mtex->pvelfac= 1.0f;
mtex->normapspace= MTEX_NSPACE_TANGENT;
}
@@ -984,6 +1014,7 @@ struct VoxelData *BKE_add_voxeldata(void)
vd->interp_type= TEX_VD_LINEAR;
vd->file_format= TEX_VD_SMOKE;
vd->int_multiplier = 1.0;
vd->extend = TEX_CLIP;
vd->object = NULL;
return vd;

View File

@@ -86,15 +86,20 @@ World *add_world(char *name)
wrld= alloc_libblock(&G.main->world, ID_WO, name);
wrld->horb= 0.6f;
wrld->skytype= WO_SKYBLEND;
wrld->horr= 0.25f;
wrld->horg= 0.25f;
wrld->horb= 0.25f;
wrld->zenr= 0.1f;
wrld->zeng= 0.1f;
wrld->zenb= 0.1f;
wrld->skytype= 0;
wrld->stardist= 15.0f;
wrld->starsize= 2.0f;
wrld->exp= 0.0f;
wrld->exposure=wrld->range= 1.0f;
wrld->aodist= 5.0f;
wrld->aodist= 10.0f;
wrld->aosamp= 5;
wrld->aoenergy= 1.0f;
wrld->aobias= 0.05f;

View File

@@ -178,7 +178,7 @@ float power_of_2(float val);
*/
/* Defines for rotation orders
* WARNING: must match the ePchan_RotMode in DNA_action_types.h
* WARNING: must match the eRotationModes in DNA_action_types.h
* order matters - types are saved to file!
*/
typedef enum eEulerRotationOrders {

View File

@@ -31,14 +31,15 @@
#ifndef BLI_THREADS_H
#define BLI_THREADS_H
/* one custom lock available now. can be extended */
#define LOCK_IMAGE 0
#define LOCK_CUSTOM1 1
#include <pthread.h>
/* for tables, button in UI, etc */
#define BLENDER_MAX_THREADS 8
struct ListBase;
/* Threading API */
void BLI_init_threads (struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
int BLI_available_threads(struct ListBase *threadbase);
int BLI_available_thread_index(struct ListBase *threadbase);
@@ -48,18 +49,46 @@ void BLI_remove_thread_index(struct ListBase *threadbase, int index);
void BLI_remove_threads(struct ListBase *threadbase);
void BLI_end_threads (struct ListBase *threadbase);
void BLI_lock_thread (int type);
void BLI_unlock_thread (int type);
/* System Information */
int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */
/* exported by preview render, it has to ensure render buffers are not freed while draw */
void BLI_lock_malloc_thread(void);
void BLI_unlock_malloc_thread(void);
/* Global Mutex Locks
*
* One custom lock available now. can be extended. */
/* ThreadedWorker is a simple tool for dispatching work to a limited number of threads in a transparent
* fashion from the caller's perspective
* */
#define LOCK_IMAGE 0
#define LOCK_PREVIEW 1
#define LOCK_CUSTOM1 2
void BLI_lock_thread(int type);
void BLI_unlock_thread(int type);
/* Mutex Lock */
typedef pthread_mutex_t ThreadMutex;
void BLI_mutex_init(ThreadMutex *mutex);
void BLI_mutex_lock(ThreadMutex *mutex);
void BLI_mutex_unlock(ThreadMutex *mutex);
void BLI_mutex_end(ThreadMutex *mutex);
/* Read/Write Mutex Lock */
#define THREAD_LOCK_READ 1
#define THREAD_LOCK_WRITE 2
typedef pthread_rwlock_t ThreadRWMutex;
void BLI_rw_mutex_init(ThreadRWMutex *mutex);
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
void BLI_rw_mutex_end(ThreadRWMutex *mutex);
/* ThreadedWorker
*
* A simple tool for dispatching work to a limited number of threads
* in a transparent fashion from the caller's perspective. */
struct ThreadedWorker;

View File

@@ -23,8 +23,6 @@
* The Original Code is: all of this file, with exception of below:
*
* Contributor(s): Peter O'Gorman
* The functions osxdlopen() and osxerror()
* are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -102,202 +100,6 @@ void PIL_dynlib_close(PILdynlib *lib) {
free(lib);
}
#else
#ifdef __APPLE__ /* MacOS X */
#include <mach-o/dyld.h>
#include <dlfcn.h>
#include <stdarg.h>
#define ERR_STR_LEN 256
struct PILdynlib {
void *handle;
};
static char *osxerror(int setget, const char *str, ...)
{
static char errstr[ERR_STR_LEN];
static int err_filled = 0;
char *retval;
NSLinkEditErrors ler;
int lerno;
const char *dylderrstr;
const char *file;
va_list arg;
if (setget <= 0)
{
va_start(arg, str);
strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
va_end(arg);
/* We prefer to use the dyld error string if setget is 0 */
if (setget == 0) {
NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
// printf("dyld: %s\n",dylderrstr);
if (dylderrstr && strlen(dylderrstr))
strncpy(errstr,dylderrstr,ERR_STR_LEN);
}
err_filled = 1;
retval = NULL;
}
else
{
if (!err_filled)
retval = NULL;
else
retval = errstr;
err_filled = 0;
}
return retval;
}
static void *osxdlopen(const char *path, int mode)
{
void *module = 0;
NSObjectFileImage ofi = 0;
NSObjectFileImageReturnCode ofirc;
static int (*make_private_module_public) (NSModule module) = 0;
unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
/* If we got no path, the app wants the global namespace, use -1 as the marker
in this case */
if (!path)
return (void *)-1;
/* Create the object file image, works for things linked with the -bundle arg to ld */
ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
switch (ofirc)
{
case NSObjectFileImageSuccess:
/* It was okay, so use NSLinkModule to link in the image */
if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
module = NSLinkModule(ofi, path,flags);
/* Don't forget to destroy the object file image, unless you like leaks */
NSDestroyObjectFileImage(ofi);
/* If the mode was global, then change the module, this avoids
multiply defined symbol errors to first load private then make
global. Silly, isn't it. */
if ((mode & RTLD_GLOBAL))
{
if (!make_private_module_public)
{
_dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
(unsigned long *)&make_private_module_public);
}
make_private_module_public(module);
}
break;
case NSObjectFileImageInappropriateFile:
/* It may have been a dynamic library rather than a bundle, try to load it */
module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
break;
case NSObjectFileImageFailure:
osxerror(0,"Object file setup failure : \"%s\"", path);
return 0;
case NSObjectFileImageArch:
osxerror(0,"No object for this architecture : \"%s\"", path);
return 0;
case NSObjectFileImageFormat:
osxerror(0,"Bad object file format : \"%s\"", path);
return 0;
case NSObjectFileImageAccess:
osxerror(0,"Can't read object file : \"%s\"", path);
return 0;
}
if (!module)
osxerror(0, "Can not open \"%s\"", path);
return module;
}
PILdynlib *PIL_dynlib_open(char *name) {
void *handle= osxdlopen(name, RTLD_LAZY);
if (handle) {
PILdynlib *lib= malloc(sizeof(*lib));
lib->handle= handle;
return lib;
} else {
return NULL;
}
}
void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
{
int sym_len = strlen(symname);
void *value = NULL;
char *malloc_sym = NULL;
NSSymbol *nssym = 0;
malloc_sym = malloc(sym_len + 2);
if (malloc_sym)
{
sprintf(malloc_sym, "_%s", symname);
/* If the lib->handle is -1, if is the app global context */
if (lib->handle == (void *)-1)
{
/* Global context, use NSLookupAndBindSymbol */
if (NSIsSymbolNameDefined(malloc_sym))
{
nssym = NSLookupAndBindSymbol(malloc_sym);
}
}
/* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image
for libraries, and NSLookupSymbolInModule for bundles */
else
{
/* Check for both possible magic numbers depending on x86/ppc byte order */
if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
(((struct mach_header *)lib->handle)->magic == MH_CIGAM))
{
if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym))
{
nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
malloc_sym,
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
}
}
else
{
nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
}
}
if (!nssym)
{
osxerror(0, "symname \"%s\" Not found", symname);
}
value = NSAddressOfSymbol(nssym);
free(malloc_sym);
}
else
{
osxerror(-1, "Unable to allocate memory");
}
return value;
}
char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
{
return osxerror(1, (char *)NULL);
}
void PIL_dynlib_close(PILdynlib *lib)
{
if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
(((struct mach_header *)lib->handle)->magic == MH_CIGAM))
{
osxerror(-1, "Can't remove dynamic libraries on darwin");
}
if (!NSUnLinkModule(lib->handle, 0))
{
osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle));
}
free(lib);
}
#else /* Unix */
#include <dlfcn.h>
@@ -334,4 +136,4 @@ void PIL_dynlib_close(PILdynlib *lib) {
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More