This commit is contained in:
2009-10-06 01:58:22 +00:00
463 changed files with 20385 additions and 10116 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(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_PYTHON)
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LINKFLAGS})
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${LLIBS})
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_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

@@ -164,7 +164,7 @@ CXX = 'cl.exe'
CFLAGS = []
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE2']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast']
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']

View File

@@ -32,14 +32,12 @@ FILE(GLOB SRC
src/BulletCollision/CollisionShapes/*.cpp
src/BulletCollision/NarrowPhaseCollision/*.cpp
src/BulletCollision/Gimpact/*.cpp
src/BulletCollision//CollisionDispatch/*.cpp
src/BulletCollision/CollisionDispatch/*.cpp
src/BulletDynamics/ConstraintSolver/*.cpp
src/BulletDynamics/Vehicle/*.cpp
src/BulletDynamics/Dynamics/*.cpp
src/BulletSoftBody/*.cpp
)
ADD_DEFINITIONS(-D_LIB)
BLENDERLIB(extern_bullet "${SRC}" "${INC}")
#, libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags )

View File

@@ -4,11 +4,11 @@ import os
Import('env')
defs = 'USE_DOUBLES QHULL _LIB'
defs = ''
cflags = []
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
defs += ' WIN32 NDEBUG _WINDOWS _LIB'
defs += ' WIN32 NDEBUG _WINDOWS'
#cflags += ['/MT', '/W3', '/GX', '/O2', '/Op']
cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6', '/O3', '/EHcs']
elif env['OURPLATFORM']=='win32-mingw':

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

@@ -598,6 +598,16 @@ extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle);
extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
GHOST_TWindowState state);
/**
* Sets the window "modified" status, indicating unsaved changes
* @param windowhandle The handle to the window
* @param isUnsavedChanges Unsaved changes or not
* @return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle,
GHOST_TUns8 isUnsavedChanges);
/**
* Sets the order of the window (bottom, top).
* @param windowhandle The handle to the window

View File

@@ -161,6 +161,19 @@ public:
*/
virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
/**
* Sets the window "modified" status, indicating unsaved changes
* @param isUnsavedChanges Unsaved changes or not
* @return Indication of success.
*/
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0;
/**
* Gets the window "modified" status, indicating unsaved changes
* @return True if there are unsaved changes
*/
virtual bool getModifiedState() = 0;
/**
* Sets the order of the window (bottom, top).
* @param order The order of the window.

View File

@@ -116,6 +116,12 @@ typedef enum {
} GHOST_TWindowState;
/** Constants for the answer to the blender exit request */
typedef enum {
GHOST_kExitCancel = 0,
GHOST_kExitNow
} GHOST_TExitRequestResponse;
typedef enum {
GHOST_kWindowOrderTop = 0,
GHOST_kWindowOrderBottom

View File

@@ -629,6 +629,13 @@ GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
}
GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
return window->setModifiedState(isUnsavedChanges);
}
GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
GHOST_TWindowOrder order)

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__
# include "GHOST_SystemCarbon.h"
# 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__
m_system = new GHOST_SystemCarbon ();
# 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);
/**
* Handle User request to quit, from Menu bar Quit, and Cmd+Q
* Display alert panel if changes performed since last save
*/
GHOST_TUns8 handleQuitRequest();
/***************************************************************************************
** 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();
/**
* 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.
*/
GHOST_TSuccess 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.
*/
GHOST_TSuccess 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.
*/
GHOST_TSuccess 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.
*/
GHOST_TSuccess 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
@@ -54,6 +52,8 @@ GHOST_Window::GHOST_Window(
m_cursorShape(GHOST_kStandardCursorDefault),
m_stereoVisual(stereoVisual)
{
m_isUnsavedChanges = false;
m_fullScreen = state == GHOST_kWindowStateFullScreen;
if (m_fullScreen) {
m_fullScreenWidth = width;
@@ -139,3 +139,15 @@ GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUn
}
}
GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges)
{
m_isUnsavedChanges = isUnsavedChanges;
return GHOST_kSuccess;
}
bool GHOST_Window::getModifiedState()
{
return m_isUnsavedChanges;
}

View File

@@ -173,6 +173,19 @@ public:
*/
virtual GHOST_TSuccess setCursorGrab(bool grab);
/**
* Sets the window "modified" status, indicating unsaved changes
* @param isUnsavedChanges Unsaved changes or not
* @return Indication of success.
*/
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
/**
* Gets the window "modified" status, indicating unsaved changes
* @return True if there are unsaved changes
*/
virtual bool getModifiedState();
/**
* Returns the type of drawing context used in this window.
* @return The current type of drawing context.
@@ -262,6 +275,9 @@ protected:
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;
/** Modified state : are there unsaved changes */
bool m_isUnsavedChanges;
/** Stores wether this is a full screen window. */
bool m_fullScreen;

View File

@@ -0,0 +1,315 @@
/**
* $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;
/**
* Sets the window "modified" status, indicating unsaved changes
* @param isUnsavedChanges Unsaved changes or not
* @return Indication of success.
*/
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
/**
* 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,751 @@
/**
* $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_kWindowStateMaximized:
case GHOST_kWindowStateNormal:
default:
::ShowWindow(m_windowRef);
break;
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
{
if (isUnsavedChanges) {
SetWindowModified(m_windowRef, 1);
} else {
SetWindowModified(m_windowRef, 0);
}
return GHOST_Window::setModifiedState(isUnsavedChanges);
}
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

@@ -187,10 +187,21 @@ void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow* window)
}
std::vector<GHOST_IWindow *> &
GHOST_WindowManager::
getWindows(
){
std::vector<GHOST_IWindow *> &GHOST_WindowManager::getWindows()
{
return m_windows;
}
bool GHOST_WindowManager::getAnyModifiedState()
{
bool isAnyModified = false;
std::vector<GHOST_IWindow*>::iterator iter;
for (iter = m_windows.begin(); iter != m_windows.end(); iter++) {
if ((*iter)->getModifiedState())
isAnyModified = true;
}
return isAnyModified;
}

View File

@@ -133,11 +133,13 @@ public:
* this vector. Please do not destroy or add windows use the
* interface above for this,
*/
std::vector<GHOST_IWindow *> & getWindows();
std::vector<GHOST_IWindow *> &
getWindows(
);
/**
* Return true if any windows has a modified status
* @return True if any window has unsaved changes
*/
bool getAnyModifiedState();
protected:
/** The list of windows managed */

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])
@@ -916,11 +917,11 @@ def save_3ds(filename, context):
if not filename.lower().endswith('.3ds'):
filename += '.3ds'
# XXX
# if not BPyMessages.Warning_SaveOver(filename):
# return
# XXX
time1 = time.clock()
# time1= Blender.sys.time()
@@ -992,7 +993,7 @@ def save_3ds(filename, context):
if mat: mat_name = mat.name
else: mat_name = None
# else there alredy set to none
img = uf.image
# img = f.image
if img: img_name = img.name
@@ -1016,7 +1017,7 @@ def save_3ds(filename, context):
if free:
free_derived_objects(ob)
# Make material chunks for all materials used in the meshes:
for mat_and_image in materialDict.values():
object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1]))
@@ -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):
"""
@@ -376,7 +377,7 @@ def write(filename, objects, scene,
# scn = Scene.GetCurrent()
file = open(filename, "w")
# Write Header
version = "2.5"
file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
@@ -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 = []
@@ -53,6 +54,10 @@ class MRenderJob(netrender.model.RenderJob):
self.usage = 0.0
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
@@ -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,17 +545,18 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
frame = job[job_frame]
if frame:
if job_result == DONE:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
f.write(buf)
f.close()
if job.type == netrender.model.JOB_BLENDER:
if job_result == DONE:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
f.write(buf)
f.close()
del buf
elif job_result == ERROR:
# blacklist slave on this job on error
job.blacklist.append(slave.id)
del buf
elif job_result == ERROR:
# blacklist slave on this job on error
job.blacklist.append(slave.id)
self.server.stats("", "Receiving result")

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,37 +99,46 @@ def render_slave(engine, scene):
if not os.path.exists(JOB_PREFIX):
os.mkdir(JOB_PREFIX)
job_path = job.files[0][0] # data in files have format (path, start, end)
main_path, main_file = os.path.split(job_path)
job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
print("Fullpath", job_full_path)
print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
engine.update_stats("", "Render File", main_file, "for job", job.id)
for file_path, start, end in job.files[1:]:
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)]
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)
job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
print("Fullpath", job_full_path)
print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
engine.update_stats("", "Render File", main_file, "for job", job.id)
for file_path, start, end in job.files[1:]:
print("\t", file_path)
testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
# 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
first_frame = job.frames[0].number
# start render
start_t = time.time()
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)
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
f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
conn.request("PUT", "/render", f, headers=headers)
f.close()
response = conn.getresponse()
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

@@ -139,3 +139,20 @@ class bpy_ops_submodule_op(object):
import bpy
bpy.ops = bpy_ops()
# TODO, C macro's cant define settings :|
class MESH_OT_delete_edgeloop(bpy.types.Operator):
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
__idname__ = "mesh.delete_edgeloop"
__label__ = "Export PLY"
def execute(self, context):
bpy.ops.tfm.edge_slide(value=1.0)
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
return ('FINISHED',)
bpy.ops.add(MESH_OT_delete_edgeloop)

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()
@@ -67,6 +67,8 @@ class BONE_PT_transform(BoneButtonsPanel):
col.itemR(pchan, "rotation_euler", text="Rotation")
row.column().itemR(pchan, "scale")
layout.itemR(pchan, "rotation_mode")
class BONE_PT_transform_locks(BoneButtonsPanel):
__label__ = "Transform Locks"
@@ -98,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
@@ -115,7 +117,17 @@ class BONE_PT_bone(BoneButtonsPanel):
pchan = ob.pose.pose_channels[context.bone.name]
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:
@@ -123,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")
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="")
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")
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
pchan = ob.pose.pose_channels[context.bone.name]
arm = context.armature
if not bone:
bone = context.edit_bone
pchan = None
else:
pchan = ob.pose.pose_channels[context.bone.name]
if ob and pchan:
split = layout.split()
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="")
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_deform(BoneButtonsPanel):
__label__ = "Deform"
@@ -285,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

@@ -609,6 +609,23 @@ class VolumeButtonsPanel(bpy.types.Panel):
mat = context.material
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"
@@ -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'])
@@ -647,25 +665,28 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
split = layout.split()
col = split.column()
col.itemR(vol, "scattering_mode", text="")
if vol.scattering_mode == 'SINGLE_SCATTERING':
col.itemR(vol, "lighting_mode", text="")
col = split.column()
if vol.lighting_mode == 'SHADED':
col.itemR(vol, "external_shadows")
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'):
elif vol.lighting_mode in ('MULTIPLE_SCATTERING', 'SHADED_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)
sub.itemR(vol, "ms_diffusion")
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 +714,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,7 +26,7 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
ob = context.object
layout.itemR(ob, "rotation_mode")
row = layout.row()
@@ -43,6 +43,8 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
row.column().itemR(ob, "scale")
layout.itemR(ob, "rotation_mode")
class OBJECT_PT_transform_locks(ObjectButtonsPanel):
__label__ = "Transform Locks"
__default_closed__ = True

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'
@@ -182,17 +121,19 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
row = layout.row()
row.active = part.distribution != 'GRID'
row.itemR(part, "amount")
split = layout.split()
col = split.column(align=True)
col.itemR(part, "start")
col.itemR(part, "end")
if part.type != 'HAIR':
split = layout.split()
col = split.column(align=True)
col.itemR(part, "start")
col.itemR(part, "end")
col = split.column(align=True)
col.itemR(part, "lifetime")
col.itemR(part, "random_lifetime", slider=True)
col = split.column(align=True)
col.itemR(part, "lifetime")
col.itemR(part, "random_lifetime", slider=True)
layout.row().itemL(text="Emit From:")
@@ -244,24 +185,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"
@@ -283,7 +223,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
class PARTICLE_PT_initial(ParticleButtonsPanel):
class PARTICLE_PT_velocity(ParticleButtonsPanel):
__label__ = "Velocity"
def poll(self, context):
@@ -300,48 +240,66 @@ class PARTICLE_PT_initial(ParticleButtonsPanel):
part = psys.settings
layout.enabled = particle_panel_enabled(psys)
layout.row().itemL(text="Direction:")
split = layout.split()
sub = split.column()
sub.itemL(text="Emitter Geometry:")
sub.itemR(part, "normal_factor")
subsub = sub.column(align=True)
subsub.itemR(part, "tangent_factor")
subsub.itemR(part, "tangent_phase", slider=True)
sub = split.column()
sub.itemL(text="Emitter Object")
sub.itemR(part, "object_aligned_factor", text="")
layout.row().itemL(text="Other:")
split = layout.split()
sub = split.column()
if part.emit_from=='PARTICLE':
sub.itemR(part, "particle_factor")
else:
sub.itemR(part, "object_factor", slider=True)
sub = split.column()
sub.itemR(part, "random_factor")
sub.itemR(part, "tangent_factor")
sub.itemR(part, "tangent_phase", slider=True)
sub = split.column()
sub.itemL(text="TODO:")
sub.itemL(text="Object aligned")
sub.itemL(text="direction: X, Y, Z")
#if part.type=='REACTOR':
# sub.itemR(part, "reactor_factor")
# sub.itemR(part, "reaction_shape", slider=True)
if part.type=='REACTOR':
sub.itemR(part, "reactor_factor")
sub.itemR(part, "reaction_shape", slider=True)
class PARTICLE_PT_rotation(ParticleButtonsPanel):
__label__ = "Rotation"
def poll(self, context):
if particle_panel_poll(context):
psys = context.particle_system
return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
else:
sub.itemL(text="")
return False
def draw(self, context):
layout = self.layout
psys = context.particle_system
part = psys.settings
layout.row().itemL(text="Rotation:")
layout.enabled = particle_panel_enabled(psys)
split = layout.split()
split.itemL(text="Initial Rotation:")
split.itemR(part, "rotation_dynamic")
split = layout.split()
sub = split.column()
sub.itemR(part, "rotation_mode", text="Axis")
split = layout.split()
sub = split.column(align=True)
sub.itemR(part, "rotation_mode", text="")
sub.itemR(part, "random_rotation_factor", slider=True, text="Random")
sub = split.column()
sub.itemR(part, "rotation_dynamic")
sub.itemR(part, "random_rotation_factor", slider=True)
sub = split.column()
sub = split.column(align=True)
sub.itemR(part, "phase_factor", slider=True)
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
layout.row().itemL(text="Angular velocity:")
layout.row().itemL(text="Angular Velocity:")
layout.row().itemR(part, "angular_velocity_mode", expand=True)
split = layout.split()
@@ -385,9 +343,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 +405,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 +461,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 +491,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
@@ -671,16 +627,37 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
elif part.ren_as == 'OBJECT':
sub.itemR(part, "dupli_object")
sub.itemR(part, "use_global_dupli")
elif part.ren_as == 'GROUP':
sub.itemR(part, "dupli_group")
split = layout.split()
sub = split.column()
sub.itemR(part, "whole_group")
colsub = sub.column()
colsub.active = part.whole_group == False
colsub.itemR(part, "use_group_count")
sub = split.column()
colsub = sub.column()
colsub.active = part.whole_group == False
colsub.itemR(part, "use_global_dupli")
colsub.itemR(part, "rand_group")
if part.use_group_count and not part.whole_group:
row = layout.row()
row.template_list(part, "dupliweights", part, "active_dupliweight_index")
col = row.column()
subrow = col.row()
subcol = subrow.column(align=True)
subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="")
subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="")
weight = part.active_dupliweight
if weight:
row = layout.row()
row.itemR(weight, "count")
elif part.ren_as == 'BILLBOARD':
sub.itemL(text="Align:")
@@ -857,30 +834,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
psys = context.particle_system
part = psys.settings
part = context.particle_system.settings
layout.itemR(part, "effector_group")
layout.itemR(part, "self_effect")
layout.itemR(part, "eweight_all", slider=True)
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.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)
if part.force_field_1.type != 'NONE':
layout.itemL(text="")
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"
@@ -951,11 +939,13 @@ bpy.types.register(PARTICLE_PT_particles)
bpy.types.register(PARTICLE_PT_hair_dynamics)
bpy.types.register(PARTICLE_PT_cache)
bpy.types.register(PARTICLE_PT_emission)
bpy.types.register(PARTICLE_PT_initial)
bpy.types.register(PARTICLE_PT_velocity)
bpy.types.register(PARTICLE_PT_rotation)
bpy.types.register(PARTICLE_PT_physics)
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:
@@ -165,8 +167,20 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
sub = col.column(align=True)
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,154 @@
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, "force", 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 != 'POINT':
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.itemR(field, "do_absorption")
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,61 +15,55 @@ class PhysicButtonsPanel(bpy.types.Panel):
class PHYSICS_PT_field(PhysicButtonsPanel):
__label__ = "Force Fields"
__default_closed__ = True
def draw(self, context):
layout = self.layout
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")
row = layout.row()
row.itemR(field, "use_max_distance")
sub = row.row()
sub.active = field.use_max_distance
sub.itemR(field, "maximum_distance")
layout.itemS()
elif field.type == 'VORTEX':
split.itemR(field, "strength")
split.itemL()
elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
split.itemR(field, "strength")
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()
@@ -143,21 +126,10 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
sub = col.column()
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 settings:
if coll:
settings = context.object.collision
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):
@@ -222,6 +222,18 @@ 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)
@@ -229,3 +241,4 @@ 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'
@@ -455,7 +463,102 @@ class SCENE_PT_unit(RenderButtonsPanel):
row.active = (unit.system != 'NONE')
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)
@@ -467,3 +570,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

@@ -99,8 +99,13 @@ class TEXTURE_PT_colors(TextureButtonsPanel):
layout.template_color_ramp(tex, "color_ramp", expand=True)
split = layout.split()
split.itemR(tex, "rgb_factor", text="Multiply RGB")
col = split.column()
col.itemL(text="RGB Multiply:")
sub = col.column(align=True)
sub.itemR(tex, "factor_red", text="R")
sub.itemR(tex, "factor_green", text="G")
sub.itemR(tex, "factor_blue", text="B")
col = split.column()
col.itemL(text="Adjust:")
@@ -175,14 +180,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 +251,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 +648,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

@@ -144,6 +144,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'

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

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

View File

@@ -57,6 +57,7 @@ typedef struct BVHTreeFromMesh
/* Vertex array, so that callbacks have instante access to data */
struct MVert *vert;
struct MEdge *edge; /* only used for BVHTreeFromMeshEdges */
struct MFace *face;
/* radius for raycast */
@@ -96,6 +97,8 @@ BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMes
*/
BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
BVHTree* bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
/*
* Frees data allocated by a call to bvhtree_from_mesh_*.
*/
@@ -109,6 +112,7 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data);
//Using local coordinates
#define BVHTREE_FROM_FACES 0
#define BVHTREE_FROM_VERTICES 1
#define BVHTREE_FROM_EDGES 2
typedef LinkNode* BVHCache;

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

@@ -115,5 +115,8 @@ 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;
/* only for particles */
float size, charge;
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;
/* precalculated variables */
float oldloc[3], oldspeed[3];
float scale, time_scale;
float guide_dist;
Object obcopy; /* for restoring transformation data */
} pEffectorCache;
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,34 @@ 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
#define PE_USE_NORMAL_DATA 4
/* 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
@@ -222,6 +201,8 @@ struct Object *psys_get_lattice(struct ParticleSimulationData *sim);
int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
void psys_check_group_weights(struct ParticleSettings *part);
/* free */
void psys_free_settings(struct ParticleSettings *part);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
@@ -244,7 +225,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 +234,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 +254,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 +295,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);
@@ -491,14 +492,55 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
glEnd();
} else {
glBegin(GL_LINES);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(eed->v1->co);
glVertex3fv(eed->v2->co);
}
GPUBuffer *buffer = 0;
float *varray;
if( setDrawOptions == 0 ) {
buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 );
}
glEnd();
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) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(eed->v1->co);
glVertex3fv(eed->v2->co);
}
}
glEnd();
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
@@ -627,8 +669,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
@@ -659,41 +701,135 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
} else {
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(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
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;
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
if( draw != 0 ) {
if(!drawSmooth) {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (!drawSmooth) {
glNormal3fv(efa->n);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
} else {
glNormal3fv(efa->v1->no);
glVertex3fv(efa->v1->co);
glNormal3fv(efa->v2->no);
glVertex3fv(efa->v2->co);
glNormal3fv(efa->v3->no);
glVertex3fv(efa->v3->co);
if(efa->v4) {
glNormal3fv(efa->v4->no);
glVertex3fv(efa->v4->co);
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++;
}
}
}
glEnd();
if (draw==2)
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);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (!drawSmooth) {
glNormal3fv(efa->n);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
} else {
glNormal3fv(efa->v1->no);
glVertex3fv(efa->v1->co);
glNormal3fv(efa->v2->no);
glVertex3fv(efa->v2->co);
glNormal3fv(efa->v3->no);
glVertex3fv(efa->v3->co);
if(efa->v4) {
glNormal3fv(efa->v4->no);
glVertex3fv(efa->v4->co);
}
}
glEnd();
if (draw==2)
glDisable(GL_POLYGON_STIPPLE);
}
}
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}

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)
@@ -766,6 +776,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
GroupObject *go;
Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
DupliObject *dob;
ParticleDupliWeight *dw;
ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)};
ParticleSettings *part;
ParticleData *pa;
@@ -773,7 +784,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
ParticleKey state;
ParticleCacheKey *cache;
float ctime, pa_time, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0;
float (*obmat)[4], (*oldobmat)[4];
int lay, a, b, counter, hair = 0;
int totpart, totchild, totgroup=0, pa_num;
@@ -803,6 +814,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
psys_check_group_weights(part);
/* if we have a hair particle system, use the path cache */
if(part->type == PART_HAIR) {
if(psys->flag & PSYS_HAIR_DONE)
@@ -821,18 +834,37 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
if(part->ren_as==PART_DRAW_GR) {
group_handle_recalc_and_update(scene, par, part->dup_group);
for(go=part->dup_group->gobject.first; go; go=go->next)
totgroup++;
if(part->draw & PART_DRAW_COUNT_GR) {
for(dw=part->dupliweights.first; dw; dw=dw->next)
totgroup += dw->count;
}
else {
for(go=part->dup_group->gobject.first; go; go=go->next)
totgroup++;
}
/* we also copy the actual objects to restore afterwards, since
* where_is_object_time will change the object which breaks transform */
oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list");
go = part->dup_group->gobject.first;
for(a=0; a<totgroup; a++, go=go->next) {
oblist[a] = go->ob;
obcopylist[a] = *go->ob;
if(part->draw & PART_DRAW_COUNT_GR && totgroup) {
dw = part->dupliweights.first;
for(a=0; a<totgroup; dw=dw->next) {
for(b=0; b<dw->count; b++, a++) {
oblist[a] = dw->ob;
obcopylist[a] = *dw->ob;
}
}
}
else {
go = part->dup_group->gobject.first;
for(a=0; a<totgroup; a++, go=go->next) {
oblist[a] = go->ob;
obcopylist[a] = *go->ob;
}
}
}
else {
@@ -926,11 +958,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
else {
/* to give ipos in object correct offset */
where_is_object_time(scene, ob, ctime-pa_time);
VECCOPY(vec, obmat[3]);
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
Mat4CpyMat4(mat, pamat);
Mat4MulMat4(tmat, obmat, mat);
Mat4MulFloat3((float *)tmat, size*scale);
if(part->draw & PART_DRAW_GLOBAL_OB)
VECADD(tmat[3], tmat[3], vec);
if(par_space_mat)
Mat4MulMat4(mat, tmat, par_space_mat);
else

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);
}
@@ -1466,7 +1464,11 @@ 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?
* - 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

@@ -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,89 @@ 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;
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
EffectedPoint epoint;
ListBase *effectors = bbd->sim->psys->effectors;
EffectorCache *cur, *eff = NULL;
EffectorData efd, cur_efd;
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(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
PartDeflect *pd = gabr->ob->pd;
float vec_to_part[3];
if(effectors) for(cur = effectors->first; cur; cur=cur->next) {
Object *eob = cur->ob;
PartDeflect *pd = cur->pd;
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);
if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
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 = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
eff = cur;
}
break;
}
}
else
priority = 1.0;
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);
priority = 1.0;
priority_ob = gabr->ob;
}
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);
if(temp == 0.0f)
; /* do nothing */
else if(temp > priority) {
priority = temp;
priority_ob = eob;
len = VecLength(vec_to_part);
}
/* choose closest object with same priority */
else if(temp == priority) {
float len2 = VecLength(vec_to_part);
if(len2 < len) {
priority_ob = eob;
len = len2;
}
}
if(temp == 0.0f)
; /* do nothing */
else if(temp > priority) {
priority = temp;
eff = cur;
efd = cur_efd;
len = efd.distance;
}
/* choose closest object with same priority */
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 +166,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 +182,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 +192,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,20 +206,16 @@ 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(coll->ob == bpa->ground)
continue;
/* don't check with current ground object */
if(eob == bpa->ground)
continue;
col.ob = coll->ob;
col.md = coll->collmd;
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
col.ob_t = eob;
if(col.md && col.md->bvhtree)
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
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) {
@@ -756,25 +730,28 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
if(bpa->data.mode == eBoidMode_Climbing) {
SurfaceModifierData *surmd = NULL;
float x[3], v[3];
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,16 +762,12 @@ 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;
for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
col.ob = coll->ob;
col.md = coll->collmd;
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
col.ob_t = eob;
if(col.md && col.md->bvhtree)
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
}
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) {
@@ -802,7 +775,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
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 +1041,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;
@@ -1075,9 +1049,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
float wanted_dir[3];
float q[4], mat[3][3]; /* rotation */
float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f};
float force[3] = {0.0f, 0.0f, 0.0f};
float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
int p = pa - bbd->sim->psys->particles;
set_boid_values(&val, boids, pa);
@@ -1208,7 +1181,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

@@ -479,6 +479,32 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r
} while(t2);
}
// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges.
// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
static void mesh_edges_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
{
const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
MVert *vert = data->vert;
MEdge *edge = data->edge + index;
float nearest_tmp[3], dist;
float *t0, *t1;
t0 = vert[ edge->v1 ].co;
t1 = vert[ edge->v2 ].co;
PclosestVL3Dfl(nearest_tmp, co, t0, t1);
dist = VecLenf(nearest_tmp, co);
if(dist < nearest->dist)
{
nearest->index = index;
nearest->dist = dist;
VECCOPY(nearest->co, nearest_tmp);
VecSubf(nearest->no, t0, t1);
Normalize(nearest->no);
}
}
/*
* BVH builders
*/
@@ -605,6 +631,68 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float
}
// Builds a bvh tree.. where nodes are the faces of the given mesh.
BVHTree* bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
{
BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_EDGES);
//Not in cache
if(tree == NULL)
{
int i;
int numEdges= mesh->getNumEdges(mesh);
MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
MEdge *edge = mesh->getEdgeDataArray(mesh, CD_MEDGE);
if(vert != NULL && edge != NULL)
{
/* Create a bvh-tree of the given target */
tree = BLI_bvhtree_new(numEdges, epsilon, tree_type, axis);
if(tree != NULL)
{
for(i = 0; i < numEdges; i++)
{
float co[4][3];
VECCOPY(co[0], vert[ edge[i].v1 ].co);
VECCOPY(co[1], vert[ edge[i].v2 ].co);
BLI_bvhtree_insert(tree, i, co[0], 2);
}
BLI_bvhtree_balance(tree);
//Save on cache for later use
// printf("BVHTree built and saved on cache\n");
bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_EDGES);
}
}
}
else
{
// printf("BVHTree is already build, using cached tree\n");
}
//Setup BVHTreeFromMesh
memset(data, 0, sizeof(*data));
data->tree = tree;
if(data->tree)
{
data->cached = TRUE;
data->nearest_callback = mesh_edges_nearest_point;
data->raycast_callback = NULL;
data->mesh = mesh;
data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
data->edge = mesh->getEdgeDataArray(mesh, CD_MEDGE);
data->sphere_radius = epsilon;
}
return data->tree;
}
// Frees data allocated by a call to bvhtree_from_mesh_*.
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
{

File diff suppressed because it is too large Load Diff

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)
@@ -402,6 +405,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
VECCOPY(verts->xconst, mvert[i].co);
Mat4MulVecfl(ob->obmat, verts->xconst);
}
effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights);
tstart();
@@ -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

@@ -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,33 +593,17 @@ 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)
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");
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");
}
}
pdEndEffectors(&effectors);
if(part->boids) {
for(state = part->boids->states.first; state; state=state->next) {
for(rule = state->rules.first; rule; rule=rule->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;
@@ -1954,10 +1971,14 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf->zbuf_float= rres.rectz;
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};
@@ -2028,6 +2050,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
* things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
* 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)
@@ -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);
@@ -1525,10 +1530,9 @@ 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

@@ -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,25 +1334,44 @@ 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);
}
/* 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;
/* free this IpoCurve now that it's been converted */
BLI_freelinkN(&ipo->curve, icu);
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);
}
}
}

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;
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;
}
float fac, loc[4], dir[3], new_quat[4], radius;
short /*upflag, */ index;
index= axis-1;
if(index>2)
index -= 3; /* negative */
/* 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;
@@ -597,22 +581,104 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
q[2]= -fac*dir[1];
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);
}
/* local rotation */
Mat3MulVecfl(mat, cent);
/* 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 */
NormalQuat(quat);
QuatMulVecf(quat, cent);
/* translation */
VECADD(co, cent, loc);
if(quatp)
QUATCOPY(quatp, quat);

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 */
@@ -705,8 +678,9 @@ void *copy_libblock(void *rt)
id->newid= idn;
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,16 +172,16 @@ 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.shade_type = MA_VOL_SHADE_SHADED;
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);
@@ -6206,7 +6211,8 @@ static void surfaceModifier_freeData(ModifierData *md)
MEM_freeN(surmd->bvhtree);
}
surmd->dm->release(surmd->dm);
if(surmd->dm)
surmd->dm->release(surmd->dm);
if(surmd->x)
MEM_freeN(surmd->x);
@@ -6293,7 +6299,10 @@ static void surfaceModifier_deformVerts(
else
surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
if(surmd->dm->getNumFaces(surmd->dm))
bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
else
bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
}
}

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"
@@ -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);
@@ -1069,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;
}
@@ -1129,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);
@@ -1268,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]);
@@ -1278,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);
@@ -1922,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

@@ -37,6 +37,7 @@
#include "DNA_scene_types.h"
#include "DNA_boid_types.h"
#include "DNA_group_types.h"
#include "DNA_particle_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -53,7 +54,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,7 +62,9 @@
#include "BKE_boids.h"
#include "BKE_cloth.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_main.h"
#include "BKE_lattice.h"
#include "BKE_utildefines.h"
@@ -96,8 +99,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 +111,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++;
}
@@ -297,20 +298,72 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
return 1;
}
void psys_check_group_weights(ParticleSettings *part)
{
ParticleDupliWeight *dw, *tdw;
GroupObject *go;
int current = 0;
if(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first) {
/* first remove all weights that don't have an object in the group */
dw = part->dupliweights.first;
while(dw) {
if(!object_in_group(dw->ob, part->dup_group)) {
tdw = dw->next;
BLI_freelinkN(&part->dupliweights, dw);
dw = tdw;
}
else
dw = dw->next;
}
/* then add objects in the group to new list */
go = part->dup_group->gobject.first;
while(go) {
dw = part->dupliweights.first;
while(dw && dw->ob != go->ob)
dw = dw->next;
if(!dw) {
dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight");
dw->ob = go->ob;
dw->count = 1;
BLI_addtail(&part->dupliweights, dw);
}
go = go->next;
}
dw = part->dupliweights.first;
for(; dw; dw=dw->next) {
if(dw->flag & PART_DUPLIW_CURRENT) {
current = 1;
break;
}
}
if(!current) {
dw = part->dupliweights.first;
if(dw)
dw->flag |= PART_DUPLIW_CURRENT;
}
}
else {
BLI_freelistN(&part->dupliweights);
}
}
/************************************************/
/* Freeing stuff */
/************************************************/
void psys_free_settings(ParticleSettings *part)
{
if(part->pd) {
MEM_freeN(part->pd);
part->pd = NULL;
}
if(part->pd2) {
MEM_freeN(part->pd2);
part->pd2 = NULL;
}
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
if(part->effector_weights)
MEM_freeN(part->effector_weights);
BLI_freelistN(&part->dupliweights);
boid_free_settings(part->boids);
}
@@ -428,21 +481,26 @@ void psys_free_particles(ParticleSystem *psys)
}
void psys_free_pdd(ParticleSystem *psys)
{
if(psys->pdd->cdata)
MEM_freeN(psys->pdd->cdata);
psys->pdd->cdata = NULL;
if(psys->pdd) {
if(psys->pdd->cdata)
MEM_freeN(psys->pdd->cdata);
psys->pdd->cdata = NULL;
if(psys->pdd->vdata)
MEM_freeN(psys->pdd->vdata);
psys->pdd->vdata = NULL;
if(psys->pdd->vdata)
MEM_freeN(psys->pdd->vdata);
psys->pdd->vdata = NULL;
if(psys->pdd->ndata)
MEM_freeN(psys->pdd->ndata);
psys->pdd->ndata = NULL;
if(psys->pdd->ndata)
MEM_freeN(psys->pdd->ndata);
psys->pdd->ndata = NULL;
if(psys->pdd->vedata)
MEM_freeN(psys->pdd->vedata);
psys->pdd->vedata = NULL;
if(psys->pdd->vedata)
MEM_freeN(psys->pdd->vedata);
psys->pdd->vedata = NULL;
psys->pdd->totpoint = 0;
psys->pdd->tot_vec_size = 0;
}
}
/* free everything */
void psys_free(Object *ob, ParticleSystem * psys)
@@ -465,9 +523,6 @@ void psys_free(Object *ob, ParticleSystem * psys)
psys->child = 0;
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){
@@ -493,10 +548,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,124 +1952,135 @@ 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);
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);
}
}
else if(pd->f_power!=0.0f){
f_force= 1.0f/(1.0f + distance-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(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(eff->ob->obmat, guidevec);
Mat4Mul3Vecfl(eff->ob->obmat, guidedir);
Mat4MulVecfl(ec->ob->obmat,guidevec);
Mat4Mul3Vecfl(ec->ob->obmat,guidedir);
Normalize(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));
angle=saacos(angle);
VecRotToQuat(temp,angle,rot2);
QuatMulVecf(rot2,pa_loc);
if(guidetime != 0.0){
/* curve direction */
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, vec_to_point);
/* curve tilt */
VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2);
QuatMulVecf(rot2,pa_loc);
/* curve tilt */
VecRotToQuat(guidedir, guidevec[3] - eff->guide_loc[3], rot2);
QuatMulVecf(rot2, vec_to_point);
}
//vectoquat(guidedir, pd->kink_axis, (pd->kink_axis+1)%3, q);
//QuatMul(par.rot,rot2,q);
}
//else{
// par.rot[0]=1.0f;
// par.rot[1]=par.rot[2]=par.rot[3]=0.0f;
//}
/* curve taper */
if(cu->taperobj)
VecMulf(vec_to_point, calc_taper(eff->scene, cu->taperobj, (int)(data->strength*guidetime*100.0), 100));
/* curve taper */
if(cu->taperobj)
VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
else{ /* curve size*/
if(cu->flag & CU_PATH_RADIUS) {
VecMulf(pa_loc, radius);
}
}
par.co[0]=par.co[1]=par.co[2]=0.0f;
VECCOPY(key.co,pa_loc);
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);
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;
}
else{ /* curve size*/
if(cu->flag & CU_PATH_RADIUS) {
VecMulf(vec_to_point, radius);
}
}
par.co[0] = par.co[1] = par.co[2] = 0.0f;
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(vec_to_point, key.co);
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);
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;
}
Normalize(veffect);
VecMulf(veffect,VecLength(state->vel));
VECCOPY(state->vel,veffect);
return 1;
}
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;
}
@@ -2041,26 +2108,30 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
float roughfac;
roughfac=fac*(float)pow((double)t,shape);
VECCOPY(rough,loc);
Vec2Copyf(rough,loc);
rough[0]=-1.0f+2.0f*rough[0];
rough[1]=-1.0f+2.0f*rough[1];
VecMulf(rough,roughfac);
Vec2Mulf(rough,roughfac);
VECADDFAC(state->co,state->co,mat[0],rough[0]);
VECADDFAC(state->co,state->co,mat[1],rough[1]);
}
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 +2848,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 +3258,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 +3268,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;
@@ -3227,6 +3296,9 @@ static void default_particle_settings(ParticleSettings *part)
part->size=0.05;
part->childsize=1.0;
part->rotmode = PART_ROT_VEL;
part->avemode = PART_AVE_SPIN;
part->child_nbr=10;
part->ren_child_nbr=100;
part->childrad=0.2f;
@@ -3249,10 +3321,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 +3329,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 +3419,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 +3474,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 +3489,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 +3524,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 +3542,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 +3697,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 +3767,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 */
}
@@ -3801,6 +3852,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
/* get different child parameters from textures & vgroups */
memset(&ctx, 0, sizeof(ParticleThreadContext));
ctx.sim = *sim;
ctx.dm = psmd->dm;
ctx.ma = ma;
/* TODO: assign vertex groups */
@@ -3869,6 +3921,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
ChildParticle *cpa = NULL;
float cfra;
int totpart = psys->totpart;
float timestep = psys_get_timestep(sim);
/* negative time means "use current time" */
cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0);
@@ -3905,8 +3958,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))
@@ -3939,13 +3990,14 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
calc_latt_deform(sim->psys->lattice, state->co,1.0f);
}
else{
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED))
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
|| pa->prev_state.time <= 0.0f)
copy_particle_key(state, &pa->state, 1);
else if(pa->prev_state.time==state->time)
copy_particle_key(state, &pa->prev_state, 1);
else {
/* let's interpolate to try to be as accurate as possible */
if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) {
if(pa->state.time + 2.0f > state->time && pa->prev_state.time - 2.0f < state->time) {
ParticleKey keys[4];
float dfra, keytime, frs_sec = sim->scene->r.frs_sec;
@@ -3964,13 +4016,13 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
keytime = (state->time - keys[1].time) / dfra;
/* convert velocity to timestep size */
VecMulf(keys[1].vel, dfra / frs_sec);
VecMulf(keys[2].vel, dfra / frs_sec);
VecMulf(keys[1].vel, dfra * timestep);
VecMulf(keys[2].vel, dfra * timestep);
psys_interpolate_particle(-1, keys, keytime, state, 1);
/* convert back to real velocity */
VecMulf(state->vel, frs_sec / dfra);
VecMulf(state->vel, 1.0f / (dfra * timestep));
VecLerpf(state->ave, keys[1].ave, keys[2].ave, keytime);
QuatInterpol(state->rot, keys[1].rot, keys[2].rot, keytime);

File diff suppressed because it is too large Load Diff

View File

@@ -269,7 +269,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
/* determine rotation from velocity */
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot);
vectoquat(pa->state.vel, OB_NEGX, OB_POSZ, pa->state.rot);
}
}
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
@@ -292,13 +292,33 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
else
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
/* determine velocity from previous location */
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
if(keys[1].time > keys[2].time) {
VecSubf(keys[2].vel, keys[1].co, keys[2].co);
VecMulf(keys[2].vel, (keys[1].time - keys[2].time) / frs_sec);
}
else {
VecSubf(keys[2].vel, keys[2].co, keys[1].co);
VecMulf(keys[2].vel, (keys[2].time - keys[1].time) / frs_sec);
}
}
/* determine rotation from velocity */
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
vectoquat(keys[2].vel, OB_NEGX, OB_POSZ, keys[2].rot);
}
if(cfra > pa->time)
cfra1 = MAX2(cfra1, pa->time);
dfra = cfra2 - cfra1;
VecMulf(keys[1].vel, dfra / frs_sec);
VecMulf(keys[2].vel, dfra / frs_sec);
psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra);
QuatInterpol(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
VecMulf(pa->state.vel, frs_sec / dfra);
@@ -591,7 +611,8 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
if(psys->part->phystype == PART_PHYS_BOIDS)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
if(psys->part->rotmode || psys->part->avemode)
if(psys->part->rotmode!=PART_ROT_VEL
|| psys->part->avemode!=PART_AVE_SPIN || psys->part->avefac!=0.0f)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION);
if(psys->part->flag & PART_ROT_DYN)
@@ -2266,6 +2287,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
}
}
}
BLI_freelistN(&pidlist2);
}
if(bake || cache->flag & PTCACHE_REDO_NEEDED)

View File

@@ -400,6 +400,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;
@@ -778,11 +782,11 @@ static void scene_update(Scene *sce, unsigned int lay)
DAG_scene_update_flags(sce, lay); // only stuff that moves or needs display still
/* All 'standard' (i.e. without any dependencies) animation is handled here,
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
* can be overridden by settings from Scene, which owns the Texture through a hierarchy
* such as Scene->World->MTex/Texture) can still get correctly overridden.
*/
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
* can be overridden by settings from Scene, which owns the Texture through a hierarchy
* such as Scene->World->MTex/Texture) can still get correctly overridden.
*/
BKE_animsys_evaluate_all_animation(G.main, ctime);
for(base= sce->base.first; base; base= base->next) {

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);
@@ -2080,6 +2080,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
}
RE_ReleaseResultImage(re);
BIF_end_render_callbacks();

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,141 +280,12 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
{
// init collision points
SmokeCollSettings *scs = smd->coll;
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getFaceArray(dm);
int i = 0, divs = 0;
int *tridivs = NULL;
float cell_len = 1.0 / 50.0; // for res = 50
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++)
{
if(mface[i].v4)
quads++;
}
calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumFaces(dm), dm->getNumFaces(dm) + quads, &tridivs, cell_len);
// count triangle divisions
for(i = 0; i < dm->getNumFaces(dm) + quads; i++)
{
divs += (tridivs[3 * i] + 1) * (tridivs[3 * i + 1] + 1) * (tridivs[3 * i + 2] + 1);
}
// printf("divs: %d\n", divs);
scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints");
for(i = 0; i < dm->getNumVerts(dm); i++)
{
float tmpvec[3];
VECCOPY(tmpvec, mvert[i].co);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[i * 3], tmpvec);
}
for(i = 0, facecounter = 0; i < dm->getNumFaces(dm); i++)
{
int again = 0;
do
{
int j, k;
int divs1 = tridivs[3 * facecounter + 0];
int divs2 = tridivs[3 * facecounter + 1];
//int divs3 = tridivs[3 * facecounter + 2];
float side1[3], side2[3], trinormorg[3], trinorm[3];
if(again == 1 && mface[i].v4)
{
VECSUB(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
VECSUB(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co);
}
else
{
VECSUB(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co);
VECSUB(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
}
Crossf(trinormorg, side1, side2);
Normalize(trinormorg);
VECCOPY(trinorm, trinormorg);
VecMulf(trinorm, 0.25 * cell_len);
for(j = 0; j <= divs1; j++)
{
for(k = 0; k <= divs2; k++)
{
float p1[3], p2[3], p3[3], p[3]={0,0,0};
const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0);
const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0);
float tmpvec[3];
if(uf+vf > 1.0)
{
// printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2);
continue;
}
VECCOPY(p1, mvert[ mface[i].v1 ].co);
if(again == 1 && mface[i].v4)
{
VECCOPY(p2, mvert[ mface[i].v3 ].co);
VECCOPY(p3, mvert[ mface[i].v4 ].co);
}
else
{
VECCOPY(p2, mvert[ mface[i].v2 ].co);
VECCOPY(p3, mvert[ mface[i].v3 ].co);
}
VecMulf(p1, (1.0-uf-vf));
VecMulf(p2, uf);
VecMulf(p3, vf);
VECADD(p, p1, p2);
VECADD(p, p, p3);
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p + trinorm);
VECCOPY(tmpvec, p);
VECADD(tmpvec, tmpvec, trinorm);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p - trinorm);
VECCOPY(tmpvec, p);
VECSUB(tmpvec, tmpvec, trinorm);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
}
}
if(again == 0 && mface[i].v4)
again++;
else
again = 0;
facecounter++;
} while(again!=0);
}
scs->numpoints = dm->getNumVerts(dm) + newdivs;
MEM_freeN(tridivs);
fill_scs_points(ob, dm, scs);
}
if(!smd->coll->bvhtree)
@@ -426,6 +298,141 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
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;
int *tridivs = NULL;
float cell_len = 1.0 / 50.0; // for res = 50
int newdivs = 0;
int quads = 0, facecounter = 0;
// count quads
for(i = 0; i < dm->getNumFaces(dm); i++)
{
if(mface[i].v4)
quads++;
}
calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumFaces(dm), dm->getNumFaces(dm) + quads, &tridivs, cell_len);
// count triangle divisions
for(i = 0; i < dm->getNumFaces(dm) + quads; i++)
{
divs += (tridivs[3 * i] + 1) * (tridivs[3 * i + 1] + 1) * (tridivs[3 * i + 2] + 1);
}
// printf("divs: %d\n", divs);
scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints");
for(i = 0; i < dm->getNumVerts(dm); i++)
{
float tmpvec[3];
VECCOPY(tmpvec, mvert[i].co);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[i * 3], tmpvec);
}
for(i = 0, facecounter = 0; i < dm->getNumFaces(dm); i++)
{
int again = 0;
do
{
int j, k;
int divs1 = tridivs[3 * facecounter + 0];
int divs2 = tridivs[3 * facecounter + 1];
//int divs3 = tridivs[3 * facecounter + 2];
float side1[3], side2[3], trinormorg[3], trinorm[3];
if(again == 1 && mface[i].v4)
{
VECSUB(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
VECSUB(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co);
}
else
{
VECSUB(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co);
VECSUB(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co);
}
Crossf(trinormorg, side1, side2);
Normalize(trinormorg);
VECCOPY(trinorm, trinormorg);
VecMulf(trinorm, 0.25 * cell_len);
for(j = 0; j <= divs1; j++)
{
for(k = 0; k <= divs2; k++)
{
float p1[3], p2[3], p3[3], p[3]={0,0,0};
const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0);
const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0);
float tmpvec[3];
if(uf+vf > 1.0)
{
// printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2);
continue;
}
VECCOPY(p1, mvert[ mface[i].v1 ].co);
if(again == 1 && mface[i].v4)
{
VECCOPY(p2, mvert[ mface[i].v3 ].co);
VECCOPY(p3, mvert[ mface[i].v4 ].co);
}
else
{
VECCOPY(p2, mvert[ mface[i].v2 ].co);
VECCOPY(p3, mvert[ mface[i].v3 ].co);
}
VecMulf(p1, (1.0-uf-vf));
VecMulf(p2, uf);
VecMulf(p3, vf);
VECADD(p, p1, p2);
VECADD(p, p, p3);
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p + trinorm);
VECCOPY(tmpvec, p);
VECADD(tmpvec, tmpvec, trinorm);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
if(newdivs > divs)
printf("mem problem\n");
// mMovPoints.push_back(p - trinorm);
VECCOPY(tmpvec, p);
VECSUB(tmpvec, tmpvec, trinorm);
Mat4MulVecfl (ob->obmat, tmpvec);
VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec);
newdivs++;
}
}
if(again == 0 && mface[i].v4)
again++;
else
again = 0;
facecounter++;
} while(again!=0);
}
scs->numpoints = dm->getNumVerts(dm) + newdivs;
MEM_freeN(tridivs);
}
/*! 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);
}
@@ -1589,14 +1592,13 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
{
SoftBody *sb = ob->soft;
ListBase *do_effector= NULL;
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)
@@ -1661,9 +1663,8 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
exec_scan_for_ext_spring_forces(&sb_threads[0]);
/* 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);

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