svn merge -r 23528:23646 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 ")
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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']
|
||||
|
||||
|
||||
6
extern/bullet2/CMakeLists.txt
vendored
6
extern/bullet2/CMakeLists.txt
vendored
@@ -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 )
|
||||
|
||||
|
||||
4
extern/bullet2/src/SConscript
vendored
4
extern/bullet2/src/SConscript
vendored
@@ -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':
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
* $Id$
|
||||
* Copyright (C) 2001 NaN Technologies B.V.
|
||||
* @author Maarten Gribnau
|
||||
* @date September 21, 2001
|
||||
|
||||
106
intern/ghost/intern/GHOST_DisplayManagerCocoa.h
Normal file
106
intern/ghost/intern/GHOST_DisplayManagerCocoa.h
Normal 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_
|
||||
|
||||
168
intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
Normal file
168
intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
274
intern/ghost/intern/GHOST_SystemCocoa.h
Normal file
274
intern/ghost/intern/GHOST_SystemCocoa.h
Normal 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_
|
||||
|
||||
1414
intern/ghost/intern/GHOST_SystemCocoa.mm
Normal file
1414
intern/ghost/intern/GHOST_SystemCocoa.mm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
315
intern/ghost/intern/GHOST_WindowCocoa.h
Normal file
315
intern/ghost/intern/GHOST_WindowCocoa.h
Normal 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_
|
||||
|
||||
751
intern/ghost/intern/GHOST_WindowCocoa.mm
Normal file
751
intern/ghost/intern/GHOST_WindowCocoa.mm
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_");
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
154
release/scripts/ui/buttons_physics_common.py
Normal file
154
release/scripts/ui/buttons_physics_common.py
Normal 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")
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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:")
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@ typedef struct SculptSession {
|
||||
|
||||
struct SculptStroke *stroke;
|
||||
struct StrokeCache *cache;
|
||||
|
||||
struct GPUDrawObject *drawobject;
|
||||
} SculptSession;
|
||||
|
||||
void free_sculptsession(SculptSession **);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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] = {
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user