merged changes to revision 23620
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(WITH_PYTHON)
|
||||
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LINKFLAGS})
|
||||
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
|
||||
TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
|
||||
ELSE(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
|
||||
ENDIF(WIN32)
|
||||
ENDIF(WITH_PYTHON)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${LLIBS})
|
||||
TARGET_LINK_LIBRARIES(${target} ${OPENGL_glu_LIBRARY} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB})
|
||||
TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIBRARY} ${LIBSAMPLERATE_LIB})
|
||||
|
||||
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
|
||||
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d)
|
||||
TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB})
|
||||
ELSE(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB})
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(WITH_INTERNATIONAL)
|
||||
TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB})
|
||||
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB})
|
||||
ENDIF(WIN32)
|
||||
ENDIF(WITH_INTERNATIONAL)
|
||||
|
||||
IF(WITH_OPENAL)
|
||||
TARGET_LINK_LIBRARIES(${target} ${OPENAL_LIBRARY})
|
||||
ENDIF(WITH_OPENAL)
|
||||
@@ -127,9 +126,6 @@ MACRO(SETUP_LIBLINKS
|
||||
IF(WITH_SDL)
|
||||
TARGET_LINK_LIBRARIES(${target} ${SDL_LIBRARY})
|
||||
ENDIF(WITH_SDL)
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB})
|
||||
ENDIF(WIN32)
|
||||
IF(WITH_QUICKTIME)
|
||||
TARGET_LINK_LIBRARIES(${target} ${QUICKTIME_LIB})
|
||||
ENDIF(WITH_QUICKTIME)
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -540,6 +540,8 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
|
||||
return device->setCapability(AUD_CAPS_VOLUME, &volume);
|
||||
}
|
||||
catch(AUD_Exception) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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__
|
||||
# ifdef GHOST_COCOA
|
||||
# include "GHOST_SystemCocoa.h"
|
||||
# else
|
||||
# include "GHOST_SystemCarbon.h"
|
||||
# endif
|
||||
# else
|
||||
# include "GHOST_SystemX11.h"
|
||||
# endif
|
||||
@@ -62,7 +66,11 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
|
||||
m_system = new GHOST_SystemWin32 ();
|
||||
#else
|
||||
# ifdef __APPLE__
|
||||
# ifdef GHOST_COCOA
|
||||
m_system = new GHOST_SystemCocoa ();
|
||||
# else
|
||||
m_system = new GHOST_SystemCarbon ();
|
||||
# endif
|
||||
# else
|
||||
m_system = new GHOST_SystemX11 ();
|
||||
# endif
|
||||
|
||||
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);
|
||||
|
||||
/***************************************************************************************
|
||||
** Cursor management functionality
|
||||
***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns the current location of the cursor (location in screen coordinates)
|
||||
* @param x The x-coordinate of the cursor.
|
||||
* @param y The y-coordinate of the cursor.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
|
||||
|
||||
/**
|
||||
* Updates the location of the cursor (location in screen coordinates).
|
||||
* @param x The x-coordinate of the cursor.
|
||||
* @param y The y-coordinate of the cursor.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
|
||||
|
||||
/***************************************************************************************
|
||||
** Access to mouse button and keyboard states.
|
||||
***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns the state of all modifier keys.
|
||||
* @param keys The state of all modifier keys (true == pressed).
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
|
||||
|
||||
/**
|
||||
* Returns the state of the mouse buttons (ouside the message queue).
|
||||
* @param buttons The state of the buttons.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
|
||||
|
||||
/**
|
||||
* Returns Clipboard data
|
||||
* @param selection Indicate which buffer to return
|
||||
* @return Returns the selected buffer
|
||||
*/
|
||||
virtual GHOST_TUns8* getClipboard(bool selection) const;
|
||||
|
||||
/**
|
||||
* Puts buffer to system clipboard
|
||||
* @param buffer The buffer to be copied
|
||||
* @param selection Indicates which buffer to copy too, only used on X11
|
||||
*/
|
||||
virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initializes the system.
|
||||
* For now, it justs registers the window class (WNDCLASS).
|
||||
* @return A success value.
|
||||
*/
|
||||
virtual GHOST_TSuccess init();
|
||||
|
||||
/**
|
||||
* Closes the system down.
|
||||
* @return A success value.
|
||||
*/
|
||||
virtual GHOST_TSuccess exit();
|
||||
|
||||
|
||||
/**
|
||||
* Handles a tablet event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
int handleTabletEvent(void *eventPtr);
|
||||
/**
|
||||
* Handles a mouse event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
int handleMouseEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a key event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
int handleKeyEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a window event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
int handleWindowEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles all basic Mac application stuff for a mouse down event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
// bool handleMouseDown(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a Mac menu command.
|
||||
* @param menuResult A Mac menu/item identifier.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
// bool handleMenuCommand(GHOST_TInt32 menuResult);
|
||||
|
||||
/* callback for blender generated events */
|
||||
// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
|
||||
|
||||
|
||||
/**
|
||||
* Callback for Mac Timer tasks that expire.
|
||||
* @param tmTask Pointer to the timer task that expired.
|
||||
*/
|
||||
//static void s_timerCallback(TMTaskPtr tmTask);
|
||||
|
||||
/** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */
|
||||
void* m_autoReleasePool;
|
||||
|
||||
/** Event handler reference. */
|
||||
//EventHandlerRef m_handler;
|
||||
|
||||
/** Start time at initialization. */
|
||||
GHOST_TUns64 m_start_time;
|
||||
|
||||
/** Mouse buttons state */
|
||||
GHOST_TUns32 m_pressedMouseButtons;
|
||||
|
||||
/** State of the modifiers. */
|
||||
GHOST_TUns32 m_modifierMask;
|
||||
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
};
|
||||
|
||||
#endif // _GHOST_SYSTEM_COCOA_H_
|
||||
|
||||
1353
intern/ghost/intern/GHOST_SystemCocoa.mm
Normal file
1353
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
|
||||
|
||||
308
intern/ghost/intern/GHOST_WindowCocoa.h
Normal file
308
intern/ghost/intern/GHOST_WindowCocoa.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
/**
|
||||
* @file GHOST_WindowCocoa.h
|
||||
* Declaration of GHOST_WindowCocoa class.
|
||||
*/
|
||||
|
||||
#ifndef _GHOST_WINDOW_COCOA_H_
|
||||
#define _GHOST_WINDOW_COCOA_H_
|
||||
|
||||
#ifndef __APPLE__
|
||||
#error Apple OSX only!
|
||||
#endif // __APPLE__
|
||||
|
||||
#include "GHOST_Window.h"
|
||||
#include "STR_String.h"
|
||||
|
||||
#include <AGL/agl.h>
|
||||
|
||||
|
||||
/**
|
||||
* Window on Mac OSX/Cocoa.
|
||||
* Carbon windows have a size widget in the lower right corner of the window.
|
||||
* To force it to be visible, the height of the client rectangle is reduced so
|
||||
* that applications do not draw in that area. GHOST will manage that area
|
||||
* which is called the gutter.
|
||||
* When OpenGL contexts are active, GHOST will use AGL_BUFFER_RECT to prevent
|
||||
* OpenGL drawing outside the reduced client rectangle.
|
||||
* @author Maarten Gribnau
|
||||
* @date May 23, 2001
|
||||
*/
|
||||
class GHOST_WindowCocoa : public GHOST_Window {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new window and opens it.
|
||||
* To check if the window was created properly, use the getValid() method.
|
||||
* @param title The text shown in the title bar of the window.
|
||||
* @param left The coordinate of the left edge of the window.
|
||||
* @param top The coordinate of the top edge of the window.
|
||||
* @param width The width the window.
|
||||
* @param height The height the window.
|
||||
* @param state The state the window is initially opened with.
|
||||
* @param type The type of drawing context installed in this window.
|
||||
* @param stereoVisual Stereo visual for quad buffered stereo.
|
||||
*/
|
||||
GHOST_WindowCocoa(
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
|
||||
const bool stereoVisual = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Closes the window and disposes resources allocated.
|
||||
*/
|
||||
virtual ~GHOST_WindowCocoa();
|
||||
|
||||
/**
|
||||
* Returns indication as to whether the window is valid.
|
||||
* @return The validity of the window.
|
||||
*/
|
||||
virtual bool getValid() const;
|
||||
|
||||
/**
|
||||
* Sets the title displayed in the title bar.
|
||||
* @param title The title to display in the title bar.
|
||||
*/
|
||||
virtual void setTitle(const STR_String& title);
|
||||
|
||||
/**
|
||||
* Returns the title displayed in the title bar.
|
||||
* @param title The title displayed in the title bar.
|
||||
*/
|
||||
virtual void getTitle(STR_String& title) const;
|
||||
|
||||
/**
|
||||
* Returns the window rectangle dimensions.
|
||||
* The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
|
||||
* @param bounds The bounding rectangle of the window.
|
||||
*/
|
||||
virtual void getWindowBounds(GHOST_Rect& bounds) const;
|
||||
|
||||
/**
|
||||
* Returns the client rectangle dimensions.
|
||||
* The left and top members of the rectangle are always zero.
|
||||
* @param bounds The bounding rectangle of the cleient area of the window.
|
||||
*/
|
||||
virtual void getClientBounds(GHOST_Rect& bounds) const;
|
||||
|
||||
/**
|
||||
* Resizes client rectangle width.
|
||||
* @param width The new width of the client area of the window.
|
||||
*/
|
||||
virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
|
||||
|
||||
/**
|
||||
* Resizes client rectangle height.
|
||||
* @param height The new height of the client area of the window.
|
||||
*/
|
||||
virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
|
||||
|
||||
/**
|
||||
* Resizes client rectangle.
|
||||
* @param width The new width of the client area of the window.
|
||||
* @param height The new height of the client area of the window.
|
||||
*/
|
||||
virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
|
||||
|
||||
/**
|
||||
* Returns the state of the window (normal, minimized, maximized).
|
||||
* @return The state of the window.
|
||||
*/
|
||||
virtual GHOST_TWindowState getState() const;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* @param inX The x-coordinate on the screen.
|
||||
* @param inY The y-coordinate on the screen.
|
||||
* @param outX The x-coordinate in the client rectangle.
|
||||
* @param outY The y-coordinate in the client rectangle.
|
||||
*/
|
||||
virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
||||
|
||||
/**
|
||||
* Converts a point in screen coordinates to client rectangle coordinates
|
||||
* @param inX The x-coordinate in the client rectangle.
|
||||
* @param inY The y-coordinate in the client rectangle.
|
||||
* @param outX The x-coordinate on the screen.
|
||||
* @param outY The y-coordinate on the screen.
|
||||
*/
|
||||
virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
||||
|
||||
/**
|
||||
* Sets the state of the window (normal, minimized, maximized).
|
||||
* @param state The state of the window.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setState(GHOST_TWindowState state);
|
||||
|
||||
/**
|
||||
* Sets the order of the window (bottom, top).
|
||||
* @param order The order of the window.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* @return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window. Needed
|
||||
* whenever the window is changed.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* @return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
|
||||
|
||||
/**
|
||||
* Returns the dirty state of the window when in full-screen mode.
|
||||
* @return Whether it is dirty.
|
||||
*/
|
||||
virtual bool getFullScreenDirty();
|
||||
|
||||
/* accessor for fullscreen window */
|
||||
virtual void setMac_windowState(short value);
|
||||
virtual short getMac_windowState();
|
||||
|
||||
|
||||
const GHOST_TabletData* GetTabletData()
|
||||
{ return &m_tablet; }
|
||||
|
||||
GHOST_TabletData& GetCocoaTabletData()
|
||||
{ return m_tablet; }
|
||||
protected:
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* @param type The type of rendering context installed.
|
||||
* @return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
|
||||
|
||||
/**
|
||||
* Removes the current drawing context.
|
||||
* @return Indication as to whether removal has succeeded.
|
||||
*/
|
||||
virtual GHOST_TSuccess removeDrawingContext();
|
||||
|
||||
/**
|
||||
* Invalidates the contents of this window.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess invalidate();
|
||||
|
||||
/**
|
||||
* Sets the cursor visibility on the window using
|
||||
* native window system calls.
|
||||
*/
|
||||
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
|
||||
|
||||
/**
|
||||
* Sets the cursor shape on the window using
|
||||
* native window system calls.
|
||||
*/
|
||||
virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
|
||||
|
||||
/**
|
||||
* Sets the cursor shape on the window using
|
||||
* native window system calls.
|
||||
*/
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
|
||||
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
|
||||
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
|
||||
|
||||
/**
|
||||
* Converts a string object to a Mac Pascal string.
|
||||
* @param in The string object to be converted.
|
||||
* @param out The converted string.
|
||||
*/
|
||||
virtual void gen2mac(const STR_String& in, Str255 out) const;
|
||||
|
||||
/**
|
||||
* Converts a Mac Pascal string to a string object.
|
||||
* @param in The string to be converted.
|
||||
* @param out The converted string object.
|
||||
*/
|
||||
virtual void mac2gen(const Str255 in, STR_String& out) const;
|
||||
|
||||
WindowRef m_windowRef;
|
||||
CGrafPtr m_grafPtr;
|
||||
AGLContext m_aglCtx;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static AGLContext s_firstaglCtx;
|
||||
|
||||
Cursor* m_customCursor;
|
||||
|
||||
GHOST_TabletData m_tablet;
|
||||
|
||||
/** When running in full-screen this tells whether to refresh the window. */
|
||||
bool m_fullScreenDirty;
|
||||
|
||||
/** specific MacOs X full screen window setting as we use partially system mechanism
|
||||
values : 0 not maximizable default
|
||||
1 normal state
|
||||
2 maximized state
|
||||
|
||||
this will be reworked when rebuilding GHOST carbon to use new OS X apis
|
||||
in order to be unified with GHOST fullscreen/maximised settings
|
||||
|
||||
(lukep)
|
||||
**/
|
||||
|
||||
short mac_windowState;
|
||||
|
||||
|
||||
/**
|
||||
* The width/height of the size rectangle in the lower right corner of a
|
||||
* Mac/Carbon window. This is also the height of the gutter area.
|
||||
*/
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
static const GHOST_TInt32 s_sizeRectSize;
|
||||
#endif // GHOST_DRAW_CARBON_GUTTER
|
||||
};
|
||||
|
||||
#endif // _GHOST_WINDOW_COCOA_H_
|
||||
|
||||
745
intern/ghost/intern/GHOST_WindowCocoa.mm
Normal file
745
intern/ghost/intern/GHOST_WindowCocoa.mm
Normal file
@@ -0,0 +1,745 @@
|
||||
/**
|
||||
* $Id$
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright (C) 2001 NaN Technologies B.V.
|
||||
* @author Maarten Gribnau
|
||||
* @date May 10, 2001
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#include "GHOST_WindowCocoa.h"
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL;
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16;
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
|
||||
static const GLint sPreferredFormatWindow[8] = {
|
||||
AGL_RGBA,
|
||||
AGL_DOUBLEBUFFER,
|
||||
AGL_ACCELERATED,
|
||||
AGL_DEPTH_SIZE, 32,
|
||||
AGL_NONE,
|
||||
};
|
||||
|
||||
static const GLint sPreferredFormatFullScreen[9] = {
|
||||
AGL_RGBA,
|
||||
AGL_DOUBLEBUFFER,
|
||||
AGL_ACCELERATED,
|
||||
AGL_FULLSCREEN,
|
||||
AGL_DEPTH_SIZE, 32,
|
||||
AGL_NONE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
WindowRef ugly_hack=NULL;
|
||||
|
||||
const EventTypeSpec kWEvents[] = {
|
||||
{ kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */
|
||||
};
|
||||
|
||||
static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
|
||||
WindowRef mywindow;
|
||||
GHOST_WindowCocoa *ghost_window;
|
||||
OSStatus err;
|
||||
int theState;
|
||||
|
||||
if (::GetEventKind(event) == kEventWindowZoom) {
|
||||
err = ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow);
|
||||
ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow);
|
||||
theState = ghost_window->getMac_windowState();
|
||||
if (theState == 1)
|
||||
ghost_window->setMac_windowState(2);
|
||||
else if (theState == 2)
|
||||
ghost_window->setMac_windowState(1);
|
||||
|
||||
}
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
|
||||
GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual
|
||||
) :
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
|
||||
m_windowRef(0),
|
||||
m_grafPtr(0),
|
||||
m_aglCtx(0),
|
||||
m_customCursor(0),
|
||||
m_fullScreenDirty(false)
|
||||
{
|
||||
Str255 title255;
|
||||
OSStatus err;
|
||||
|
||||
//fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
|
||||
|
||||
if (state >= GHOST_kWindowState8Normal ) {
|
||||
if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal;
|
||||
else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized;
|
||||
else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized;
|
||||
else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen;
|
||||
|
||||
// state = state - 8; this was the simple version of above code, doesnt work in gcc 4.0
|
||||
|
||||
setMac_windowState(1);
|
||||
} else
|
||||
setMac_windowState(0);
|
||||
|
||||
if (state != GHOST_kWindowStateFullScreen) {
|
||||
Rect bnds = { top, left, top+height, left+width };
|
||||
// Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
|
||||
gen2mac(title, title255);
|
||||
|
||||
err = ::CreateNewWindow( kDocumentWindowClass,
|
||||
kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
|
||||
&bnds,
|
||||
&m_windowRef);
|
||||
|
||||
if ( err != noErr) {
|
||||
fprintf(stderr," error creating window %i \n",err);
|
||||
} else {
|
||||
|
||||
::SetWRefCon(m_windowRef,(SInt32)this);
|
||||
setTitle(title);
|
||||
err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL);
|
||||
if ( err != noErr) {
|
||||
fprintf(stderr," error creating handler %i \n",err);
|
||||
} else {
|
||||
// ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
|
||||
::ShowWindow(m_windowRef);
|
||||
::MoveWindow (m_windowRef, left, top,true);
|
||||
|
||||
}
|
||||
}
|
||||
if (m_windowRef) {
|
||||
m_grafPtr = ::GetWindowPort(m_windowRef);
|
||||
setDrawingContextType(type);
|
||||
updateDrawingContext();
|
||||
activateDrawingContext();
|
||||
}
|
||||
if(ugly_hack==NULL) {
|
||||
ugly_hack= m_windowRef;
|
||||
// when started from commandline, window remains in the back... also for play anim
|
||||
ProcessSerialNumber psn;
|
||||
GetCurrentProcess(&psn);
|
||||
SetFrontProcess(&psn);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
Rect bnds = { top, left, top+height, left+width };
|
||||
gen2mac("", title255);
|
||||
m_windowRef = ::NewCWindow(
|
||||
nil, // Storage
|
||||
&bnds, // Bounding rectangle of the window
|
||||
title255, // Title of the window
|
||||
0, // Window initially visible
|
||||
plainDBox, // procID
|
||||
(WindowRef)-1L, // Put window before all other windows
|
||||
0, // Window has minimize box
|
||||
(SInt32)this); // Store a pointer to the class in the refCon
|
||||
*/
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n");
|
||||
setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
|
||||
updateDrawingContext();
|
||||
activateDrawingContext();
|
||||
|
||||
m_tablet.Active = GHOST_kTabletModeNone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
{
|
||||
if (m_customCursor) delete m_customCursor;
|
||||
|
||||
if(ugly_hack==m_windowRef) ugly_hack= NULL;
|
||||
|
||||
// printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n");
|
||||
if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);
|
||||
if (m_windowRef) {
|
||||
::DisposeWindow(m_windowRef);
|
||||
m_windowRef = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool GHOST_WindowCocoa::getValid() const
|
||||
{
|
||||
bool valid;
|
||||
if (!m_fullScreen) {
|
||||
valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
|
||||
}
|
||||
else {
|
||||
valid = true;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::setTitle(const STR_String& title)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
|
||||
Str255 title255;
|
||||
gen2mac(title, title255);
|
||||
::SetWTitle(m_windowRef, title255);
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getTitle(STR_String& title) const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
|
||||
Str255 title255;
|
||||
::GetWTitle(m_windowRef, title255);
|
||||
mac2gen(title255, title);
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
|
||||
{
|
||||
OSStatus success;
|
||||
Rect rect;
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
|
||||
success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
|
||||
bounds.m_b = rect.bottom;
|
||||
bounds.m_l = rect.left;
|
||||
bounds.m_r = rect.right;
|
||||
bounds.m_t = rect.top;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
|
||||
{
|
||||
Rect rect;
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
|
||||
//::GetPortBounds(m_grafPtr, &rect);
|
||||
::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect);
|
||||
|
||||
bounds.m_b = rect.bottom;
|
||||
bounds.m_l = rect.left;
|
||||
bounds.m_r = rect.right;
|
||||
bounds.m_t = rect.top;
|
||||
|
||||
// Subtract gutter height from bottom
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if ((bounds.m_b - bounds.m_t) > s_sizeRectSize)
|
||||
{
|
||||
bounds.m_b -= s_sizeRectSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds.m_t = bounds.m_b;
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
if (((GHOST_TUns32)cBnds.getWidth()) != width) {
|
||||
::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) {
|
||||
::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true);
|
||||
}
|
||||
#else //GHOST_DRAW_CARBON_GUTTER
|
||||
if (((GHOST_TUns32)cBnds.getHeight()) != height) {
|
||||
::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
|
||||
(((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) {
|
||||
::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true);
|
||||
}
|
||||
#else //GHOST_DRAW_CARBON_GUTTER
|
||||
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
|
||||
(((GHOST_TUns32)cBnds.getHeight()) != height)) {
|
||||
::SizeWindow(m_windowRef, width, height, true);
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TWindowState GHOST_WindowCocoa::getState() const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
|
||||
GHOST_TWindowState state;
|
||||
if (::IsWindowVisible(m_windowRef) == false) {
|
||||
state = GHOST_kWindowStateMinimized;
|
||||
}
|
||||
else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
|
||||
state = GHOST_kWindowStateMaximized;
|
||||
}
|
||||
else {
|
||||
state = GHOST_kWindowStateNormal;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
|
||||
Point point;
|
||||
point.h = inX;
|
||||
point.v = inY;
|
||||
GrafPtr oldPort;
|
||||
::GetPort(&oldPort);
|
||||
::SetPort(m_grafPtr);
|
||||
::GlobalToLocal(&point);
|
||||
::SetPort(oldPort);
|
||||
outX = point.h;
|
||||
outY = point.v;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid")
|
||||
Point point;
|
||||
point.h = inX;
|
||||
point.v = inY;
|
||||
GrafPtr oldPort;
|
||||
::GetPort(&oldPort);
|
||||
::SetPort(m_grafPtr);
|
||||
::LocalToGlobal(&point);
|
||||
::SetPort(oldPort);
|
||||
outX = point.h;
|
||||
outY = point.v;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
|
||||
switch (state) {
|
||||
case GHOST_kWindowStateMinimized:
|
||||
::HideWindow(m_windowRef);
|
||||
break;
|
||||
case GHOST_kWindowStateModified:
|
||||
SetWindowModified(m_windowRef, 1);
|
||||
break;
|
||||
case GHOST_kWindowStateUnModified:
|
||||
SetWindowModified(m_windowRef, 0);
|
||||
break;
|
||||
case GHOST_kWindowStateMaximized:
|
||||
case GHOST_kWindowStateNormal:
|
||||
default:
|
||||
::ShowWindow(m_windowRef);
|
||||
break;
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
|
||||
if (order == GHOST_kWindowOrderTop) {
|
||||
//::BringToFront(m_windowRef); is wrong, front window should be active for input too
|
||||
::SelectWindow(m_windowRef);
|
||||
}
|
||||
else {
|
||||
/* doesnt work if you do this with a mouseclick */
|
||||
::SendBehind(m_windowRef, nil);
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
/*#define WAIT_FOR_VSYNC 1*/
|
||||
#ifdef WAIT_FOR_VSYNC
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
|
||||
{
|
||||
#ifdef WAIT_FOR_VSYNC
|
||||
/* wait for vsync, to avoid tearing artifacts */
|
||||
long VBL = 1;
|
||||
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglSwapBuffers(m_aglCtx);
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglUpdateContext(m_aglCtx);
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglSetCurrentContext(m_aglCtx);
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
// Restrict drawing to non-gutter area
|
||||
::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
|
||||
GHOST_Rect bnds;
|
||||
getClientBounds(bnds);
|
||||
GLint b[4] =
|
||||
{
|
||||
bnds.m_l,
|
||||
bnds.m_t+s_sizeRectSize,
|
||||
bnds.m_r-bnds.m_l,
|
||||
bnds.m_b-bnds.m_t
|
||||
};
|
||||
GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
{
|
||||
if (!getValid()) break;
|
||||
|
||||
AGLPixelFormat pixelFormat;
|
||||
if (!m_fullScreen) {
|
||||
pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
|
||||
m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
|
||||
if (!m_aglCtx) break;
|
||||
if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
|
||||
success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
else {
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n");
|
||||
GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen);
|
||||
m_aglCtx = ::aglCreateContext(pixelFormat, 0);
|
||||
if (!m_aglCtx) break;
|
||||
if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n");
|
||||
//::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
|
||||
success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
/*
|
||||
if (success == GHOST_kSuccess) {
|
||||
GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n");
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
::aglDestroyPixelFormat(pixelFormat);
|
||||
}
|
||||
break;
|
||||
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
switch (m_drawingContextType) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
if (m_aglCtx) {
|
||||
aglSetCurrentContext(NULL);
|
||||
aglSetDrawable(m_aglCtx, NULL);
|
||||
//aglDestroyContext(m_aglCtx);
|
||||
if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
|
||||
success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
m_aglCtx = 0;
|
||||
}
|
||||
break;
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
|
||||
if (!m_fullScreen) {
|
||||
Rect rect;
|
||||
::GetPortBounds(m_grafPtr, &rect);
|
||||
::InvalWindowRect(m_windowRef, &rect);
|
||||
}
|
||||
else {
|
||||
//EventRef event;
|
||||
//OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n");
|
||||
//status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n");
|
||||
//status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
|
||||
//status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
|
||||
m_fullScreenDirty = true;
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const
|
||||
{
|
||||
STR_String tempStr = in;
|
||||
int num = tempStr.Length();
|
||||
if (num > 255) num = 255;
|
||||
::memcpy(out+1, tempStr.Ptr(), num);
|
||||
out[0] = num;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const
|
||||
{
|
||||
char tmp[256];
|
||||
::memcpy(tmp, in+1, in[0]);
|
||||
tmp[in[0]] = '\0';
|
||||
out = tmp;
|
||||
}
|
||||
|
||||
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
|
||||
{
|
||||
static bool systemCursorVisible = true;
|
||||
|
||||
if (visible != systemCursorVisible) {
|
||||
if (visible) {
|
||||
::ShowCursor();
|
||||
systemCursorVisible = true;
|
||||
}
|
||||
else {
|
||||
::HideCursor();
|
||||
systemCursorVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
|
||||
::SetCursor( m_customCursor );
|
||||
} else {
|
||||
int carbon_cursor;
|
||||
|
||||
#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break
|
||||
switch (cursor) {
|
||||
default:
|
||||
GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorRightArrow, kThemeAliasArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor);
|
||||
GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor);
|
||||
GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor);
|
||||
GCMAP( GHOST_kStandardCursorUpDown, kThemeClosedHandCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftRight, kThemeClosedHandCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor);
|
||||
GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor);
|
||||
};
|
||||
#undef GCMAP
|
||||
|
||||
::SetThemeCursor(carbon_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GHOST_WindowCocoa::getFullScreenDirty()
|
||||
{
|
||||
return m_fullScreen && m_fullScreenDirty;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
|
||||
{
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
loadCursor(visible, getCursorShape());
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
|
||||
{
|
||||
if (m_customCursor) {
|
||||
delete m_customCursor;
|
||||
m_customCursor = 0;
|
||||
}
|
||||
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
loadCursor(getCursorVisibility(), shape);
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/** Reverse the bits in a GHOST_TUns8 */
|
||||
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
|
||||
{
|
||||
ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA);
|
||||
ch= ((ch>>2)&0x33) | ((ch<<2)&0xCC);
|
||||
ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** Reverse the bits in a GHOST_TUns16 */
|
||||
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
|
||||
{
|
||||
shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
|
||||
shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
|
||||
shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
|
||||
shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
|
||||
return shrt;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
|
||||
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
|
||||
{
|
||||
int y;
|
||||
|
||||
if (m_customCursor) {
|
||||
delete m_customCursor;
|
||||
m_customCursor = 0;
|
||||
}
|
||||
|
||||
m_customCursor = new Cursor;
|
||||
if (!m_customCursor) return GHOST_kFailure;
|
||||
|
||||
for (y=0; y<16; y++) {
|
||||
#if !defined(__LITTLE_ENDIAN__)
|
||||
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
|
||||
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
|
||||
#else
|
||||
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
|
||||
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
m_customCursor->hotSpot.h = hotX;
|
||||
m_customCursor->hotSpot.v = hotY;
|
||||
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
|
||||
GHOST_TUns8 mask[16][2], int hotX, int hotY)
|
||||
{
|
||||
return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::setMac_windowState(short value)
|
||||
{
|
||||
mac_windowState = value;
|
||||
}
|
||||
|
||||
short GHOST_WindowCocoa::getMac_windowState()
|
||||
{
|
||||
return mac_windowState;
|
||||
}
|
||||
@@ -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])
|
||||
@@ -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):
|
||||
"""
|
||||
@@ -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 = []
|
||||
@@ -54,6 +55,10 @@ class MRenderJob(netrender.model.RenderJob):
|
||||
self.blacklist = blacklist
|
||||
self.last_dispatched = time.time()
|
||||
|
||||
# force one chunk for process jobs
|
||||
if self.type == netrender.model.JOB_PROCESS:
|
||||
self.chunks = 1
|
||||
|
||||
# special server properties
|
||||
self.last_update = 0
|
||||
self.save_path = ""
|
||||
@@ -93,8 +98,8 @@ class MRenderJob(netrender.model.RenderJob):
|
||||
if frame:
|
||||
frame.log_path = log_path
|
||||
|
||||
def addFrame(self, frame_number):
|
||||
frame = MRenderFrame(frame_number)
|
||||
def addFrame(self, frame_number, command):
|
||||
frame = MRenderFrame(frame_number, command)
|
||||
self.frames.append(frame)
|
||||
return frame
|
||||
|
||||
@@ -114,12 +119,14 @@ class MRenderJob(netrender.model.RenderJob):
|
||||
return frames
|
||||
|
||||
class MRenderFrame(netrender.model.RenderFrame):
|
||||
def __init__(self, frame):
|
||||
def __init__(self, frame, command):
|
||||
super().__init__()
|
||||
self.number = frame
|
||||
self.slave = None
|
||||
self.time = 0
|
||||
self.status = QUEUED
|
||||
self.command = command
|
||||
|
||||
self.log_path = None
|
||||
|
||||
def reset(self, all):
|
||||
@@ -368,10 +375,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
|
||||
|
||||
job_id = self.server.nextJobID()
|
||||
|
||||
job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
|
||||
job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
|
||||
|
||||
for frame in job_info.frames:
|
||||
frame = job.addFrame(frame.number)
|
||||
frame = job.addFrame(frame.number, frame.command)
|
||||
|
||||
self.server.addJob(job)
|
||||
|
||||
@@ -538,6 +545,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
|
||||
frame = job[job_frame]
|
||||
|
||||
if frame:
|
||||
if job.type == netrender.model.JOB_BLENDER:
|
||||
if job_result == DONE:
|
||||
length = int(self.headers['content-length'])
|
||||
buf = self.rfile.read(length)
|
||||
|
||||
@@ -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,6 +99,8 @@ def render_slave(engine, scene):
|
||||
if not os.path.exists(JOB_PREFIX):
|
||||
os.mkdir(JOB_PREFIX)
|
||||
|
||||
|
||||
if job.type == netrender.model.JOB_BLENDER:
|
||||
job_path = job.files[0][0] # data in files have format (path, start, end)
|
||||
main_path, main_file = os.path.split(job_path)
|
||||
|
||||
@@ -111,25 +113,32 @@ def render_slave(engine, scene):
|
||||
print("\t", file_path)
|
||||
testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
|
||||
|
||||
frame_args = []
|
||||
|
||||
for frame in job.frames:
|
||||
print("frame", frame.number)
|
||||
frame_args += ["-f", str(frame.number)]
|
||||
|
||||
# announce log to master
|
||||
logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames])
|
||||
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id})
|
||||
response = conn.getresponse()
|
||||
|
||||
|
||||
first_frame = job.frames[0].number
|
||||
|
||||
# start render
|
||||
start_t = time.time()
|
||||
|
||||
if job.type == netrender.model.JOB_BLENDER:
|
||||
frame_args = []
|
||||
|
||||
for frame in job.frames:
|
||||
print("frame", frame.number)
|
||||
frame_args += ["-f", str(frame.number)]
|
||||
|
||||
val = SetErrorMode()
|
||||
process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
RestoreErrorMode(val)
|
||||
elif job.type == netrender.model.JOB_PROCESS:
|
||||
command = job.frames[0].command
|
||||
val = SetErrorMode()
|
||||
process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
RestoreErrorMode(val)
|
||||
|
||||
headers = {"job-id":job.id, "slave-id":slave_id}
|
||||
|
||||
@@ -155,6 +164,9 @@ def render_slave(engine, scene):
|
||||
if testCancel(conn, job.id, first_frame):
|
||||
cancelled = True
|
||||
|
||||
# read leftovers if needed
|
||||
stdout += process.stdout.read()
|
||||
|
||||
if cancelled:
|
||||
# kill process if needed
|
||||
if process.poll() == None:
|
||||
@@ -182,11 +194,16 @@ def render_slave(engine, scene):
|
||||
headers["job-result"] = str(DONE)
|
||||
for frame in job.frames:
|
||||
headers["job-frame"] = str(frame.number)
|
||||
# send result back to server
|
||||
|
||||
if job.type == netrender.model.JOB_BLENDER:
|
||||
# send image back to server
|
||||
f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
|
||||
conn.request("PUT", "/render", f, headers=headers)
|
||||
f.close()
|
||||
response = conn.getresponse()
|
||||
elif job.type == netrender.model.JOB_PROCESS:
|
||||
conn.request("PUT", "/render", headers=headers)
|
||||
response = conn.getresponse()
|
||||
else:
|
||||
headers["job-result"] = str(ERROR)
|
||||
for frame in job.frames:
|
||||
|
||||
211
release/scripts/modules/autocomplete.py
Normal file
211
release/scripts/modules/autocomplete.py
Normal file
@@ -0,0 +1,211 @@
|
||||
|
||||
|
||||
def execute(bcon):
|
||||
'''
|
||||
This function has been taken from a BGE console autocomp I wrote a while ago
|
||||
the dictionaty bcon is not needed but it means I can copy and paste from the old func
|
||||
which works ok for now.
|
||||
|
||||
'bcon' dictionary keys, set by the caller
|
||||
* 'cursor' - index of the editing character (int)
|
||||
* 'edit_text' - text string for editing (string)
|
||||
* 'scrollback' - text to add to the scrollback, options are added here. (text)
|
||||
* 'namespace' - namespace, (dictionary)
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def is_delimiter(ch):
|
||||
'''
|
||||
For skipping words
|
||||
'''
|
||||
if ch == '_':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def is_delimiter_autocomp(ch):
|
||||
'''
|
||||
When autocompleteing will earch back and
|
||||
'''
|
||||
if ch in '._[] "\'':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def do_autocomp(autocomp_prefix, autocomp_members):
|
||||
'''
|
||||
return text to insert and a list of options
|
||||
'''
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
print("AUTO: '%s'" % autocomp_prefix)
|
||||
print("MEMBERS: '%s'" % str(autocomp_members))
|
||||
|
||||
if not autocomp_prefix:
|
||||
return '', autocomp_members
|
||||
elif len(autocomp_members) > 1:
|
||||
# find a common string between all members after the prefix
|
||||
# 'ge' [getA, getB, getC] --> 'get'
|
||||
|
||||
# get the shortest member
|
||||
min_len = min([len(v) for v in autocomp_members])
|
||||
|
||||
autocomp_prefix_ret = ''
|
||||
|
||||
for i in range(len(autocomp_prefix), min_len):
|
||||
char_soup = set()
|
||||
for v in autocomp_members:
|
||||
char_soup.add(v[i])
|
||||
|
||||
if len(char_soup) > 1:
|
||||
break
|
||||
else:
|
||||
autocomp_prefix_ret += char_soup.pop()
|
||||
|
||||
return autocomp_prefix_ret, autocomp_members
|
||||
elif len(autocomp_members) == 1:
|
||||
if autocomp_prefix == autocomp_members[0]:
|
||||
# the variable matched the prefix exactly
|
||||
# add a '.' so you can quickly continue.
|
||||
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
|
||||
return '.', []
|
||||
else:
|
||||
# finish off the of the word word
|
||||
return autocomp_members[0][len(autocomp_prefix):], []
|
||||
else:
|
||||
return '', []
|
||||
|
||||
|
||||
def BCon_PrevChar(bcon):
|
||||
cursor = bcon['cursor']-1
|
||||
if cursor<0:
|
||||
return None
|
||||
|
||||
try:
|
||||
return bcon['edit_text'][cursor]
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def BCon_NextChar(bcon):
|
||||
try:
|
||||
return bcon['edit_text'][bcon['cursor']]
|
||||
except:
|
||||
return None
|
||||
|
||||
def BCon_cursorLeft(bcon):
|
||||
bcon['cursor'] -= 1
|
||||
if bcon['cursor'] < 0:
|
||||
bcon['cursor'] = 0
|
||||
|
||||
def BCon_cursorRight(bcon):
|
||||
bcon['cursor'] += 1
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
|
||||
def BCon_AddScrollback(bcon, text):
|
||||
|
||||
bcon['scrollback'] = bcon['scrollback'] + text
|
||||
|
||||
|
||||
def BCon_cursorInsertChar(bcon, ch):
|
||||
if bcon['cursor']==0:
|
||||
bcon['edit_text'] = ch + bcon['edit_text']
|
||||
elif bcon['cursor']==len(bcon['edit_text']):
|
||||
bcon['edit_text'] = bcon['edit_text'] + ch
|
||||
else:
|
||||
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
|
||||
|
||||
bcon['cursor']
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
|
||||
TEMP_NAME = '___tempname___'
|
||||
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and (not is_delimiter(ch)):
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
if ch != None:
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
#print (cursor_orig, bcon['cursor'])
|
||||
|
||||
cursor_base = bcon['cursor']
|
||||
|
||||
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
|
||||
|
||||
print("PREFIX:'%s'" % autocomp_prefix)
|
||||
|
||||
# Get the previous word
|
||||
if BCon_PrevChar(bcon)=='.':
|
||||
BCon_cursorLeft(bcon)
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and is_delimiter_autocomp(ch)==False:
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
cursor_new = bcon['cursor']
|
||||
|
||||
if ch != None:
|
||||
cursor_new+=1
|
||||
|
||||
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
|
||||
print("AUTOCOMP EVAL: '%s'" % pytxt)
|
||||
#try:
|
||||
if pytxt:
|
||||
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
|
||||
# print val
|
||||
else: ##except:
|
||||
val = None
|
||||
|
||||
try:
|
||||
val = bcon['namespace'][TEMP_NAME]
|
||||
del bcon['namespace'][TEMP_NAME]
|
||||
except:
|
||||
val = None
|
||||
|
||||
if val:
|
||||
autocomp_members = dir(val)
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
del val
|
||||
|
||||
else:
|
||||
# Autocomp global namespace
|
||||
autocomp_members = bcon['namespace'].keys()
|
||||
|
||||
if autocomp_prefix:
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
12
release/scripts/modules/bpy_sys.py
Normal file
12
release/scripts/modules/bpy_sys.py
Normal file
@@ -0,0 +1,12 @@
|
||||
import bpy
|
||||
import os
|
||||
|
||||
def expandpath(path):
|
||||
if path.startswith("//"):
|
||||
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
|
||||
|
||||
return path
|
||||
|
||||
import types
|
||||
bpy.sys = types.ModuleType("bpy.sys")
|
||||
bpy.sys.expandpath = expandpath
|
||||
@@ -48,7 +48,7 @@ class BONE_PT_transform(BoneButtonsPanel):
|
||||
else:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
layout.itemR(pchan, "rotation_mode")
|
||||
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
@@ -57,20 +57,18 @@ class BONE_PT_transform(BoneButtonsPanel):
|
||||
|
||||
col = row.column()
|
||||
if pchan.rotation_mode == 'QUATERNION':
|
||||
col.itemR(pchan, "rotation", text="Rotation")
|
||||
col.itemR(pchan, "rotation_quaternion", text="Rotation")
|
||||
elif pchan.rotation_mode == 'AXIS_ANGLE':
|
||||
col.itemL(text="Rotation")
|
||||
col.itemR(pchan, "rotation_angle", text="Angle")
|
||||
col.itemR(pchan, "rotation_axis", text="Axis")
|
||||
#col.itemL(text="Rotation")
|
||||
#col.itemR(pchan, "rotation_angle", text="Angle")
|
||||
#col.itemR(pchan, "rotation_axis", text="Axis")
|
||||
col.itemR(pchan, "rotation_axis_angle", text="Rotation")
|
||||
else:
|
||||
col.itemR(pchan, "euler_rotation", text="Rotation")
|
||||
col.itemR(pchan, "rotation_euler", text="Rotation")
|
||||
|
||||
row.column().itemR(pchan, "scale")
|
||||
|
||||
if pchan.rotation_mode == 'QUATERNION':
|
||||
col = layout.column(align=True)
|
||||
col.itemL(text="Euler:")
|
||||
col.row().itemR(pchan, "euler_rotation", text="")
|
||||
layout.itemR(pchan, "rotation_mode")
|
||||
|
||||
class BONE_PT_transform_locks(BoneButtonsPanel):
|
||||
__label__ = "Transform Locks"
|
||||
@@ -102,8 +100,8 @@ class BONE_PT_transform_locks(BoneButtonsPanel):
|
||||
|
||||
row.column().itemR(pchan, "lock_scale")
|
||||
|
||||
class BONE_PT_bone(BoneButtonsPanel):
|
||||
__label__ = "Bone"
|
||||
class BONE_PT_relations(BoneButtonsPanel):
|
||||
__label__ = "Relations"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -120,6 +118,16 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Layers:")
|
||||
col.itemR(bone, "layer", text="")
|
||||
|
||||
col.itemS()
|
||||
|
||||
if ob and pchan:
|
||||
col.itemL(text="Bone Group:")
|
||||
col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Parent:")
|
||||
if context.bone:
|
||||
@@ -127,119 +135,46 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
else:
|
||||
col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
|
||||
|
||||
row = col.row()
|
||||
row.active = bone.parent != None
|
||||
row.itemR(bone, "connected")
|
||||
sub = col.column()
|
||||
sub.active = bone.parent != None
|
||||
sub.itemR(bone, "connected")
|
||||
sub.itemR(bone, "hinge", text="Inherit Rotation")
|
||||
sub.itemR(bone, "inherit_scale", text="Inherit Scale")
|
||||
|
||||
col.itemL(text="Layers:")
|
||||
col.itemR(bone, "layer", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Inherit:")
|
||||
col.itemR(bone, "hinge", text="Rotation")
|
||||
col.itemR(bone, "inherit_scale", text="Scale")
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(bone, "draw_wire", text="Wireframe")
|
||||
col.itemR(bone, "hidden", text="Hide")
|
||||
|
||||
if ob and pchan:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Bone Group:")
|
||||
col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Custom Shape:")
|
||||
col.itemR(pchan, "custom_shape", text="")
|
||||
|
||||
class BONE_PT_inverse_kinematics(BoneButtonsPanel):
|
||||
__label__ = "Inverse Kinematics"
|
||||
__default_closed__ = True
|
||||
class BONE_PT_display(BoneButtonsPanel):
|
||||
__label__ = "Display"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
|
||||
if ob and context.bone:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
return pchan.has_ik
|
||||
|
||||
return False
|
||||
return context.bone
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
arm = context.armature
|
||||
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
pchan = None
|
||||
else:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(ob.pose, "ik_solver")
|
||||
if ob and pchan:
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_x", text="X")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_x
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_x", text="Limit")
|
||||
row.active = pchan.ik_dof_x
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_x", text="")
|
||||
row.itemR(pchan, "ik_max_x", text="")
|
||||
row.active = pchan.ik_dof_x and pchan.ik_limit_x
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_y", text="Y")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_y
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_y", text="Limit")
|
||||
row.active = pchan.ik_dof_y
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_y", text="")
|
||||
row.itemR(pchan, "ik_max_y", text="")
|
||||
row.active = pchan.ik_dof_y and pchan.ik_limit_y
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_z", text="Z")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_z
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_z", text="Limit")
|
||||
row.active = pchan.ik_dof_z
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_z", text="")
|
||||
row.itemR(pchan, "ik_max_z", text="")
|
||||
row.active = pchan.ik_dof_z and pchan.ik_limit_z
|
||||
split = layout.split()
|
||||
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
|
||||
split.itemL()
|
||||
|
||||
if ob.pose.ik_solver == "ITASC":
|
||||
layout.itemL(text="Joint constraint:")
|
||||
split = layout.split(percentage=0.3)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_rot_control", text="Rotation")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
|
||||
row.active = pchan.ik_rot_control
|
||||
# not supported yet
|
||||
#split = layout.split(percentage=0.3)
|
||||
#row = split.row()
|
||||
#row.itemR(pchan, "ik_lin_control", text="Size")
|
||||
#row = split.row()
|
||||
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
|
||||
#row.active = pchan.ik_lin_control
|
||||
col = split.column()
|
||||
|
||||
col.itemR(bone, "draw_wire", text="Wireframe")
|
||||
col.itemR(bone, "hidden", text="Hide")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Custom Shape:")
|
||||
col.itemR(pchan, "custom_shape", text="")
|
||||
|
||||
|
||||
class BONE_PT_deform(BoneButtonsPanel):
|
||||
__label__ = "Deform"
|
||||
@@ -289,65 +224,10 @@ class BONE_PT_deform(BoneButtonsPanel):
|
||||
col.itemL(text="Offset:")
|
||||
col.itemR(bone, "cyclic_offset")
|
||||
|
||||
class BONE_PT_iksolver_itasc(BoneButtonsPanel):
|
||||
__idname__ = "BONE_PT_iksolver_itasc"
|
||||
__label__ = "iTaSC parameters"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
|
||||
if ob and context.bone:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
itasc = ob.pose.ik_param
|
||||
|
||||
layout.row().itemR(itasc, "simulation")
|
||||
if itasc.simulation:
|
||||
split = layout.split()
|
||||
row = split.row()
|
||||
row.itemR(itasc, "reiteration")
|
||||
row = split.row()
|
||||
if itasc.reiteration:
|
||||
itasc.initial_reiteration = True
|
||||
row.itemR(itasc, "initial_reiteration")
|
||||
row.active = not itasc.reiteration
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(itasc, "precision")
|
||||
flow.itemR(itasc, "num_iter")
|
||||
flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
|
||||
|
||||
if itasc.simulation:
|
||||
layout.itemR(itasc, "auto_step")
|
||||
row = layout.row()
|
||||
if itasc.auto_step:
|
||||
row.itemR(itasc, "min_step")
|
||||
row.itemR(itasc, "max_step")
|
||||
else:
|
||||
row.itemR(itasc, "num_step")
|
||||
|
||||
layout.itemR(itasc, "solver")
|
||||
if itasc.simulation:
|
||||
layout.itemR(itasc, "feedback")
|
||||
layout.itemR(itasc, "max_velocity")
|
||||
if itasc.solver == "DLS":
|
||||
row = layout.row()
|
||||
row.itemR(itasc, "dampmax")
|
||||
row.itemR(itasc, "dampeps")
|
||||
|
||||
bpy.types.register(BONE_PT_context_bone)
|
||||
bpy.types.register(BONE_PT_transform)
|
||||
bpy.types.register(BONE_PT_transform_locks)
|
||||
bpy.types.register(BONE_PT_bone)
|
||||
bpy.types.register(BONE_PT_relations)
|
||||
bpy.types.register(BONE_PT_display)
|
||||
bpy.types.register(BONE_PT_deform)
|
||||
bpy.types.register(BONE_PT_inverse_kinematics)
|
||||
bpy.types.register(BONE_PT_iksolver_itasc)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -610,6 +610,23 @@ class VolumeButtonsPanel(bpy.types.Panel):
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
class MATERIAL_PT_volume_density(VolumeButtonsPanel):
|
||||
__label__ = "Density"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
vol = context.material.volume
|
||||
|
||||
split = layout.split()
|
||||
row = split.row()
|
||||
row.itemR(vol, "density")
|
||||
row.itemR(vol, "density_scale")
|
||||
|
||||
|
||||
class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
|
||||
__label__ = "Shading"
|
||||
__default_closed__ = False
|
||||
@@ -620,22 +637,23 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
|
||||
|
||||
vol = context.material.volume
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(vol, "density")
|
||||
row.itemR(vol, "scattering")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(vol, "absorption")
|
||||
col.itemR(vol, "absorption_color", text="")
|
||||
col.itemR(vol, "scattering")
|
||||
col.itemR(vol, "asymmetry")
|
||||
col.itemR(vol, "transmission_color")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(vol, "emission")
|
||||
col.itemR(vol, "emission_color", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "emission")
|
||||
sub.itemR(vol, "emission_color", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "reflection")
|
||||
sub.itemR(vol, "reflection_color", text="")
|
||||
|
||||
class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
|
||||
__label__ = "Scattering"
|
||||
class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
|
||||
__label__ = "Lighting"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
@@ -648,12 +666,19 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
|
||||
|
||||
col = split.column()
|
||||
col.itemR(vol, "scattering_mode", text="")
|
||||
|
||||
col = split.column()
|
||||
|
||||
if vol.scattering_mode == 'SINGLE_SCATTERING':
|
||||
col.itemR(vol, "light_cache")
|
||||
sub = col.column()
|
||||
sub.active = vol.light_cache
|
||||
sub.itemR(vol, "cache_resolution")
|
||||
elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
|
||||
sub = col.column()
|
||||
sub.enabled = True
|
||||
sub.active = False
|
||||
sub.itemR(vol, "light_cache")
|
||||
col.itemR(vol, "cache_resolution")
|
||||
|
||||
sub = col.column(align=True)
|
||||
@@ -661,11 +686,6 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
|
||||
sub.itemR(vol, "ms_spread")
|
||||
sub.itemR(vol, "ms_intensity")
|
||||
|
||||
col = split.column()
|
||||
# col.itemL(text="Anisotropic Scattering:")
|
||||
col.itemR(vol, "phase_function", text="")
|
||||
if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
|
||||
col.itemR(vol, "asymmetry")
|
||||
|
||||
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
|
||||
__label__= "Transparency"
|
||||
@@ -693,16 +713,15 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
|
||||
col = split.column()
|
||||
col.itemL(text="Step Calculation:")
|
||||
col.itemR(vol, "step_calculation", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "step_size")
|
||||
sub.itemR(vol, "shading_step_size")
|
||||
col = col.column(align=True)
|
||||
col.itemR(vol, "step_size")
|
||||
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(vol, "depth_cutoff")
|
||||
col.itemR(vol, "density_scale")
|
||||
|
||||
bpy.types.register(MATERIAL_PT_volume_density)
|
||||
bpy.types.register(MATERIAL_PT_volume_shading)
|
||||
bpy.types.register(MATERIAL_PT_volume_scattering)
|
||||
bpy.types.register(MATERIAL_PT_volume_lighting)
|
||||
bpy.types.register(MATERIAL_PT_volume_transp)
|
||||
bpy.types.register(MATERIAL_PT_volume_integration)
|
||||
|
||||
@@ -26,11 +26,50 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
|
||||
|
||||
ob = context.object
|
||||
|
||||
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.column().itemR(ob, "location")
|
||||
row.column().itemR(ob, "rotation")
|
||||
if ob.rotation_mode == 'QUATERNION':
|
||||
row.column().itemR(ob, "rotation_quaternion", text="Rotation")
|
||||
elif ob.rotation_mode == 'AXIS_ANGLE':
|
||||
#row.column().itemL(text="Rotation")
|
||||
#row.column().itemR(pchan, "rotation_angle", text="Angle")
|
||||
#row.column().itemR(pchan, "rotation_axis", text="Axis")
|
||||
row.column().itemR(ob, "rotation_axis_angle", text="Rotation")
|
||||
else:
|
||||
row.column().itemR(ob, "rotation_euler", text="Rotation")
|
||||
|
||||
row.column().itemR(ob, "scale")
|
||||
|
||||
layout.itemR(ob, "rotation_mode")
|
||||
|
||||
class OBJECT_PT_transform_locks(ObjectButtonsPanel):
|
||||
__label__ = "Transform Locks"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemR(ob, "lock_location")
|
||||
|
||||
col = row.column()
|
||||
if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
|
||||
col.itemR(ob, "lock_rotations_4d", text="Lock Rotation")
|
||||
if ob.lock_rotations_4d:
|
||||
col.itemR(ob, "lock_rotation_w", text="W")
|
||||
col.itemR(ob, "lock_rotation", text="")
|
||||
else:
|
||||
col.itemR(ob, "lock_rotation", text="Rotation")
|
||||
|
||||
row.column().itemR(ob, "lock_scale")
|
||||
|
||||
class OBJECT_PT_relations(ObjectButtonsPanel):
|
||||
__label__ = "Relations"
|
||||
|
||||
@@ -178,6 +217,7 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
|
||||
|
||||
bpy.types.register(OBJECT_PT_context_object)
|
||||
bpy.types.register(OBJECT_PT_transform)
|
||||
bpy.types.register(OBJECT_PT_transform_locks)
|
||||
bpy.types.register(OBJECT_PT_relations)
|
||||
bpy.types.register(OBJECT_PT_groups)
|
||||
bpy.types.register(OBJECT_PT_display)
|
||||
|
||||
@@ -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'
|
||||
@@ -244,24 +183,23 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
col.itemL(text="Gravity:")
|
||||
col.itemR(cloth, "gravity", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Material:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
sub.itemR(cloth, "internal_friction", slider="True")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "spring_damping", text="Spring")
|
||||
sub.itemR(cloth, "air_damping", text="Air")
|
||||
|
||||
layout.itemR(cloth, "internal_friction", slider="True")
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
|
||||
class PARTICLE_PT_cache(ParticleButtonsPanel):
|
||||
__label__ = "Cache"
|
||||
@@ -385,9 +323,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
|
||||
sub.itemR(part, "brownian_factor")
|
||||
sub.itemR(part, "drag_factor", slider=True)
|
||||
sub.itemR(part, "damp_factor", slider=True)
|
||||
sub.itemR(part, "integrator")
|
||||
sub = split.column()
|
||||
sub.itemR(part, "acceleration")
|
||||
sub.itemR(part, "size_deflect")
|
||||
sub.itemR(part, "die_on_collision")
|
||||
sub.itemR(part, "integrator")
|
||||
sub.itemR(part, "time_tweak")
|
||||
|
||||
elif part.physics_type == 'KEYED':
|
||||
split = layout.split()
|
||||
@@ -445,14 +385,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Misc:")
|
||||
col.itemR(part, "gravity")
|
||||
col.itemR(boids, "banking", slider=True)
|
||||
col.itemR(boids, "height", slider=True)
|
||||
|
||||
if part.physics_type=='NEWTON':
|
||||
sub.itemR(part, "size_deflect")
|
||||
sub.itemR(part, "die_on_collision")
|
||||
elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
|
||||
if part.physics_type=='KEYED' or part.physics_type=='BOIDS':
|
||||
if part.physics_type=='BOIDS':
|
||||
layout.itemL(text="Relations:")
|
||||
|
||||
@@ -505,18 +441,18 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
|
||||
boids = context.particle_system.settings.boids
|
||||
layout = self.layout
|
||||
|
||||
layout.enabled = particle_panel_enabled(psys)
|
||||
layout.enabled = particle_panel_enabled(context.particle_system)
|
||||
|
||||
# Currently boids can only use the first state so these are commented out for now.
|
||||
#row = layout.row()
|
||||
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
|
||||
#col = row.row()
|
||||
#subrow = col.row(align=True)
|
||||
#subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
|
||||
#subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
|
||||
#subrow.itemO("boid.state_add", icon='ICON_ZOOMIN', text="")
|
||||
#subrow.itemO("boid.state_del", icon='ICON_ZOOMOUT', text="")
|
||||
#subrow = row.row(align=True)
|
||||
#subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
|
||||
#subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
#subrow.itemO("boid.state_move_up", icon='VICON_MOVE_UP', text="")
|
||||
#subrow.itemO("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
state = boids.active_boid_state
|
||||
|
||||
@@ -535,12 +471,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
|
||||
col = row.column()
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
|
||||
subcol.item_menu_enumO("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("boid.rule_del", icon='ICON_ZOOMOUT', text="")
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
|
||||
subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
subcol.itemO("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
|
||||
subcol.itemO("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
rule = state.active_boid_rule
|
||||
|
||||
@@ -857,30 +793,41 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
|
||||
sub = split.column()
|
||||
sub.itemR(part, "kink_shape", slider=True)
|
||||
|
||||
class PARTICLE_PT_effectors(ParticleButtonsPanel):
|
||||
__label__ = "Effectors"
|
||||
class PARTICLE_PT_field_weights(ParticleButtonsPanel):
|
||||
__label__ = "Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
part = context.particle_system.settings
|
||||
effector_weights_ui(self, part.effector_weights)
|
||||
|
||||
if part.type == 'HAIR':
|
||||
self.layout.itemR(part.effector_weights, "do_growing_hair")
|
||||
|
||||
class PARTICLE_PT_force_fields(ParticleButtonsPanel):
|
||||
__label__ = "Force Field Settings"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
part = context.particle_system.settings
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
layout.itemR(part, "self_effect")
|
||||
|
||||
layout.itemR(part, "effector_group")
|
||||
split = layout.split(percentage=0.2)
|
||||
split.itemL(text="Type 1:")
|
||||
split.itemR(part.force_field_1, "type",text="")
|
||||
basic_force_field_settings_ui(self, part.force_field_1)
|
||||
basic_force_field_falloff_ui(self, part.force_field_1)
|
||||
|
||||
layout.itemR(part, "eweight_all", slider=True)
|
||||
if part.force_field_1.type != 'NONE':
|
||||
layout.itemL(text="")
|
||||
|
||||
layout.itemS()
|
||||
layout.itemR(part, "eweight_spherical", slider=True)
|
||||
layout.itemR(part, "eweight_vortex", slider=True)
|
||||
layout.itemR(part, "eweight_magnetic", slider=True)
|
||||
layout.itemR(part, "eweight_wind", slider=True)
|
||||
layout.itemR(part, "eweight_curveguide", slider=True)
|
||||
layout.itemR(part, "eweight_texture", slider=True)
|
||||
layout.itemR(part, "eweight_harmonic", slider=True)
|
||||
layout.itemR(part, "eweight_charge", slider=True)
|
||||
layout.itemR(part, "eweight_lennardjones", slider=True)
|
||||
split = layout.split(percentage=0.2)
|
||||
split.itemL(text="Type 2:")
|
||||
split.itemR(part.force_field_2, "type",text="")
|
||||
basic_force_field_settings_ui(self, part.force_field_2)
|
||||
basic_force_field_falloff_ui(self, part.force_field_2)
|
||||
|
||||
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
|
||||
__label__ = "Vertexgroups"
|
||||
@@ -957,5 +904,6 @@ bpy.types.register(PARTICLE_PT_boidbrain)
|
||||
bpy.types.register(PARTICLE_PT_render)
|
||||
bpy.types.register(PARTICLE_PT_draw)
|
||||
bpy.types.register(PARTICLE_PT_children)
|
||||
bpy.types.register(PARTICLE_PT_effectors)
|
||||
bpy.types.register(PARTICLE_PT_field_weights)
|
||||
bpy.types.register(PARTICLE_PT_force_fields)
|
||||
bpy.types.register(PARTICLE_PT_vertexgroups)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_particle import point_cache_ui
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
|
||||
def cloth_panel_enabled(md):
|
||||
return md.point_cache.baked==False
|
||||
@@ -49,10 +50,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
col.itemL(text="Gravity:")
|
||||
col.itemR(cloth, "gravity", text="")
|
||||
col.itemL(text="Material:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "structural_stiffness", text="Structural")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
|
||||
col.itemR(cloth, "pin_cloth", text="Pin")
|
||||
sub = col.column(align=True)
|
||||
@@ -61,18 +63,18 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
|
||||
sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Presets...")
|
||||
col.itemL(text="TODO!")
|
||||
col.itemL(text="Material:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "structural_stiffness", text="Structural")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "spring_damping", text="Spring")
|
||||
sub.itemR(cloth, "air_damping", text="Air")
|
||||
|
||||
col.itemL(text="Presets...")
|
||||
col.itemL(text="TODO!")
|
||||
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
|
||||
# Disabled for now
|
||||
"""
|
||||
if cloth.mass_vertex_group:
|
||||
@@ -166,7 +168,19 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
|
||||
sub.itemR(cloth, "bending_stiffness_max", text="Max")
|
||||
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel):
|
||||
__label__ = "Cloth Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth)
|
||||
|
||||
def draw(self, context):
|
||||
cloth = context.cloth.settings
|
||||
effector_weights_ui(self, cloth.effector_weights)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_cloth)
|
||||
bpy.types.register(PHYSICS_PT_cloth_cache)
|
||||
bpy.types.register(PHYSICS_PT_cloth_collision)
|
||||
bpy.types.register(PHYSICS_PT_cloth_stiffness)
|
||||
bpy.types.register(PHYSICS_PT_cloth_field_weights)
|
||||
|
||||
153
release/scripts/ui/buttons_physics_common.py
Normal file
153
release/scripts/ui/buttons_physics_common.py
Normal file
@@ -0,0 +1,153 @@
|
||||
import bpy
|
||||
|
||||
def point_cache_ui(self, cache, enabled, particles, smoke):
|
||||
layout = self.layout
|
||||
layout.set_context_pointer("PointCache", cache)
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
|
||||
col = row.column(align=True)
|
||||
col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="File Name:")
|
||||
if particles:
|
||||
row.itemR(cache, "external")
|
||||
|
||||
if cache.external:
|
||||
split = layout.split(percentage=0.80)
|
||||
split.itemR(cache, "name", text="")
|
||||
split.itemR(cache, "index", text="")
|
||||
|
||||
layout.itemL(text="File Path:")
|
||||
layout.itemR(cache, "filepath", text="")
|
||||
|
||||
layout.itemL(text=cache.info)
|
||||
else:
|
||||
layout.itemR(cache, "name", text="")
|
||||
|
||||
if not particles:
|
||||
row = layout.row()
|
||||
row.enabled = enabled
|
||||
row.itemR(cache, "start_frame")
|
||||
row.itemR(cache, "end_frame")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
if cache.baked == True:
|
||||
row.itemO("ptcache.free_bake", text="Free Bake")
|
||||
else:
|
||||
row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
|
||||
|
||||
sub = row.row()
|
||||
sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
|
||||
sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
|
||||
|
||||
row = layout.row()
|
||||
row.enabled = enabled
|
||||
row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
|
||||
if not smoke:
|
||||
row.itemR(cache, "step");
|
||||
|
||||
if not smoke:
|
||||
row = layout.row()
|
||||
sub = row.row()
|
||||
sub.enabled = enabled
|
||||
sub.itemR(cache, "quick_cache")
|
||||
row.itemR(cache, "disk_cache")
|
||||
|
||||
layout.itemL(text=cache.info)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
|
||||
row.itemO("ptcache.free_bake_all", text="Free All Bakes")
|
||||
layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
|
||||
|
||||
def effector_weights_ui(self, weights):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemR(weights, "group")
|
||||
|
||||
split = layout.split()
|
||||
split.itemR(weights, "gravity", slider=True)
|
||||
split.itemR(weights, "all", slider=True)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(weights, "spherical", slider=True)
|
||||
flow.itemR(weights, "vortex", slider=True)
|
||||
flow.itemR(weights, "magnetic", slider=True)
|
||||
flow.itemR(weights, "wind", slider=True)
|
||||
flow.itemR(weights, "curveguide", slider=True)
|
||||
flow.itemR(weights, "texture", slider=True)
|
||||
flow.itemR(weights, "harmonic", slider=True)
|
||||
flow.itemR(weights, "charge", slider=True)
|
||||
flow.itemR(weights, "lennardjones", slider=True)
|
||||
flow.itemR(weights, "turbulence", slider=True)
|
||||
flow.itemR(weights, "drag", slider=True)
|
||||
flow.itemR(weights, "boid", slider=True)
|
||||
|
||||
def basic_force_field_settings_ui(self, field):
|
||||
layout = self.layout
|
||||
split = layout.split()
|
||||
|
||||
if not field or field.type == 'NONE':
|
||||
return
|
||||
|
||||
col = split.column()
|
||||
|
||||
if field.type == 'DRAG':
|
||||
col.itemR(field, "linear_drag", text="Linear")
|
||||
else:
|
||||
col.itemR(field, "strength")
|
||||
|
||||
if field.type == 'TURBULENCE':
|
||||
col.itemR(field, "size")
|
||||
col.itemR(field, "flow")
|
||||
elif field.type == 'HARMONIC':
|
||||
col.itemR(field, "harmonic_damping", text="Damping")
|
||||
elif field.type == 'VORTEX' and field.shape == 'PLANE':
|
||||
col.itemR(field, "inflow")
|
||||
elif field.type == 'DRAG':
|
||||
col.itemR(field, "quadratic_drag", text="Quadratic")
|
||||
else:
|
||||
col.itemR(field, "flow")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "noise")
|
||||
col.itemR(field, "seed")
|
||||
if field.type == 'TURBULENCE':
|
||||
col.itemR(field, "global_coordinates", text="Global")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Effect point:")
|
||||
row.itemR(field, "do_location")
|
||||
row.itemR(field, "do_rotation")
|
||||
|
||||
|
||||
def basic_force_field_falloff_ui(self, field):
|
||||
layout = self.layout
|
||||
split = layout.split(percentage=0.35)
|
||||
|
||||
if not field or field.type == 'NONE':
|
||||
return
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "z_direction", text="")
|
||||
col.itemR(field, "use_min_distance", text="Use Minimum")
|
||||
col.itemR(field, "use_max_distance", text="Use Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "falloff_power", text="Power")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_min_distance
|
||||
sub.itemR(field, "minimum_distance", text="Distance")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_max_distance
|
||||
sub.itemR(field, "maximum_distance", text="Distance")
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import basic_force_field_settings_ui
|
||||
from buttons_physics_common import basic_force_field_falloff_ui
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
@@ -12,7 +15,6 @@ class PhysicButtonsPanel(bpy.types.Panel):
|
||||
|
||||
class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
__label__ = "Force Fields"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -20,53 +22,48 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
ob = context.object
|
||||
field = ob.field
|
||||
|
||||
#layout.active = field.enabled
|
||||
|
||||
split = layout.split(percentage=0.2)
|
||||
|
||||
split.itemL(text="Type:")
|
||||
split.itemR(field, "type",text="")
|
||||
|
||||
if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
|
||||
split = layout.split(percentage=0.2)
|
||||
#split = layout.row()
|
||||
split.itemL(text="Shape:")
|
||||
split.itemR(field, "shape", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if field.type == 'GUIDE':
|
||||
layout.itemR(field, "guide_path_add")
|
||||
|
||||
elif field.type == 'WIND':
|
||||
split.itemR(field, "strength")
|
||||
if field.type == 'NONE':
|
||||
return # nothing to draw
|
||||
elif field.type == 'GUIDE':
|
||||
col = split.column()
|
||||
col.itemR(field, "guide_minimum")
|
||||
col.itemR(field, "guide_free")
|
||||
col.itemR(field, "falloff_power")
|
||||
col.itemR(field, "guide_path_add")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "noise")
|
||||
col.itemR(field, "seed")
|
||||
col.itemL(text="Clumping:")
|
||||
col.itemR(field, "guide_clump_amount")
|
||||
col.itemR(field, "guide_clump_shape")
|
||||
|
||||
elif field.type == 'VORTEX':
|
||||
split.itemR(field, "strength")
|
||||
split.itemL()
|
||||
row = layout.row()
|
||||
row.itemR(field, "use_max_distance")
|
||||
sub = row.row()
|
||||
sub.active = field.use_max_distance
|
||||
sub.itemR(field, "maximum_distance")
|
||||
|
||||
elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
|
||||
split.itemR(field, "strength")
|
||||
layout.itemS()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "planar")
|
||||
col.itemR(field, "surface")
|
||||
|
||||
elif field.type == 'BOID':
|
||||
split.itemR(field, "strength")
|
||||
split.itemR(field, "surface")
|
||||
|
||||
elif field.type == 'MAGNET':
|
||||
split.itemR(field, "strength")
|
||||
split.itemR(field, "planar")
|
||||
|
||||
elif field.type == 'HARMONIC':
|
||||
col = split.column()
|
||||
col.itemR(field, "strength")
|
||||
col.itemR(field, "harmonic_damping", text="Damping")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "planar")
|
||||
col.itemR(field, "surface")
|
||||
layout.itemR(field, "guide_kink_type")
|
||||
if (field.guide_kink_type != "NONE"):
|
||||
layout.itemR(field, "guide_kink_axis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(field, "guide_kink_frequency")
|
||||
flow.itemR(field, "guide_kink_shape")
|
||||
flow.itemR(field, "guide_kink_amplitude")
|
||||
elif field.type == 'TEXTURE':
|
||||
col = split.column()
|
||||
col.itemR(field, "strength")
|
||||
@@ -78,29 +75,15 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
col.itemR(field, "use_coordinates")
|
||||
col.itemR(field, "root_coordinates")
|
||||
col.itemR(field, "force_2d")
|
||||
else :
|
||||
basic_force_field_settings_ui(self, field)
|
||||
|
||||
if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'):
|
||||
if field.type not in ('NONE', 'GUIDE'):
|
||||
|
||||
layout.itemL(text="Falloff:")
|
||||
layout.itemR(field, "falloff_type", expand=True)
|
||||
|
||||
split = layout.split(percentage=0.35)
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "positive_z", text="Positive Z")
|
||||
col.itemR(field, "use_min_distance", text="Use Minimum")
|
||||
col.itemR(field, "use_max_distance", text="Use Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "falloff_power", text="Power")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_min_distance
|
||||
sub.itemR(field, "minimum_distance", text="Distance")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_max_distance
|
||||
sub.itemR(field, "maximum_distance", text="Distance")
|
||||
basic_force_field_falloff_ui(self, field)
|
||||
|
||||
if field.falloff_type == 'CONE':
|
||||
layout.itemS()
|
||||
@@ -144,20 +127,9 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
sub.active = field.use_radial_max
|
||||
sub.itemR(field, "radial_maximum", text="Distance")
|
||||
|
||||
#if ob.type in 'CURVE':
|
||||
#if field.type == 'GUIDE':
|
||||
#colsub = col.column(align=True)
|
||||
|
||||
#if field.type != 'NONE':
|
||||
#layout.itemR(field, "strength")
|
||||
|
||||
#if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"):
|
||||
#if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'):
|
||||
#layout.itemR(field, "surface")
|
||||
|
||||
class PHYSICS_PT_collision(PhysicButtonsPanel):
|
||||
__label__ = "Collision"
|
||||
__default_closed__ = True
|
||||
#__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
@@ -182,16 +154,18 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
|
||||
#row.itemR(md, "render", text="")
|
||||
#row.itemR(md, "realtime", text="")
|
||||
|
||||
settings = md.settings
|
||||
coll = md.settings
|
||||
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add")
|
||||
split.itemL()
|
||||
|
||||
settings = None
|
||||
coll = None
|
||||
|
||||
if coll:
|
||||
settings = context.object.collision
|
||||
|
||||
if settings:
|
||||
layout.active = settings.enabled
|
||||
|
||||
split = layout.split()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_particle import point_cache_ui
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
|
||||
def softbody_panel_enabled(md):
|
||||
return md.point_cache.baked==False
|
||||
@@ -55,7 +56,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Simulation:")
|
||||
col.itemR(softbody, "gravity")
|
||||
col.itemR(softbody, "speed")
|
||||
|
||||
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
|
||||
@@ -223,9 +223,22 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
|
||||
layout.itemL(text="Diagnostics:")
|
||||
layout.itemR(softbody, "diagnose")
|
||||
|
||||
class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body)
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
effector_weights_ui(self, softbody.effector_weights)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_softbody)
|
||||
bpy.types.register(PHYSICS_PT_softbody_cache)
|
||||
bpy.types.register(PHYSICS_PT_softbody_goal)
|
||||
bpy.types.register(PHYSICS_PT_softbody_edge)
|
||||
bpy.types.register(PHYSICS_PT_softbody_collision)
|
||||
bpy.types.register(PHYSICS_PT_softbody_solver)
|
||||
bpy.types.register(PHYSICS_PT_softbody_field_weights)
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class SceneButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "scene"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.scene != None)
|
||||
|
||||
class RenderButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
@@ -254,12 +262,11 @@ class SCENE_PT_output(RenderButtonsPanel):
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.itemL(text="Depth:")
|
||||
col.row().itemR(rd, "jpeg_depth", expand=True)
|
||||
col.row().itemR(rd, "jpeg2k_depth", expand=True)
|
||||
|
||||
col = split.column()
|
||||
col.itemR(rd, "jpeg_preset", text="")
|
||||
col.itemR(rd, "jpeg_ycc")
|
||||
col.itemR(rd, "exr_preview")
|
||||
col.itemR(rd, "jpeg2k_preset", text="")
|
||||
col.itemR(rd, "jpeg2k_ycc")
|
||||
|
||||
elif rd.file_format in ('CINEON', 'DPX'):
|
||||
split = layout.split()
|
||||
@@ -452,6 +459,101 @@ class SCENE_PT_unit(RenderButtonsPanel):
|
||||
row.itemR(unit, "scale_length", text="Scale")
|
||||
row.itemR(unit, "use_separate")
|
||||
|
||||
class SCENE_PT_keying_sets(SceneButtonsPanel):
|
||||
__label__ = "Keying Sets"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
ks = scene.active_keying_set
|
||||
if ks:
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemR(ks, "name")
|
||||
col.itemR(ks, "absolute")
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Keyframing Settings:")
|
||||
col.itemR(ks, "insertkey_needed", text="Needed")
|
||||
col.itemR(ks, "insertkey_visual", text="Visual")
|
||||
|
||||
class SCENE_PT_keying_set_paths(SceneButtonsPanel):
|
||||
__label__ = "Active Keying Set"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.scene != None) and (context.scene.active_keying_set != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
ks = scene.active_keying_set
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.template_list(ks, "paths", ks, "active_path_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
ksp = ks.active_path
|
||||
if ksp:
|
||||
col = layout.column()
|
||||
col.itemL(text="Target:")
|
||||
col.itemR(ksp, "id")
|
||||
col.itemR(ksp, "rna_path")
|
||||
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Array Target:")
|
||||
col.itemR(ksp, "entire_array")
|
||||
if ksp.entire_array == False:
|
||||
col.itemR(ksp, "array_index")
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="F-Curve Grouping:")
|
||||
col.itemR(ksp, "grouping")
|
||||
if ksp.grouping == 'NAMED':
|
||||
col.itemR(ksp, "group")
|
||||
|
||||
|
||||
|
||||
|
||||
class SCENE_PT_physics(RenderButtonsPanel):
|
||||
__label__ = "Gravity"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
self.layout.itemR(context.scene, "use_gravity", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
layout.active = scene.use_gravity
|
||||
|
||||
layout.itemR(scene, "gravity", text="")
|
||||
|
||||
|
||||
bpy.types.register(SCENE_PT_render)
|
||||
bpy.types.register(SCENE_PT_layers)
|
||||
bpy.types.register(SCENE_PT_dimensions)
|
||||
@@ -463,3 +565,6 @@ bpy.types.register(SCENE_PT_performance)
|
||||
bpy.types.register(SCENE_PT_post_processing)
|
||||
bpy.types.register(SCENE_PT_stamp)
|
||||
bpy.types.register(SCENE_PT_unit)
|
||||
bpy.types.register(SCENE_PT_keying_sets)
|
||||
bpy.types.register(SCENE_PT_keying_set_paths)
|
||||
bpy.types.register(SCENE_PT_physics)
|
||||
|
||||
@@ -175,14 +175,14 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
|
||||
row.itemR(tex, "z_mapping", text="")
|
||||
|
||||
if br:
|
||||
layout.itemR(tex, "brush_map_mode", expand=True)
|
||||
layout.itemR(tex, "map_mode", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.brush_map_mode in ('FIXED', 'TILED')
|
||||
row.active = tex.map_mode in ('FIXED', 'TILED')
|
||||
row.itemR(tex, "angle")
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.brush_map_mode in ('TILED', '3D')
|
||||
row.active = tex.map_mode in ('TILED', '3D')
|
||||
row.column().itemR(tex, "size")
|
||||
else:
|
||||
row = layout.row()
|
||||
@@ -246,13 +246,14 @@ class TEXTURE_PT_influence(TextureSlotPanel):
|
||||
col = split.column()
|
||||
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
|
||||
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
|
||||
factor_but(col, tex.map_absorption, "map_absorption", "absorption_factor", "Absorption")
|
||||
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
|
||||
factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text=" ")
|
||||
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
|
||||
factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color")
|
||||
factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
|
||||
factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
|
||||
|
||||
elif la:
|
||||
row = layout.row()
|
||||
@@ -642,6 +643,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
|
||||
row.itemR(vd, "still_frame_number")
|
||||
|
||||
layout.itemR(vd, "interpolation")
|
||||
layout.itemR(vd, "extension")
|
||||
layout.itemR(vd, "intensity")
|
||||
|
||||
class TEXTURE_PT_pointdensity(TextureButtonsPanel):
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
|
||||
import bpy
|
||||
|
||||
import bpy_ops # XXX - should not need to do this
|
||||
del bpy_ops
|
||||
|
||||
class CONSOLE_HT_header(bpy.types.Header):
|
||||
__space_type__ = 'CONSOLE'
|
||||
|
||||
@@ -184,212 +180,6 @@ class CONSOLE_OT_exec(bpy.types.Operator):
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
def autocomp(bcon):
|
||||
'''
|
||||
This function has been taken from a BGE console autocomp I wrote a while ago
|
||||
the dictionaty bcon is not needed but it means I can copy and paste from the old func
|
||||
which works ok for now.
|
||||
|
||||
could be moved into its own module.
|
||||
'''
|
||||
|
||||
|
||||
def is_delimiter(ch):
|
||||
'''
|
||||
For skipping words
|
||||
'''
|
||||
if ch == '_':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def is_delimiter_autocomp(ch):
|
||||
'''
|
||||
When autocompleteing will earch back and
|
||||
'''
|
||||
if ch in '._[] "\'':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def do_autocomp(autocomp_prefix, autocomp_members):
|
||||
'''
|
||||
return text to insert and a list of options
|
||||
'''
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
print("AUTO: '%s'" % autocomp_prefix)
|
||||
print("MEMBERS: '%s'" % str(autocomp_members))
|
||||
|
||||
if not autocomp_prefix:
|
||||
return '', autocomp_members
|
||||
elif len(autocomp_members) > 1:
|
||||
# find a common string between all members after the prefix
|
||||
# 'ge' [getA, getB, getC] --> 'get'
|
||||
|
||||
# get the shortest member
|
||||
min_len = min([len(v) for v in autocomp_members])
|
||||
|
||||
autocomp_prefix_ret = ''
|
||||
|
||||
for i in range(len(autocomp_prefix), min_len):
|
||||
char_soup = set()
|
||||
for v in autocomp_members:
|
||||
char_soup.add(v[i])
|
||||
|
||||
if len(char_soup) > 1:
|
||||
break
|
||||
else:
|
||||
autocomp_prefix_ret += char_soup.pop()
|
||||
|
||||
return autocomp_prefix_ret, autocomp_members
|
||||
elif len(autocomp_members) == 1:
|
||||
if autocomp_prefix == autocomp_members[0]:
|
||||
# the variable matched the prefix exactly
|
||||
# add a '.' so you can quickly continue.
|
||||
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
|
||||
return '.', []
|
||||
else:
|
||||
# finish off the of the word word
|
||||
return autocomp_members[0][len(autocomp_prefix):], []
|
||||
else:
|
||||
return '', []
|
||||
|
||||
|
||||
def BCon_PrevChar(bcon):
|
||||
cursor = bcon['cursor']-1
|
||||
if cursor<0:
|
||||
return None
|
||||
|
||||
try:
|
||||
return bcon['edit_text'][cursor]
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def BCon_NextChar(bcon):
|
||||
try:
|
||||
return bcon['edit_text'][bcon['cursor']]
|
||||
except:
|
||||
return None
|
||||
|
||||
def BCon_cursorLeft(bcon):
|
||||
bcon['cursor'] -= 1
|
||||
if bcon['cursor'] < 0:
|
||||
bcon['cursor'] = 0
|
||||
|
||||
def BCon_cursorRight(bcon):
|
||||
bcon['cursor'] += 1
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
|
||||
def BCon_AddScrollback(bcon, text):
|
||||
|
||||
bcon['scrollback'] = bcon['scrollback'] + text
|
||||
|
||||
|
||||
def BCon_cursorInsertChar(bcon, ch):
|
||||
if bcon['cursor']==0:
|
||||
bcon['edit_text'] = ch + bcon['edit_text']
|
||||
elif bcon['cursor']==len(bcon['edit_text']):
|
||||
bcon['edit_text'] = bcon['edit_text'] + ch
|
||||
else:
|
||||
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
|
||||
|
||||
bcon['cursor']
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
|
||||
TEMP_NAME = '___tempname___'
|
||||
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and (not is_delimiter(ch)):
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
if ch != None:
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
#print (cursor_orig, bcon['cursor'])
|
||||
|
||||
cursor_base = bcon['cursor']
|
||||
|
||||
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
|
||||
|
||||
print("PREFIX:'%s'" % autocomp_prefix)
|
||||
|
||||
# Get the previous word
|
||||
if BCon_PrevChar(bcon)=='.':
|
||||
BCon_cursorLeft(bcon)
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and is_delimiter_autocomp(ch)==False:
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
cursor_new = bcon['cursor']
|
||||
|
||||
if ch != None:
|
||||
cursor_new+=1
|
||||
|
||||
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
|
||||
print("AUTOCOMP EVAL: '%s'" % pytxt)
|
||||
#try:
|
||||
if pytxt:
|
||||
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
|
||||
# print val
|
||||
else: ##except:
|
||||
val = None
|
||||
|
||||
try:
|
||||
val = bcon['namespace'][TEMP_NAME]
|
||||
del bcon['namespace'][TEMP_NAME]
|
||||
except:
|
||||
val = None
|
||||
|
||||
if val:
|
||||
autocomp_members = dir(val)
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
del val
|
||||
|
||||
else:
|
||||
# Autocomp global namespace
|
||||
autocomp_members = bcon['namespace'].keys()
|
||||
|
||||
if autocomp_prefix:
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
|
||||
|
||||
class CONSOLE_OT_autocomplete(bpy.types.Operator):
|
||||
'''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.'''
|
||||
__idname__ = "console.autocomplete"
|
||||
@@ -425,7 +215,8 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator):
|
||||
|
||||
# This function isnt aware of the text editor or being an operator
|
||||
# just does the autocomp then copy its results back
|
||||
autocomp(bcon)
|
||||
import autocomplete
|
||||
autocomplete.execute(bcon)
|
||||
|
||||
# Now we need to copy back the line from blender back into the text editor.
|
||||
# This will change when we dont use the text editor anymore
|
||||
|
||||
@@ -145,6 +145,10 @@ class INFO_MT_add(bpy.types.Menu):
|
||||
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
|
||||
layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
|
||||
|
||||
class INFO_MT_game(bpy.types.Menu):
|
||||
__space_type__ = 'INFO'
|
||||
__label__ = "Game"
|
||||
@@ -211,9 +215,6 @@ bpy.types.register(INFO_MT_help)
|
||||
|
||||
# Help operators
|
||||
|
||||
import bpy_ops # XXX - should not need to do this
|
||||
del bpy_ops
|
||||
|
||||
class HelpOperator(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
try: import webbrowser
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -103,6 +103,9 @@ void armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], flo
|
||||
void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc);
|
||||
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
|
||||
|
||||
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
|
||||
void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode);
|
||||
|
||||
/* B-Bone support */
|
||||
typedef struct Mat4 {
|
||||
float mat[4][4];
|
||||
|
||||
@@ -43,7 +43,7 @@ struct bContext;
|
||||
struct ReportList;
|
||||
|
||||
#define BLENDER_VERSION 250
|
||||
#define BLENDER_SUBVERSION 3
|
||||
#define BLENDER_SUBVERSION 4
|
||||
|
||||
#define BLENDER_MINVERSION 250
|
||||
#define BLENDER_MINSUBVERSION 0
|
||||
|
||||
@@ -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);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -116,4 +116,7 @@ void DAG_ids_flush_update(int time);
|
||||
/* (re)-create dependency graph for armature pose */
|
||||
void DAG_pose_sort(struct Object *ob);
|
||||
|
||||
/* callback for editors module to do updates */
|
||||
void DAG_editors_update_cb(void (*func)(struct Main *bmain, struct ID *id));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define BKE_EFFECT_H
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
|
||||
struct Object;
|
||||
struct Scene;
|
||||
@@ -40,20 +41,72 @@ struct ListBase;
|
||||
struct Particle;
|
||||
struct Group;
|
||||
struct RNG;
|
||||
struct ParticleSimulationData;
|
||||
struct ParticleData;
|
||||
struct ParticleKey;
|
||||
|
||||
struct PartDeflect *object_add_collision_fields(void);
|
||||
struct EffectorWeights *BKE_add_effector_weights(struct Group *group);
|
||||
struct PartDeflect *object_add_collision_fields(int type);
|
||||
|
||||
typedef struct pEffectorCache {
|
||||
struct pEffectorCache *next, *prev;
|
||||
Object *ob;
|
||||
/* Input to effector code */
|
||||
typedef struct EffectedPoint {
|
||||
float *loc;
|
||||
float *vel;
|
||||
float *ave; /* angular velocity for particles with dynamic rotation */
|
||||
float *rot; /* rotation quaternion for particles with dynamic rotation */
|
||||
float vel_to_frame;
|
||||
float vel_to_sec;
|
||||
|
||||
/* precalculated variables */
|
||||
float oldloc[3], oldspeed[3];
|
||||
float scale, time_scale;
|
||||
float guide_dist;
|
||||
/* only for particles */
|
||||
float size, charge;
|
||||
|
||||
Object obcopy; /* for restoring transformation data */
|
||||
} pEffectorCache;
|
||||
unsigned int flag;
|
||||
int index;
|
||||
|
||||
struct ParticleSystem *psys; /* particle system the point belongs to */
|
||||
} EffectedPoint;
|
||||
|
||||
typedef struct GuideEffectorData {
|
||||
float vec_to_point[3];
|
||||
float strength;
|
||||
} GuideEffectorData;
|
||||
|
||||
typedef struct EffectorData {
|
||||
/* Effector point */
|
||||
float loc[3];
|
||||
float nor[3];
|
||||
float vel[3];
|
||||
|
||||
float vec_to_point[3];
|
||||
float distance, falloff;
|
||||
|
||||
/* only for effector particles */
|
||||
float size, charge;
|
||||
|
||||
/* only for vortex effector with surface falloff */
|
||||
float nor2[3], vec_to_point2[3];
|
||||
|
||||
int *index; /* point index */
|
||||
} EffectorData;
|
||||
|
||||
/* used for calculating the effector force */
|
||||
typedef struct EffectorCache {
|
||||
struct EffectorCache *next, *prev;
|
||||
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSystem *psys;
|
||||
struct SurfaceModifierData *surmd;
|
||||
|
||||
struct PartDeflect *pd;
|
||||
|
||||
/* precalculated for guides */
|
||||
struct GuideEffectorData *guide_data;
|
||||
float guide_loc[4], guide_dir[3], guide_radius;
|
||||
|
||||
float frame;
|
||||
int flag;
|
||||
} EffectorCache;
|
||||
|
||||
void free_effect(struct Effect *eff);
|
||||
void free_effects(struct ListBase *lb);
|
||||
@@ -61,23 +114,33 @@ struct Effect *copy_effect(struct Effect *eff);
|
||||
void copy_effects(struct ListBase *lbn, struct ListBase *lb);
|
||||
void deselectall_eff(struct Object *ob);
|
||||
|
||||
/* particle deflector */
|
||||
#define PE_WIND_AS_SPEED 0x00000001
|
||||
|
||||
struct PartEff *give_parteff(struct Object *ob);
|
||||
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *obsrc, struct Group *group);
|
||||
void pdEndEffectors(struct ListBase *lb);
|
||||
void pdDoEffectors(struct Scene *scene, struct ListBase *lb, float *opco, float *force,
|
||||
float *speed, float cur_time, float loc_time, unsigned int flags);
|
||||
|
||||
|
||||
void free_partdeflect(struct PartDeflect *pd);
|
||||
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights);
|
||||
void pdEndEffectors(struct ListBase **effectors);
|
||||
void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
|
||||
|
||||
void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
|
||||
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
|
||||
void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
|
||||
|
||||
/* needed for boids */
|
||||
float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights);
|
||||
int closest_point_on_surface(struct SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel);
|
||||
int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity);
|
||||
|
||||
/* required for particle_system.c */
|
||||
void do_physical_effector(struct Scene *scene, struct Object *ob, float *opco, short type, float force_val, float distance,
|
||||
float falloff, float size, float damp, float *eff_velocity, float *vec_to_part,
|
||||
float *velocity, float *field, int planar, struct RNG *rng, float noise_factor,
|
||||
float charge, float pa_size);
|
||||
float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part);
|
||||
//void do_physical_effector(struct EffectorData *eff, struct EffectorPoint *point, float *total_force);
|
||||
//float effector_falloff(struct EffectorData *eff, struct EffectorPoint *point, struct EffectorWeights *weights);
|
||||
|
||||
/* EffectedPoint->flag */
|
||||
#define PE_WIND_AS_SPEED 1
|
||||
#define PE_DYNAMIC_ROTATION 2
|
||||
|
||||
/* EffectorData->flag */
|
||||
#define PE_VELOCITY_TO_IMPULSE 1
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
@@ -244,7 +223,6 @@ void object_add_particle_system(struct Scene *scene, struct Object *ob);
|
||||
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
|
||||
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
|
||||
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
|
||||
void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
|
||||
void make_local_particlesettings(struct ParticleSettings *part);
|
||||
|
||||
void psys_reset(struct ParticleSystem *psys, int mode);
|
||||
@@ -254,7 +232,8 @@ void psys_find_parents(struct ParticleSimulationData *sim);
|
||||
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
|
||||
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
|
||||
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
|
||||
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
|
||||
int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
|
||||
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
|
||||
float psys_get_timestep(struct ParticleSimulationData *sim);
|
||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
|
||||
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
|
||||
@@ -273,9 +252,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
|
||||
/* particle_system.c */
|
||||
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
|
||||
void psys_count_keyed_targets(struct ParticleSimulationData *sim);
|
||||
//void psys_get_reactor_target(struct ParticleSimulationData *sim, struct Object **target_ob, struct ParticleSystem **target_psys);
|
||||
|
||||
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc);
|
||||
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
|
||||
|
||||
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);
|
||||
@@ -316,29 +293,17 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_
|
||||
|
||||
/* particle_system.c */
|
||||
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p);
|
||||
|
||||
int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index);
|
||||
void do_effectors(struct ParticleSimulationData *sim, int pa_no, struct ParticleData *pa, struct ParticleKey *state, float *texco, float *force_field, float *vel,float framestep, float cfra);
|
||||
void psys_end_effectors(struct ParticleSystem *psys);
|
||||
|
||||
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
|
||||
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
|
||||
|
||||
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
|
||||
|
||||
|
||||
/* psys_reset */
|
||||
#define PSYS_RESET_ALL 1
|
||||
#define PSYS_RESET_DEPSGRAPH 2
|
||||
#define PSYS_RESET_CHILDREN 3
|
||||
#define PSYS_RESET_CACHE_MISS 4
|
||||
|
||||
/* ParticleEffectorCache->type */
|
||||
#define PSYS_EC_EFFECTOR 1
|
||||
#define PSYS_EC_DEFLECT 2
|
||||
#define PSYS_EC_PARTICLE 4
|
||||
#define PSYS_EC_REACTOR 8
|
||||
|
||||
/* index_dmcache */
|
||||
#define DMCACHE_NOTFOUND -1
|
||||
#define DMCACHE_ISCHILD -2
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "gpu_buffers.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
@@ -218,7 +219,7 @@ int DM_release(DerivedMesh *dm)
|
||||
{
|
||||
if (dm->needsFree) {
|
||||
bvhcache_free(&dm->bvhCache);
|
||||
|
||||
GPU_drawobject_free( dm );
|
||||
CustomData_free(&dm->vertData, dm->numVertData);
|
||||
CustomData_free(&dm->edgeData, dm->numEdgeData);
|
||||
CustomData_free(&dm->faceData, dm->numFaceData);
|
||||
@@ -490,6 +491,44 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
} else {
|
||||
GPUBuffer *buffer = 0;
|
||||
float *varray;
|
||||
if( setDrawOptions == 0 ) {
|
||||
buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 );
|
||||
}
|
||||
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
|
||||
int prevdraw = 0;
|
||||
int numedges = 0;
|
||||
int draw = 0;
|
||||
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
|
||||
GPU_buffer_unlock( buffer );
|
||||
GPU_interleaved_setup( buffer, datatype );
|
||||
varray = GPU_buffer_lock_stream( buffer );
|
||||
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
|
||||
if(!setDrawOptions || setDrawOptions(userData, i)) {
|
||||
draw = 1;
|
||||
} else {
|
||||
draw = 0;
|
||||
}
|
||||
if( prevdraw != draw && prevdraw != 0 && numedges > 0) {
|
||||
GPU_buffer_unlock( buffer );
|
||||
glDrawArrays(GL_LINES,0,numedges*2);
|
||||
varray = GPU_buffer_lock_stream( buffer );
|
||||
numedges = 0;
|
||||
}
|
||||
if( draw != 0 ) {
|
||||
VECCOPY(&varray[numedges*6],eed->v1->co);
|
||||
VECCOPY(&varray[numedges*6+3],eed->v2->co);
|
||||
numedges++;
|
||||
}
|
||||
prevdraw = draw;
|
||||
}
|
||||
GPU_buffer_unlock( buffer );
|
||||
if( prevdraw != 0 && numedges > 0) {
|
||||
glDrawArrays(GL_LINES,0,numedges*2);
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
} else {
|
||||
glBegin(GL_LINES);
|
||||
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
|
||||
@@ -500,6 +539,9 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
if( buffer != 0 )
|
||||
GPU_buffer_free( buffer, 0 );
|
||||
}
|
||||
}
|
||||
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
{
|
||||
@@ -658,6 +700,97 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GPUBuffer *buffer = 0;
|
||||
float *varray;
|
||||
if( setDrawOptions == 0 ) {
|
||||
/* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
|
||||
buffer = GPU_buffer_alloc( sizeof(float)*6*emdm->em->totface*3*2, 0 );
|
||||
}
|
||||
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
|
||||
int prevdraw = 0;
|
||||
int numfaces = 0;
|
||||
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
|
||||
GPU_buffer_unlock( buffer );
|
||||
GPU_interleaved_setup( buffer, datatype );
|
||||
glShadeModel(GL_SMOOTH);
|
||||
varray = GPU_buffer_lock_stream( buffer );
|
||||
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
|
||||
int drawSmooth = (efa->flag & ME_SMOOTH);
|
||||
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
|
||||
if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
|
||||
if( prevdraw==2 ) {
|
||||
glEnable(GL_POLYGON_STIPPLE);
|
||||
glPolygonStipple(stipple_quarttone);
|
||||
}
|
||||
GPU_buffer_unlock( buffer );
|
||||
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
|
||||
if( prevdraw==2 ) {
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
}
|
||||
varray = GPU_buffer_lock_stream( buffer );
|
||||
numfaces = 0;
|
||||
}
|
||||
if( draw != 0 ) {
|
||||
if(!drawSmooth) {
|
||||
VECCOPY(&varray[numfaces*18],efa->v1->co);
|
||||
VECCOPY(&varray[numfaces*18+3],efa->n);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
|
||||
VECCOPY(&varray[numfaces*18+9],efa->n);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
|
||||
VECCOPY(&varray[numfaces*18+15],efa->n);
|
||||
numfaces++;
|
||||
if( efa->v4 ) {
|
||||
VECCOPY(&varray[numfaces*18],efa->v3->co);
|
||||
VECCOPY(&varray[numfaces*18+3],efa->n);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
|
||||
VECCOPY(&varray[numfaces*18+9],efa->n);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
|
||||
VECCOPY(&varray[numfaces*18+15],efa->n);
|
||||
numfaces++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
VECCOPY(&varray[numfaces*18],efa->v1->co);
|
||||
VECCOPY(&varray[numfaces*18+3],efa->v1->no);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
|
||||
VECCOPY(&varray[numfaces*18+9],efa->v2->no);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
|
||||
VECCOPY(&varray[numfaces*18+15],efa->v3->no);
|
||||
numfaces++;
|
||||
if( efa->v4 ) {
|
||||
VECCOPY(&varray[numfaces*18],efa->v3->co);
|
||||
VECCOPY(&varray[numfaces*18+3],efa->v3->no);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
|
||||
VECCOPY(&varray[numfaces*18+9],efa->v4->no);
|
||||
|
||||
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
|
||||
VECCOPY(&varray[numfaces*18+15],efa->v1->no);
|
||||
numfaces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevdraw = draw;
|
||||
}
|
||||
GPU_buffer_unlock( buffer );
|
||||
if( prevdraw != 0 && numfaces > 0) {
|
||||
if( prevdraw==2 ) {
|
||||
glEnable(GL_POLYGON_STIPPLE);
|
||||
glPolygonStipple(stipple_quarttone);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
|
||||
if( prevdraw==2 ) {
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
} else {
|
||||
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
|
||||
int drawSmooth = (efa->flag & ME_SMOOTH);
|
||||
@@ -695,6 +828,9 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
}
|
||||
}
|
||||
}
|
||||
if( buffer != 0 )
|
||||
GPU_buffer_free( buffer, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void emDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -187,8 +187,6 @@ AnimData *BKE_copy_animdata (AnimData *adt)
|
||||
dadt= MEM_dupallocN(adt);
|
||||
|
||||
/* make a copy of action - at worst, user has to delete copies... */
|
||||
// XXX review this... it might not be optimal behaviour yet...
|
||||
//id_us_plus((ID *)dadt->action);
|
||||
dadt->action= copy_action(adt->action);
|
||||
dadt->tmpact= copy_action(adt->tmpact);
|
||||
|
||||
@@ -213,7 +211,7 @@ static void make_local_strips(ListBase *strips)
|
||||
|
||||
for (strip=strips->first; strip; strip=strip->next) {
|
||||
if (strip->act) make_local_action(strip->act);
|
||||
//if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
|
||||
if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
|
||||
|
||||
make_local_strips(&strip->strips);
|
||||
}
|
||||
@@ -1467,6 +1465,10 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt, float ct
|
||||
* Unresolved things:
|
||||
* - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids or nodal system? but stored where?
|
||||
* - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
|
||||
*
|
||||
* Current Status:
|
||||
* - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides.
|
||||
* However, the code fo this is relatively harmless, so is left in the code for now.
|
||||
*/
|
||||
|
||||
/* Evaluation loop for evaluation animation data
|
||||
@@ -1623,9 +1625,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
|
||||
|
||||
/* objects */
|
||||
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
|
||||
* this tagged by Depsgraph on framechange
|
||||
* this tagged by Depsgraph on framechange. This optimisation means that objects
|
||||
* linked from other (not-visible) scenes will not need their data calculated.
|
||||
*/
|
||||
EVAL_ANIM_IDS(main->object.first, /*ADT_RECALC_ANIM*/0);
|
||||
EVAL_ANIM_IDS(main->object.first, 0);
|
||||
|
||||
/* worlds */
|
||||
EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM);
|
||||
|
||||
@@ -1279,6 +1279,65 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
|
||||
Mat4MulMat4(delta_mat, pose_mat, imat);
|
||||
}
|
||||
|
||||
/* **************** Rotation Mode Conversions ****************************** */
|
||||
/* Used for Objects and Pose Channels, since both can have multiple rotation representations */
|
||||
|
||||
/* Called from RNA when rotation mode changes
|
||||
* - the result should be that the rotations given in the provided pointers have had conversions
|
||||
* applied (as appropriate), such that the rotation of the element hasn't 'visually' changed
|
||||
*
|
||||
* - as in SDNA data, quat is used to store quaternions AND axis-angle rotations...
|
||||
*/
|
||||
void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode)
|
||||
{
|
||||
/* check if any change - if so, need to convert data */
|
||||
if (newMode > 0) { /* to euler */
|
||||
if (oldMode == ROT_MODE_AXISANGLE) {
|
||||
/* axis-angle to euler */
|
||||
AxisAngleToEulO(&quat[1], quat[0], eul, newMode);
|
||||
}
|
||||
else if (oldMode == ROT_MODE_QUAT) {
|
||||
/* quat to euler */
|
||||
QuatToEulO(quat, eul, newMode);
|
||||
}
|
||||
/* else { no conversion needed } */
|
||||
}
|
||||
else if (newMode == ROT_MODE_QUAT) { /* to quat */
|
||||
if (oldMode == ROT_MODE_AXISANGLE) {
|
||||
/* axis angle to quat */
|
||||
float q[4];
|
||||
|
||||
/* copy to temp var first, since quats and axis-angle are stored in same place */
|
||||
QuatCopy(q, quat);
|
||||
AxisAngleToQuat(q, &quat[1], quat[0]);
|
||||
}
|
||||
else if (oldMode > 0) {
|
||||
/* euler to quat */
|
||||
EulOToQuat(eul, oldMode, quat);
|
||||
}
|
||||
/* else { no conversion needed } */
|
||||
}
|
||||
else { /* to axis-angle */
|
||||
if (oldMode > 0) {
|
||||
/* euler to axis angle */
|
||||
EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]);
|
||||
}
|
||||
else if (oldMode == ROT_MODE_QUAT) {
|
||||
/* quat to axis angle */
|
||||
float q[4];
|
||||
|
||||
/* copy to temp var first, since quats and axis-angle are stored in same place */
|
||||
QuatCopy(q, quat);
|
||||
QuatToAxisAngle(q, &quat[1], &quat[0]);
|
||||
}
|
||||
|
||||
/* when converting to axis-angle, we need a special exception for the case when there is no axis */
|
||||
if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
|
||||
/* for now, rotate around y-axis then (so that it simply becomes the roll) */
|
||||
quat[2]= 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* **************** The new & simple (but OK!) armature evaluation ********* */
|
||||
|
||||
@@ -1591,7 +1650,7 @@ void chan_calc_mat(bPoseChannel *chan)
|
||||
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
|
||||
EulOToMat3(chan->eul, chan->rotmode, rmat);
|
||||
}
|
||||
else if (chan->rotmode == PCHAN_ROT_AXISANGLE) {
|
||||
else if (chan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
|
||||
AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_kdtree.h"
|
||||
#include "BLI_kdopbvh.h"
|
||||
#include "BKE_collision.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_boids.h"
|
||||
#include "BKE_particle.h"
|
||||
@@ -72,112 +73,91 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
{
|
||||
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
|
||||
BoidSettings *boids = bbd->part->boids;
|
||||
ParticleEffectorCache *ec;
|
||||
Object *priority_ob = NULL;
|
||||
BoidParticle *bpa = pa->boid;
|
||||
EffectedPoint epoint;
|
||||
ListBase *effectors = bbd->sim->psys->effectors;
|
||||
EffectorCache *cur, *eff = NULL;
|
||||
EffectorData efd, cur_efd;
|
||||
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
|
||||
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
|
||||
float priority = 0.0f, len = 0.0f;
|
||||
int ret = 0;
|
||||
|
||||
pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
|
||||
|
||||
/* first find out goal/predator with highest priority */
|
||||
/* if rule->ob specified use it */
|
||||
if(effectors) for(cur = effectors->first; cur; cur=cur->next) {
|
||||
Object *eob = cur->ob;
|
||||
PartDeflect *pd = cur->pd;
|
||||
|
||||
if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
|
||||
PartDeflect *pd = gabr->ob->pd;
|
||||
float vec_to_part[3];
|
||||
|
||||
if(pd && pd->forcefield == PFIELD_BOID) {
|
||||
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
|
||||
priority = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
|
||||
}
|
||||
if(gabr->ob == eob) {
|
||||
/* TODO: objects without any effector and effectors with multiple points */
|
||||
if(get_effector_data(cur, &efd, &epoint, 0)) {
|
||||
if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
|
||||
priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
|
||||
else
|
||||
priority = 1.0;
|
||||
|
||||
priority = 1.0;
|
||||
priority_ob = gabr->ob;
|
||||
eff = cur;
|
||||
}
|
||||
else for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_EFFECTOR) {
|
||||
Object *eob = ec->ob;
|
||||
PartDeflect *pd = eob->pd;
|
||||
|
||||
/* skip current object */
|
||||
if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
|
||||
continue;
|
||||
|
||||
if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
|
||||
float vec_to_part[3], temp;
|
||||
|
||||
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
|
||||
temp = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
|
||||
; /* skip current object */
|
||||
else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(eff, &efd, &epoint, 0)) {
|
||||
float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
|
||||
|
||||
if(temp == 0.0f)
|
||||
; /* do nothing */
|
||||
else if(temp > priority) {
|
||||
priority = temp;
|
||||
priority_ob = eob;
|
||||
len = VecLength(vec_to_part);
|
||||
eff = cur;
|
||||
efd = cur_efd;
|
||||
len = efd.distance;
|
||||
}
|
||||
/* choose closest object with same priority */
|
||||
else if(temp == priority) {
|
||||
float len2 = VecLength(vec_to_part);
|
||||
|
||||
if(len2 < len) {
|
||||
priority_ob = eob;
|
||||
len = len2;
|
||||
}
|
||||
}
|
||||
else if(temp == priority && efd.distance < len) {
|
||||
eff = cur;
|
||||
efd = cur_efd;
|
||||
len = efd.distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* then use that effector */
|
||||
if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
|
||||
Object *eob = priority_ob;
|
||||
Object *eob = eff->ob;
|
||||
PartDeflect *pd = eob->pd;
|
||||
float vec_to_part[3];
|
||||
float surface = 0.0f;
|
||||
float nor[3];
|
||||
float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f;
|
||||
|
||||
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
|
||||
/* estimate future location of target */
|
||||
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL);
|
||||
get_effector_data(eff, &efd, &epoint, 1);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
len = Normalize(vec_to_part);
|
||||
|
||||
VecMulf(vec, len / (val->max_speed * bbd->timestep));
|
||||
VecAddf(loc, loc, vec);
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
}
|
||||
else {
|
||||
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
len = VecLength(vec_to_part);
|
||||
VecMulf(efd.vel, efd.distance / (val->max_speed * bbd->timestep));
|
||||
VecAddf(efd.loc, efd.loc, efd.vel);
|
||||
VecSubf(efd.vec_to_point, pa->prev_state.co, efd.loc);
|
||||
efd.distance = VecLength(efd.vec_to_point);
|
||||
}
|
||||
|
||||
if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) {
|
||||
if(!bbd->goal_ob || bbd->goal_priority < priority) {
|
||||
bbd->goal_ob = eob;
|
||||
VECCOPY(bbd->goal_co, loc);
|
||||
VECCOPY(bbd->goal_nor, nor);
|
||||
VECCOPY(bbd->goal_co, efd.loc);
|
||||
VECCOPY(bbd->goal_nor, efd.nor);
|
||||
}
|
||||
}
|
||||
else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
|
||||
priority > 2.0f * gabr->fear_factor) {
|
||||
/* detach from surface and try to fly away from danger */
|
||||
VECCOPY(vec_to_part, bpa->gravity);
|
||||
VecMulf(vec_to_part, -1.0f);
|
||||
VECCOPY(efd.vec_to_point, bpa->gravity);
|
||||
VecMulf(efd.vec_to_point, -1.0f);
|
||||
}
|
||||
|
||||
VECCOPY(bbd->wanted_co, vec_to_part);
|
||||
VECCOPY(bbd->wanted_co, efd.vec_to_point);
|
||||
VecMulf(bbd->wanted_co, mul);
|
||||
|
||||
bbd->wanted_speed = val->max_speed * priority;
|
||||
@@ -188,8 +168,8 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
|
||||
surface *= pa->size * boids->height;
|
||||
|
||||
if(len2 > 0.0f && len - surface < len2) {
|
||||
len2 = (len - surface)/len2;
|
||||
if(len2 > 0.0f && efd.distance - surface < len2) {
|
||||
len2 = (efd.distance - surface)/len2;
|
||||
bbd->wanted_speed *= pow(len2, boids->landing_smoothness);
|
||||
}
|
||||
}
|
||||
@@ -204,9 +184,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
{
|
||||
BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule;
|
||||
KDTreeNearest *ptn = NULL;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleTarget *pt;
|
||||
BoidParticle *bpa = pa->boid;
|
||||
ColliderCache *coll;
|
||||
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
|
||||
float co1[3], vel1[3], co2[3], vel2[3];
|
||||
float len, t, inp, t_min = 2.0f;
|
||||
@@ -214,7 +194,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
int ret = 0;
|
||||
|
||||
//check deflector objects first
|
||||
if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS) {
|
||||
if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) {
|
||||
ParticleCollision col;
|
||||
BVHTreeRayHit hit;
|
||||
float radius = val->personal_space * pa->size, ray_dir[3];
|
||||
@@ -228,21 +208,17 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
hit.dist = col.ray_len = VecLength(ray_dir);
|
||||
|
||||
/* find out closest deflector object */
|
||||
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_DEFLECT) {
|
||||
Object *eob = ec->ob;
|
||||
|
||||
for(coll = bbd->sim->colliders->first; coll; coll=coll->next) {
|
||||
/* don't check with current ground object */
|
||||
if(eob == bpa->ground)
|
||||
if(coll->ob == bpa->ground)
|
||||
continue;
|
||||
|
||||
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
|
||||
col.ob_t = eob;
|
||||
col.ob = coll->ob;
|
||||
col.md = coll->collmd;
|
||||
|
||||
if(col.md && col.md->bvhtree)
|
||||
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
|
||||
}
|
||||
}
|
||||
/* then avoid that object */
|
||||
if(hit.index>=0) {
|
||||
/* TODO: not totally happy with this part */
|
||||
@@ -760,21 +736,24 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
|
||||
surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface );
|
||||
|
||||
/* take surface velocity into account */
|
||||
effector_find_co(bbd->sim->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
|
||||
closest_point_on_surface(surmd, pa->state.co, x, NULL, v);
|
||||
VecAddf(x, x, v);
|
||||
|
||||
/* get actual position on surface */
|
||||
effector_find_co(bbd->sim->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
|
||||
closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL);
|
||||
|
||||
return bpa->ground;
|
||||
}
|
||||
else {
|
||||
float zvec[3] = {0.0f, 0.0f, 2000.0f};
|
||||
ParticleCollision col;
|
||||
ColliderCache *coll;
|
||||
BVHTreeRayHit hit;
|
||||
ParticleEffectorCache *ec;
|
||||
float radius = 0.0f, t, ray_dir[3];
|
||||
|
||||
if(!bbd->sim->colliders)
|
||||
return NULL;
|
||||
|
||||
VECCOPY(col.co1, pa->state.co);
|
||||
VECCOPY(col.co2, pa->state.co);
|
||||
VecAddf(col.co1, col.co1, zvec);
|
||||
@@ -785,24 +764,20 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
|
||||
hit.dist = col.ray_len = VecLength(ray_dir);
|
||||
|
||||
/* find out upmost deflector object */
|
||||
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_DEFLECT) {
|
||||
Object *eob = ec->ob;
|
||||
|
||||
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
|
||||
col.ob_t = eob;
|
||||
for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
|
||||
col.ob = coll->ob;
|
||||
col.md = coll->collmd;
|
||||
|
||||
if(col.md && col.md->bvhtree)
|
||||
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
|
||||
}
|
||||
}
|
||||
/* then use that object */
|
||||
if(hit.index>=0) {
|
||||
t = hit.dist/col.ray_len;
|
||||
VecLerpf(ground_co, col.co1, col.co2, t);
|
||||
VECCOPY(ground_nor, col.nor);
|
||||
Normalize(ground_nor);
|
||||
return col.ob;
|
||||
return col.hit_ob;
|
||||
}
|
||||
else {
|
||||
/* default to z=0 */
|
||||
@@ -1068,6 +1043,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
|
||||
BoidSettings *boids = bbd->part->boids;
|
||||
BoidParticle *bpa = pa->boid;
|
||||
BoidValues val;
|
||||
EffectedPoint epoint;
|
||||
float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
|
||||
float dvec[3], bvec[3];
|
||||
float new_dir[3], new_speed;
|
||||
@@ -1208,7 +1184,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
|
||||
}
|
||||
|
||||
/* account for effectors */
|
||||
do_effectors(bbd->sim, p, pa, &pa->state, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
|
||||
pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
|
||||
pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
|
||||
|
||||
if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
|
||||
float length = Normalize(force);
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "gpu_buffers.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
@@ -176,11 +177,20 @@ static void cdDM_drawVerts(DerivedMesh *dm)
|
||||
MVert *mv = cddm->mvert;
|
||||
int i;
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
glBegin(GL_POINTS);
|
||||
for(i = 0; i < dm->numVertData; i++, mv++)
|
||||
glVertex3fv(mv->co);
|
||||
glEnd();
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
GPU_vertex_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
glDrawArrays(GL_POINTS,0,dm->drawObject->nelements);
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawUVEdges(DerivedMesh *dm)
|
||||
{
|
||||
@@ -190,6 +200,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
|
||||
int i;
|
||||
|
||||
if(mf) {
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
glBegin(GL_LINES);
|
||||
for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
|
||||
if(!(mf->flag&ME_HIDE)) {
|
||||
@@ -213,6 +224,42 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
int prevstart = 0;
|
||||
int prevdraw = 1;
|
||||
int draw = 1;
|
||||
int curpos = 0;
|
||||
|
||||
GPU_uvedge_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
for(i = 0; i < dm->numFaceData; i++, mf++) {
|
||||
if(mf->flag&ME_LOOSEEDGE) {
|
||||
draw = 1;
|
||||
}
|
||||
else {
|
||||
draw = 0;
|
||||
}
|
||||
if( prevdraw != draw ) {
|
||||
if( prevdraw > 0 && (curpos-prevstart) > 0) {
|
||||
glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
|
||||
}
|
||||
prevstart = curpos;
|
||||
}
|
||||
if( mf->v4 ) {
|
||||
curpos += 8;
|
||||
}
|
||||
else {
|
||||
curpos += 6;
|
||||
}
|
||||
prevdraw = draw;
|
||||
}
|
||||
if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
|
||||
glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
@@ -222,6 +269,8 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
MEdge *medge = cddm->medge;
|
||||
int i;
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
|
||||
glBegin(GL_LINES);
|
||||
for(i = 0; i < dm->numEdgeData; i++, medge++) {
|
||||
if((medge->flag&ME_EDGEDRAW)
|
||||
@@ -232,6 +281,36 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
int prevstart = 0;
|
||||
int prevdraw = 1;
|
||||
int draw = 1;
|
||||
|
||||
GPU_edge_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
for(i = 0; i < dm->numEdgeData; i++, medge++) {
|
||||
if((medge->flag&ME_EDGEDRAW)
|
||||
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
|
||||
draw = 1;
|
||||
}
|
||||
else {
|
||||
draw = 0;
|
||||
}
|
||||
if( prevdraw != draw ) {
|
||||
if( prevdraw > 0 && (i-prevstart) > 0 ) {
|
||||
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
|
||||
}
|
||||
prevstart = i;
|
||||
}
|
||||
prevdraw = draw;
|
||||
}
|
||||
if( prevdraw > 0 && (i-prevstart) > 0 ) {
|
||||
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawLooseEdges(DerivedMesh *dm)
|
||||
{
|
||||
@@ -240,6 +319,8 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
|
||||
MEdge *medge = cddm->medge;
|
||||
int i;
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
|
||||
glBegin(GL_LINES);
|
||||
for(i = 0; i < dm->numEdgeData; i++, medge++) {
|
||||
if(medge->flag&ME_LOOSEEDGE) {
|
||||
@@ -249,6 +330,35 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm)
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
int prevstart = 0;
|
||||
int prevdraw = 1;
|
||||
int draw = 1;
|
||||
|
||||
GPU_edge_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
for(i = 0; i < dm->numEdgeData; i++, medge++) {
|
||||
if(medge->flag&ME_LOOSEEDGE) {
|
||||
draw = 1;
|
||||
}
|
||||
else {
|
||||
draw = 0;
|
||||
}
|
||||
if( prevdraw != draw ) {
|
||||
if( prevdraw > 0 && (i-prevstart) > 0) {
|
||||
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
|
||||
}
|
||||
prevstart = i;
|
||||
}
|
||||
prevdraw = draw;
|
||||
}
|
||||
if( prevdraw > 0 && (i-prevstart) > 0 ) {
|
||||
GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
|
||||
{
|
||||
@@ -266,6 +376,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a
|
||||
glVertex3fv(mvert[index].co); \
|
||||
}
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
|
||||
glBegin(glmode = GL_QUADS);
|
||||
for(a = 0; a < dm->numFaceData; a++, mface++) {
|
||||
int new_glmode, new_matnr, new_shademodel;
|
||||
@@ -315,9 +427,22 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a
|
||||
if(nors) nors += 3;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
GPU_vertex_setup( dm );
|
||||
GPU_normal_setup( dm );
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
|
||||
if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
|
||||
glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind( );
|
||||
}
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
#undef PASSVERT
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
|
||||
static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
|
||||
@@ -342,6 +467,8 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
|
||||
if(col1 && col2)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(glmode = GL_QUADS);
|
||||
for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
|
||||
@@ -378,6 +505,25 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
|
||||
if(col2) cp2 += 16;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
GPU_color4_upload(dm,cp1);
|
||||
GPU_vertex_setup(dm);
|
||||
GPU_color_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
|
||||
|
||||
if( useTwoSided ) {
|
||||
GPU_color4_upload(dm,cp2);
|
||||
GPU_color_setup(dm);
|
||||
glCullFace(GL_FRONT);
|
||||
glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
@@ -390,12 +536,18 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
|
||||
MVert *mv = cddm->mvert;
|
||||
MFace *mf = cddm->mface;
|
||||
MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL);
|
||||
MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
|
||||
MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
|
||||
float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
|
||||
MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
|
||||
int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
|
||||
int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
|
||||
int startFace = 0, lastFlag = 0xdeadbeef;
|
||||
MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
|
||||
if(!mcol)
|
||||
mcol = dm->getFaceDataArray(dm, CD_MCOL);
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
|
||||
for(i = 0; i < dm->numFaceData; i++, mf++) {
|
||||
MVert *mvert;
|
||||
int flag;
|
||||
@@ -416,7 +568,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
else { if(nors) nors += 3; continue; }
|
||||
}
|
||||
|
||||
if(flag != 0) { /* if the flag is 0 it means the face is hidden or invisible */
|
||||
if(flag != 0) {
|
||||
if (flag==1 && mcol)
|
||||
cp= (unsigned char*) &mcol[i*4];
|
||||
|
||||
@@ -425,7 +577,6 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
glNormal3fv(nors);
|
||||
}
|
||||
else {
|
||||
/* TODO make this better (cache facenormals as layer?) */
|
||||
float nor[3];
|
||||
if(mf->v4) {
|
||||
CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
|
||||
@@ -470,6 +621,88 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
|
||||
if(nors) nors += 3;
|
||||
}
|
||||
} else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
MCol *col = realcol;
|
||||
if(!col)
|
||||
col = mcol;
|
||||
|
||||
GPU_vertex_setup( dm );
|
||||
GPU_normal_setup( dm );
|
||||
GPU_uv_setup( dm );
|
||||
if( col != 0 ) {
|
||||
/*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) {
|
||||
col = 0;
|
||||
} else if( mcol && dm->drawObject->colType == CD_MCOL ) {
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if( col != 0 ) {*/
|
||||
unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
|
||||
for( i=0; i < dm->getNumFaces(dm); i++ ) {
|
||||
for( j=0; j < 4; j++ ) {
|
||||
colors[i*12+j*3] = col[i*4+j].r;
|
||||
colors[i*12+j*3+1] = col[i*4+j].g;
|
||||
colors[i*12+j*3+2] = col[i*4+j].b;
|
||||
}
|
||||
}
|
||||
GPU_color3_upload(dm,colors);
|
||||
MEM_freeN(colors);
|
||||
if(realcol)
|
||||
dm->drawObject->colType = CD_TEXTURE_MCOL;
|
||||
else if(mcol)
|
||||
dm->drawObject->colType = CD_MCOL;
|
||||
//}
|
||||
GPU_color_setup( dm );
|
||||
}
|
||||
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
glShadeModel( GL_SMOOTH );
|
||||
for(i = 0; i < dm->drawObject->nelements/3; i++) {
|
||||
int actualFace = dm->drawObject->faceRemap[i];
|
||||
int flag = 1;
|
||||
unsigned char *cp = NULL;
|
||||
|
||||
if(drawParams) {
|
||||
flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr);
|
||||
}
|
||||
else {
|
||||
if(index) {
|
||||
orig = index[actualFace];
|
||||
if(drawParamsMapped)
|
||||
flag = drawParamsMapped(userData, orig);
|
||||
}
|
||||
else
|
||||
if(drawParamsMapped)
|
||||
flag = drawParamsMapped(userData, actualFace);
|
||||
}
|
||||
if( flag != lastFlag ) {
|
||||
if( startFace < i ) {
|
||||
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
|
||||
if (lastFlag==1 && mcol)
|
||||
GPU_color_switch(1);
|
||||
else
|
||||
GPU_color_switch(0);
|
||||
glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
|
||||
}
|
||||
}
|
||||
lastFlag = flag;
|
||||
startFace = i;
|
||||
}
|
||||
}
|
||||
if( startFace < dm->drawObject->nelements/3 ) {
|
||||
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
|
||||
if (lastFlag==1 && mcol)
|
||||
GPU_color_switch(1);
|
||||
else
|
||||
GPU_color_switch(0);
|
||||
glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPU_buffer_unbind();
|
||||
glShadeModel( GL_FLAT );
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
|
||||
@@ -486,10 +719,15 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
|
||||
int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
|
||||
|
||||
|
||||
mc = DM_get_face_data_layer(dm, CD_ID_MCOL);
|
||||
if(!mc)
|
||||
mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
|
||||
if(!mc)
|
||||
mc = DM_get_face_data_layer(dm, CD_MCOL);
|
||||
|
||||
if( GPU_buffer_legacy(dm) ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
|
||||
for(i = 0; i < dm->numFaceData; i++, mf++) {
|
||||
int drawSmooth = (mf->flag & ME_SMOOTH);
|
||||
|
||||
@@ -515,7 +753,6 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
glNormal3fv(nors);
|
||||
}
|
||||
else {
|
||||
/* TODO make this better (cache facenormals as layer?) */
|
||||
float nor[3];
|
||||
if(mf->v4) {
|
||||
CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
|
||||
@@ -561,6 +798,54 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
|
||||
if (nors) nors += 3;
|
||||
}
|
||||
}
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
int state = 1;
|
||||
int prevstate = 1;
|
||||
int prevstart = 0;
|
||||
GPU_vertex_setup(dm);
|
||||
GPU_normal_setup(dm);
|
||||
if( useColors && mc )
|
||||
GPU_color_setup(dm);
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
|
||||
int actualFace = dm->drawObject->faceRemap[i];
|
||||
int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
|
||||
int dontdraw = 0;
|
||||
if(index) {
|
||||
orig = index[actualFace];
|
||||
if(setDrawOptions && orig == ORIGINDEX_NONE)
|
||||
dontdraw = 1;
|
||||
}
|
||||
else
|
||||
orig = i;
|
||||
if( dontdraw ) {
|
||||
state = 0;
|
||||
}
|
||||
else {
|
||||
if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
|
||||
state = 1;
|
||||
}
|
||||
else {
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
if( prevstate != state && prevstate == 1 ) {
|
||||
if( i-prevstart > 0 ) {
|
||||
glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
|
||||
}
|
||||
prevstart = i;
|
||||
}
|
||||
prevstate = state;
|
||||
}
|
||||
if(state==1) {
|
||||
glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
}
|
||||
|
||||
static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
|
||||
{
|
||||
@@ -586,9 +871,12 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
|
||||
transp = GPU_get_material_blend_mode();
|
||||
orig_transp = transp;
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
if( GPU_buffer_legacy(dm) || setDrawOptions != 0 ) {
|
||||
DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for(a = 0; a < dm->numFaceData; a++, mface++) {
|
||||
@@ -686,6 +974,206 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
|
||||
#undef PASSVERT
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
GPUBuffer *buffer = 0;
|
||||
char *varray = 0;
|
||||
int numdata = 0, elementsize = 0, offset;
|
||||
int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
|
||||
GPUAttrib datatypes[32];
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
|
||||
GPU_vertex_setup(dm);
|
||||
GPU_normal_setup(dm);
|
||||
|
||||
if( !GPU_buffer_legacy(dm) ) {
|
||||
for(a = 0; a < dm->numFaceData; a++, mface++) {
|
||||
new_matnr = mface->mat_nr + 1;
|
||||
|
||||
if(new_matnr != matnr ) {
|
||||
numfaces = curface - start;
|
||||
if( numfaces > 0 ) {
|
||||
if( prevdraw ) {
|
||||
GPU_buffer_unlock(buffer);
|
||||
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
|
||||
glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
|
||||
GPU_buffer_free(buffer,0);
|
||||
}
|
||||
}
|
||||
start = curface;
|
||||
prevdraw = dodraw;
|
||||
dodraw = setMaterial(matnr = new_matnr, &gattribs);
|
||||
if(dodraw) {
|
||||
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
|
||||
|
||||
if(attribs.totorco) {
|
||||
datatypes[numdata].index = attribs.orco.glIndex;
|
||||
datatypes[numdata].size = 3;
|
||||
datatypes[numdata].type = GL_FLOAT;
|
||||
numdata++;
|
||||
}
|
||||
for(b = 0; b < attribs.tottface; b++) {
|
||||
datatypes[numdata].index = attribs.tface[b].glIndex;
|
||||
datatypes[numdata].size = 2;
|
||||
datatypes[numdata].type = GL_FLOAT;
|
||||
numdata++;
|
||||
}
|
||||
for(b = 0; b < attribs.totmcol; b++) {
|
||||
datatypes[numdata].index = attribs.mcol[b].glIndex;
|
||||
datatypes[numdata].size = 4;
|
||||
datatypes[numdata].type = GL_UNSIGNED_BYTE;
|
||||
numdata++;
|
||||
}
|
||||
if(attribs.tottang) {
|
||||
datatypes[numdata].index = attribs.tang.glIndex;
|
||||
datatypes[numdata].size = 3;
|
||||
datatypes[numdata].type = GL_FLOAT;
|
||||
numdata++;
|
||||
}
|
||||
if( numdata != 0 ) {
|
||||
elementsize = GPU_attrib_element_size( datatypes, numdata );
|
||||
buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, 0 );
|
||||
if( buffer == 0 ) {
|
||||
GPU_buffer_unbind();
|
||||
dm->drawObject->legacy = 1;
|
||||
return;
|
||||
}
|
||||
varray = GPU_buffer_lock_stream(buffer);
|
||||
if( varray == 0 ) {
|
||||
GPU_buffer_unbind();
|
||||
GPU_buffer_free(buffer, 0);
|
||||
dm->drawObject->legacy = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!dodraw) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(tf) {
|
||||
new_transp = tf[a].transp;
|
||||
|
||||
if(new_transp != transp) {
|
||||
numfaces = curface - start;
|
||||
if( numfaces > 0 ) {
|
||||
if( dodraw ) {
|
||||
if( numdata != 0 ) {
|
||||
GPU_buffer_unlock(buffer);
|
||||
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
|
||||
if( numdata != 0 ) {
|
||||
varray = GPU_buffer_lock_stream(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
start = curface;
|
||||
|
||||
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
|
||||
GPU_set_material_blend_mode(orig_transp);
|
||||
else
|
||||
GPU_set_material_blend_mode(new_transp);
|
||||
transp = new_transp;
|
||||
}
|
||||
}
|
||||
|
||||
if( numdata != 0 ) {
|
||||
offset = 0;
|
||||
if(attribs.totorco) {
|
||||
VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
|
||||
offset += sizeof(float)*3;
|
||||
}
|
||||
for(b = 0; b < attribs.tottface; b++) {
|
||||
MTFace *tf = &attribs.tface[b].array[a];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
|
||||
offset += sizeof(float)*2;
|
||||
}
|
||||
for(b = 0; b < attribs.totmcol; b++) {
|
||||
MCol *cp = &attribs.mcol[b].array[a*4 + 0];
|
||||
GLubyte col[4];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
|
||||
cp = &attribs.mcol[b].array[a*4 + 1];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
|
||||
cp = &attribs.mcol[b].array[a*4 + 2];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
|
||||
offset += sizeof(unsigned char)*4;
|
||||
}
|
||||
if(attribs.tottang) {
|
||||
float *tang = attribs.tang.array[a*4 + 0];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
|
||||
tang = attribs.tang.array[a*4 + 1];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
|
||||
tang = attribs.tang.array[a*4 + 2];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
|
||||
offset += sizeof(float)*3;
|
||||
}
|
||||
}
|
||||
curface++;
|
||||
if(mface->v4) {
|
||||
if( numdata != 0 ) {
|
||||
offset = 0;
|
||||
if(attribs.totorco) {
|
||||
VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
|
||||
offset += sizeof(float)*3;
|
||||
}
|
||||
for(b = 0; b < attribs.tottface; b++) {
|
||||
MTFace *tf = &attribs.tface[b].array[a];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
|
||||
offset += sizeof(float)*2;
|
||||
}
|
||||
for(b = 0; b < attribs.totmcol; b++) {
|
||||
MCol *cp = &attribs.mcol[b].array[a*4 + 2];
|
||||
GLubyte col[4];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
|
||||
cp = &attribs.mcol[b].array[a*4 + 3];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
|
||||
cp = &attribs.mcol[b].array[a*4 + 0];
|
||||
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
|
||||
QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
|
||||
offset += sizeof(unsigned char)*4;
|
||||
}
|
||||
if(attribs.tottang) {
|
||||
float *tang = attribs.tang.array[a*4 + 2];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
|
||||
tang = attribs.tang.array[a*4 + 3];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
|
||||
tang = attribs.tang.array[a*4 + 0];
|
||||
VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
|
||||
offset += sizeof(float)*3;
|
||||
}
|
||||
}
|
||||
curface++;
|
||||
}
|
||||
}
|
||||
numfaces = curface - start;
|
||||
if( numfaces > 0 ) {
|
||||
if( dodraw ) {
|
||||
if( numdata != 0 ) {
|
||||
GPU_buffer_unlock(buffer);
|
||||
GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
|
||||
}
|
||||
}
|
||||
GPU_buffer_unbind();
|
||||
}
|
||||
GPU_buffer_free( buffer, 0 );
|
||||
}
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
|
||||
@@ -153,6 +153,9 @@ void cloth_init ( ClothModifierData *clmd )
|
||||
clmd->sim_parms->defgoal = 0.0f;
|
||||
clmd->sim_parms->goalspring = 1.0f;
|
||||
clmd->sim_parms->goalfrict = 0.0f;
|
||||
|
||||
if(!clmd->sim_parms->effector_weights)
|
||||
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
|
||||
}
|
||||
|
||||
static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
|
||||
@@ -403,6 +406,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
Mat4MulVecfl(ob->obmat, verts->xconst);
|
||||
}
|
||||
|
||||
effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights);
|
||||
|
||||
tstart();
|
||||
|
||||
/* call the solver. */
|
||||
@@ -411,6 +416,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
|
||||
tend();
|
||||
|
||||
pdEndEffectors(&effectors);
|
||||
|
||||
// printf ( "%f\n", ( float ) tval() );
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -692,9 +692,11 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
|
||||
}\
|
||||
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \
|
||||
ct->type = CONSTRAINT_OBTYPE_VERT; \
|
||||
ct->rotOrder = EULER_ORDER_DEFAULT; \
|
||||
} \
|
||||
else {\
|
||||
ct->type = CONSTRAINT_OBTYPE_OBJECT; \
|
||||
ct->rotOrder= ct->tar->rotmode; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
||||
@@ -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,32 +593,16 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
}
|
||||
}
|
||||
|
||||
psys_update_effectors(&sim, 0.0, 0);
|
||||
effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
|
||||
|
||||
for(nec= psys->effectors.first; nec; nec= nec->next) {
|
||||
Object *ob1= nec->ob;
|
||||
|
||||
if(nec->type & PSYS_EC_EFFECTOR) {
|
||||
node2 = dag_get_node(dag, ob1);
|
||||
if(ob1->pd->forcefield==PFIELD_GUIDE)
|
||||
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
|
||||
if(eff->psys) {
|
||||
node2 = dag_get_node(dag, eff->ob);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field");
|
||||
else
|
||||
dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Particle Field");
|
||||
}
|
||||
else if(nec->type & PSYS_EC_DEFLECT) {
|
||||
node2 = dag_get_node(dag, ob1);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Collision");
|
||||
}
|
||||
else if(nec->type & PSYS_EC_PARTICLE) {
|
||||
node2 = dag_get_node(dag, ob1);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Field");
|
||||
}
|
||||
|
||||
if(nec->type & PSYS_EC_REACTOR) {
|
||||
node2 = dag_get_node(dag, ob1);
|
||||
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Reactor");
|
||||
}
|
||||
}
|
||||
pdEndEffectors(&effectors);
|
||||
|
||||
if(part->boids) {
|
||||
for(state = part->boids->states.first; state; state=state->next) {
|
||||
@@ -1607,6 +1591,21 @@ void graph_print_adj_list(void)
|
||||
|
||||
/* ************************ API *********************** */
|
||||
|
||||
/* mechanism to allow editors to be informed of depsgraph updates,
|
||||
to do their own updates based on changes... */
|
||||
static void (*EditorsUpdateCb)(Main *bmain, ID *id)= NULL;
|
||||
|
||||
void DAG_editors_update_cb(void (*func)(Main *bmain, ID *id))
|
||||
{
|
||||
EditorsUpdateCb= func;
|
||||
}
|
||||
|
||||
static void dag_editors_update(Main *bmain, ID *id)
|
||||
{
|
||||
if(EditorsUpdateCb)
|
||||
EditorsUpdateCb(bmain, id);
|
||||
}
|
||||
|
||||
/* groups with objects in this scene need to be put in the right order as well */
|
||||
static void scene_sort_groups(Scene *sce)
|
||||
{
|
||||
@@ -2202,7 +2201,7 @@ void DAG_id_flush_update(ID *id, short flag)
|
||||
/* set flags & pointcache for object */
|
||||
if(GS(id->name) == ID_OB) {
|
||||
ob= (Object*)id;
|
||||
ob->recalc |= flag;
|
||||
ob->recalc |= (flag & OB_RECALC);
|
||||
BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
|
||||
|
||||
if(flag & OB_RECALC_DATA) {
|
||||
@@ -2239,6 +2238,23 @@ void DAG_id_flush_update(ID *id, short flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set flags based on particle settings */
|
||||
if(idtype == ID_PA) {
|
||||
ParticleSystem *psys;
|
||||
for(obt=bmain->object.first; obt; obt= obt->id.next) {
|
||||
for(psys=obt->particlesystem.first; psys; psys=psys->next) {
|
||||
if(&psys->part->id == id) {
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
obt->recalc |= (flag & OB_RECALC);
|
||||
psys->recalc |= (flag & PSYS_RECALC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update editors */
|
||||
dag_editors_update(bmain, id);
|
||||
}
|
||||
|
||||
/* flush to other objects that depend on this one */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1564,15 +1564,22 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
|
||||
return rpass;
|
||||
}
|
||||
|
||||
RenderResult *BKE_image_get_renderresult(struct Scene *scene, Image *ima)
|
||||
RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
|
||||
{
|
||||
if(ima->rr)
|
||||
return ima->rr;
|
||||
if(ima->type==IMA_TYPE_R_RESULT)
|
||||
return RE_GetResult(RE_GetRender(scene->id.name));
|
||||
else if(ima->type==IMA_TYPE_R_RESULT)
|
||||
return RE_AcquireResultRead(RE_GetRender(scene->id.name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
|
||||
{
|
||||
if(ima->rr);
|
||||
else if(ima->type==IMA_TYPE_R_RESULT)
|
||||
RE_ReleaseResult(RE_GetRender(scene->id.name));
|
||||
}
|
||||
|
||||
/* after imbuf load, openexr type can return with a exrhandle open */
|
||||
/* in that case we have to build a render-result */
|
||||
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
|
||||
@@ -1873,16 +1880,25 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
|
||||
/* showing RGBA result itself (from compo/sequence) or
|
||||
like exr, using layers etc */
|
||||
/* always returns a single ibuf, also during render progress */
|
||||
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
|
||||
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_r)
|
||||
{
|
||||
Render *re= NULL;
|
||||
RenderResult *rr= NULL;
|
||||
|
||||
/* if we the caller is not going to release the lock, don't give the image */
|
||||
if(!lock_r)
|
||||
return NULL;
|
||||
|
||||
if(iuser && iuser->scene) {
|
||||
re= RE_GetRender(iuser->scene->id.name);
|
||||
rr= RE_GetResult(re);
|
||||
rr= RE_AcquireResultRead(re);
|
||||
|
||||
/* release is done in BKE_image_release_ibuf using lock_r */
|
||||
*lock_r= re;
|
||||
}
|
||||
if(rr==NULL) return NULL;
|
||||
|
||||
if(rr==NULL)
|
||||
return NULL;
|
||||
|
||||
if(RE_RenderInProgress(re)) {
|
||||
ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
|
||||
@@ -1893,6 +1909,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
|
||||
ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
|
||||
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
|
||||
}
|
||||
|
||||
return ibuf;
|
||||
}
|
||||
else {
|
||||
@@ -1907,7 +1924,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
|
||||
pass= (iuser)? iuser->pass: 0;
|
||||
|
||||
/* this gives active layer, composite or seqence result */
|
||||
RE_GetResultImage(RE_GetRender(iuser->scene->id.name), &rres);
|
||||
RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres);
|
||||
rect= (unsigned int *)rres.rect32;
|
||||
rectf= rres.rectf;
|
||||
dither= iuser->scene->r.dither_intensity;
|
||||
@@ -1955,9 +1972,13 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
|
||||
ibuf->flags |= IB_zbuffloat;
|
||||
ibuf->dither= dither;
|
||||
|
||||
RE_ReleaseResultImage(re);
|
||||
|
||||
ima->ok= IMA_OK_LOADED;
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
RE_ReleaseResultImage(re);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2011,8 +2032,9 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
|
||||
}
|
||||
|
||||
/* Checks optional ImageUser and verifies/creates ImBuf. */
|
||||
/* returns ibuf */
|
||||
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
|
||||
/* use this one if you want to get a render result in progress,
|
||||
* if not, use BKE_image_get_ibuf which doesn't require a release */
|
||||
ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
|
||||
{
|
||||
ImBuf *ibuf= NULL;
|
||||
float color[] = {0, 0, 0, 1};
|
||||
@@ -2029,6 +2051,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
|
||||
* That means, the last two steps must be, 1) add the ibuf to the list and
|
||||
* 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
|
||||
|
||||
if(lock_r)
|
||||
*lock_r= NULL;
|
||||
|
||||
/* quick reject tests */
|
||||
if(ima==NULL)
|
||||
return NULL;
|
||||
@@ -2103,8 +2128,9 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
|
||||
}
|
||||
else if(ima->source == IMA_SRC_VIEWER) {
|
||||
if(ima->type==IMA_TYPE_R_RESULT) {
|
||||
/* always verify entirely */
|
||||
ibuf= image_get_render_result(ima, iuser);
|
||||
/* always verify entirely, and potentially
|
||||
returns pointer to release later */
|
||||
ibuf= image_get_render_result(ima, iuser, lock_r);
|
||||
}
|
||||
else if(ima->type==IMA_TYPE_COMPOSITE) {
|
||||
/* Composite Viewer, all handled in compositor */
|
||||
@@ -2126,6 +2152,17 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
void BKE_image_release_ibuf(Image *ima, void *lock)
|
||||
{
|
||||
/* for getting image during threaded render, need to release */
|
||||
if(lock)
|
||||
RE_ReleaseResult(lock);
|
||||
}
|
||||
|
||||
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
|
||||
{
|
||||
return BKE_image_acquire_ibuf(ima, iuser, NULL);
|
||||
}
|
||||
|
||||
void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "DNA_cloth_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -1482,15 +1483,19 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
int i = 0;
|
||||
float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
|
||||
float gravity[3];
|
||||
float gravity[3] = {0.0f, 0.0f, 0.0f};
|
||||
float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
|
||||
MFace *mfaces = cloth->mfaces;
|
||||
unsigned int numverts = cloth->numverts;
|
||||
LinkNode *search = cloth->springs;
|
||||
lfVector *winvec;
|
||||
EffectedPoint epoint;
|
||||
|
||||
VECCOPY(gravity, clmd->sim_parms->gravity);
|
||||
mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
|
||||
/* global acceleration (gravitation) */
|
||||
if(clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
|
||||
VECCOPY(gravity, clmd->scene->physics_settings.gravity);
|
||||
mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */
|
||||
}
|
||||
|
||||
/* set dFdX jacobi matrix to zero */
|
||||
init_bfmatrix(dFdX, ZERO);
|
||||
@@ -1526,9 +1531,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
|
||||
// precalculate wind forces
|
||||
for(i = 0; i < cloth->numverts; i++)
|
||||
{
|
||||
float speed[3] = {0.0f, 0.0f,0.0f};
|
||||
|
||||
pdDoEffectors(clmd->scene, effectors, lX[i], winvec[i], speed, frame, 0.0f, 0);
|
||||
pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint);
|
||||
pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
|
||||
}
|
||||
|
||||
for(i = 0; i < cloth->numfaces; i++)
|
||||
@@ -1656,9 +1660,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
|
||||
while(step < tf)
|
||||
{
|
||||
// calculate forces
|
||||
effectors= pdInitEffectors(clmd->scene, ob, NULL);
|
||||
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M);
|
||||
if(effectors) pdEndEffectors(effectors);
|
||||
|
||||
// calculate new velocity
|
||||
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
|
||||
@@ -1741,9 +1743,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
|
||||
cp_lfvector(id->V, id->Vnew, numverts);
|
||||
|
||||
// calculate
|
||||
effectors= pdInitEffectors(clmd->scene, ob, NULL);
|
||||
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
|
||||
if(effectors) pdEndEffectors(effectors);
|
||||
|
||||
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
|
||||
}
|
||||
|
||||
@@ -213,17 +213,17 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
|
||||
*array_index= 2; return "delta_location";
|
||||
|
||||
case OB_ROT_X:
|
||||
*array_index= 0; return "rotation";
|
||||
*array_index= 0; return "rotation_euler";
|
||||
case OB_ROT_Y:
|
||||
*array_index= 1; return "rotation";
|
||||
*array_index= 1; return "rotation_euler";
|
||||
case OB_ROT_Z:
|
||||
*array_index= 2; return "rotation";
|
||||
*array_index= 2; return "rotation_euler";
|
||||
case OB_DROT_X:
|
||||
*array_index= 0; return "delta_rotation";
|
||||
*array_index= 0; return "delta_rotation_euler";
|
||||
case OB_DROT_Y:
|
||||
*array_index= 1; return "delta_rotation";
|
||||
*array_index= 1; return "delta_rotation_euler";
|
||||
case OB_DROT_Z:
|
||||
*array_index= 2; return "delta_rotation";
|
||||
*array_index= 2; return "delta_rotation_euler";
|
||||
|
||||
case OB_SIZE_X:
|
||||
*array_index= 0; return "scale";
|
||||
@@ -281,23 +281,23 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
|
||||
/* result depends on adrcode */
|
||||
switch (adrcode) {
|
||||
case AC_QUAT_W:
|
||||
*array_index= 0; return "rotation";
|
||||
*array_index= 0; return "rotation_quaternion";
|
||||
case AC_QUAT_X:
|
||||
*array_index= 1; return "rotation";
|
||||
*array_index= 1; return "rotation_quaternion";
|
||||
case AC_QUAT_Y:
|
||||
*array_index= 2; return "rotation";
|
||||
*array_index= 2; return "rotation_quaternion";
|
||||
case AC_QUAT_Z:
|
||||
*array_index= 3; return "rotation";
|
||||
*array_index= 3; return "rotation_quaternion";
|
||||
|
||||
case AC_EUL_X:
|
||||
*array_index= 0; return "euler_rotation";
|
||||
*array_index= 0; return "rotation_euler";
|
||||
case AC_EUL_Y:
|
||||
*array_index= 1; return "euler_rotation";
|
||||
*array_index= 1; return "rotation_euler";
|
||||
case AC_EUL_Z:
|
||||
*array_index= 2; return "euler_rotation";
|
||||
*array_index= 2; return "rotation_euler";
|
||||
|
||||
case -1: /* special case for euler-rotations used by old drivers */
|
||||
*array_index= 0; return "euler_rotation";
|
||||
*array_index= 0; return "rotation_euler";
|
||||
|
||||
case AC_LOC_X:
|
||||
*array_index= 0; return "location";
|
||||
@@ -1047,10 +1047,6 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* free old driver */
|
||||
MEM_freeN(idriver);
|
||||
|
||||
/* return the new one */
|
||||
return cdriver;
|
||||
}
|
||||
@@ -1122,11 +1118,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
/* allocate memory for a new F-Curve */
|
||||
fcu= MEM_callocN(sizeof(FCurve), "FCurve");
|
||||
|
||||
/* convert driver - will free the old one... */
|
||||
if (icu->driver) {
|
||||
/* convert driver */
|
||||
if (icu->driver)
|
||||
fcu->driver= idriver_to_cdriver(icu->driver);
|
||||
icu->driver= NULL;
|
||||
}
|
||||
|
||||
/* copy flags */
|
||||
if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE;
|
||||
@@ -1233,10 +1227,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
/* add new F-Curve to list */
|
||||
fcurve_add_to_list(groups, list, fcurve, actname);
|
||||
}
|
||||
|
||||
/* free old data of curve now that it's no longer needed for converting any more curves */
|
||||
if (icu->bezt) MEM_freeN(icu->bezt);
|
||||
if (icu->bp) MEM_freeN(icu->bezt);
|
||||
}
|
||||
else {
|
||||
/* get rna-path
|
||||
@@ -1302,9 +1292,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free this data now */
|
||||
MEM_freeN(icu->bezt);
|
||||
}
|
||||
else if (icu->bp) {
|
||||
/* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
|
||||
@@ -1325,7 +1312,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
*/
|
||||
static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase *animgroups, ListBase *anim, ListBase *drivers)
|
||||
{
|
||||
IpoCurve *icu, *icn;
|
||||
IpoCurve *icu;
|
||||
|
||||
/* sanity check */
|
||||
if (ELEM3(NULL, ipo, anim, drivers))
|
||||
@@ -1347,27 +1334,46 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
|
||||
}
|
||||
|
||||
/* loop over IPO-Curves, freeing as we progress */
|
||||
for (icu= ipo->curve.first; icu; icu= icn) {
|
||||
/* get link to next (for later) */
|
||||
icn= icu->next;
|
||||
|
||||
for (icu= ipo->curve.first; icu; icu= icu->next) {
|
||||
/* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves),
|
||||
* we figure out the best place to put the channel, then tell the curve-converter to just dump there
|
||||
*/
|
||||
if (icu->driver) {
|
||||
/* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */
|
||||
if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON))
|
||||
if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
|
||||
icu_to_fcurves(NULL, drivers, icu, actname, constname);
|
||||
else
|
||||
}
|
||||
else {
|
||||
MEM_freeN(icu->driver);
|
||||
icu->driver= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
icu_to_fcurves(animgroups, anim, icu, actname, constname);
|
||||
}
|
||||
|
||||
/* free this IpoCurve now that it's been converted */
|
||||
/* if this IPO block doesn't have any users after this one, free... */
|
||||
ipo->id.us--;
|
||||
if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) )
|
||||
{
|
||||
IpoCurve *icn;
|
||||
|
||||
for (icu= ipo->curve.first; icu; icu= icn) {
|
||||
icn= icu->next;
|
||||
|
||||
/* free driver */
|
||||
if (icu->driver)
|
||||
MEM_freeN(icu->driver);
|
||||
|
||||
/* free old data of curve now that it's no longer needed for converting any more curves */
|
||||
if (icu->bezt) MEM_freeN(icu->bezt);
|
||||
if (icu->bp) MEM_freeN(icu->bezt);
|
||||
|
||||
/* free this IPO-Curve */
|
||||
BLI_freelinkN(&ipo->curve, icu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert Action-block to new system, separating animation and drivers
|
||||
* New curves may not be converted directly into the given Action (i.e. for Actions linked
|
||||
|
||||
@@ -524,30 +524,13 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
|
||||
static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
|
||||
{
|
||||
Curve *cu= par->data;
|
||||
float fac, loc[4], dir[3], cent[3], radius;
|
||||
short upflag, index;
|
||||
float fac, loc[4], dir[3], new_quat[4], radius;
|
||||
short /*upflag, */ index;
|
||||
|
||||
index= axis-1;
|
||||
if(index>2)
|
||||
index -= 3; /* negative */
|
||||
|
||||
if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
|
||||
upflag= OB_POSZ;
|
||||
cent[0]= 0.0;
|
||||
cent[1]= co[1];
|
||||
cent[2]= co[2];
|
||||
index= 0;
|
||||
}
|
||||
else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) {
|
||||
upflag= OB_POSZ;
|
||||
cent[0]= co[0];
|
||||
cent[1]= 0.0;
|
||||
cent[2]= co[2];
|
||||
index= 1;
|
||||
}
|
||||
else {
|
||||
upflag= OB_POSY;
|
||||
cent[0]= co[0];
|
||||
cent[1]= co[1];
|
||||
cent[2]= 0.0;
|
||||
index= 2;
|
||||
}
|
||||
/* to be sure, mostly after file load */
|
||||
if(cu->path==NULL) {
|
||||
makeDispListCurveTypes(scene, par, 0);
|
||||
@@ -555,7 +538,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
}
|
||||
|
||||
/* options */
|
||||
if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) {
|
||||
if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
|
||||
if(cu->flag & CU_STRETCH)
|
||||
fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
|
||||
else
|
||||
@@ -579,9 +562,10 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */
|
||||
float q[4], mat[3][3], quat[4];
|
||||
if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
|
||||
float quat[4], cent[3];
|
||||
|
||||
#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt.
|
||||
if(cd->no_rot_axis) /* set by caller */
|
||||
dir[cd->no_rot_axis-1]= 0.0f;
|
||||
|
||||
@@ -598,17 +582,99 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
q[3]= -fac*dir[2];
|
||||
QuatMul(quat, q, quat);
|
||||
}
|
||||
QuatToMat3(quat, mat);
|
||||
#endif
|
||||
|
||||
if(cu->flag & CU_PATH_RADIUS) {
|
||||
float tmat[3][3], rmat[3][3];
|
||||
Mat3Scale(tmat, radius);
|
||||
Mat3MulMat3(rmat, mat, tmat);
|
||||
Mat3CpyMat3(mat, rmat);
|
||||
|
||||
static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
|
||||
static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
|
||||
static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
|
||||
|
||||
static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
|
||||
static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
|
||||
static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
|
||||
|
||||
|
||||
if(cd->no_rot_axis) { /* set by caller */
|
||||
|
||||
/* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then
|
||||
* changing the axis before calculating the tilt but serves much the same purpose */
|
||||
float dir_flat[3]={0,0,0}, q[4];
|
||||
VECCOPY(dir_flat, dir);
|
||||
dir_flat[cd->no_rot_axis-1]= 0.0f;
|
||||
|
||||
Normalize(dir);
|
||||
Normalize(dir_flat);
|
||||
|
||||
RotationBetweenVectorsToQuat(q, dir, dir_flat); /* Could this be done faster? */
|
||||
|
||||
QuatMul(new_quat, q, new_quat);
|
||||
}
|
||||
|
||||
|
||||
/* Logic for 'cent' orientation *
|
||||
*
|
||||
* The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
|
||||
*
|
||||
* Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
|
||||
* view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
|
||||
* Notice X,Y,Z Up all have light colors and each ordered CCW.
|
||||
*
|
||||
* Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
|
||||
* */
|
||||
|
||||
switch(axis) {
|
||||
case MOD_CURVE_POSX:
|
||||
QuatMul(quat, new_quat, q_y90d);
|
||||
|
||||
cent[0]= 0.0;
|
||||
cent[1]= co[2];
|
||||
cent[2]= co[1];
|
||||
break;
|
||||
case MOD_CURVE_NEGX:
|
||||
QuatMul(quat, new_quat, q_ny90d);
|
||||
|
||||
cent[0]= 0.0;
|
||||
cent[1]= -co[1];
|
||||
cent[2]= co[2];
|
||||
|
||||
break;
|
||||
case MOD_CURVE_POSY:
|
||||
QuatMul(quat, new_quat, q_x90d);
|
||||
|
||||
cent[0]= co[2];
|
||||
cent[1]= 0.0;
|
||||
cent[2]= -co[0];
|
||||
break;
|
||||
case MOD_CURVE_NEGY:
|
||||
QuatMul(quat, new_quat, q_nx90d);
|
||||
|
||||
cent[0]= -co[0];
|
||||
cent[1]= 0.0;
|
||||
cent[2]= -co[2];
|
||||
break;
|
||||
case MOD_CURVE_POSZ:
|
||||
QuatMul(quat, new_quat, q_z90d);
|
||||
|
||||
cent[0]= co[1];
|
||||
cent[1]= -co[0];
|
||||
cent[2]= 0.0;
|
||||
break;
|
||||
case MOD_CURVE_NEGZ:
|
||||
QuatMul(quat, new_quat, q_nz90d);
|
||||
|
||||
cent[0]= co[0];
|
||||
cent[1]= -co[1];
|
||||
cent[2]= 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* scale if enabled */
|
||||
if(cu->flag & CU_PATH_RADIUS)
|
||||
VecMulf(cent, radius);
|
||||
|
||||
/* local rotation */
|
||||
Mat3MulVecfl(mat, cent);
|
||||
NormalQuat(quat);
|
||||
QuatMulVecf(quat, cent);
|
||||
|
||||
/* translation */
|
||||
VECADD(co, cent, loc);
|
||||
|
||||
@@ -640,42 +640,15 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
|
||||
}
|
||||
|
||||
/* by spec, animdata is first item after ID */
|
||||
/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
|
||||
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
|
||||
static void id_copy_animdata(ID *id)
|
||||
{
|
||||
switch(GS(id->name)) {
|
||||
case ID_OB:
|
||||
((Object *)id)->adt= BKE_copy_animdata(((Object *)id)->adt);
|
||||
break;
|
||||
case ID_CU:
|
||||
((Curve *)id)->adt= BKE_copy_animdata(((Curve *)id)->adt);
|
||||
break;
|
||||
case ID_CA:
|
||||
((Camera *)id)->adt= BKE_copy_animdata(((Camera *)id)->adt);
|
||||
break;
|
||||
case ID_KE:
|
||||
((Key *)id)->adt= BKE_copy_animdata(((Key *)id)->adt);
|
||||
break;
|
||||
case ID_LA:
|
||||
((Lamp *)id)->adt= BKE_copy_animdata(((Lamp *)id)->adt);
|
||||
break;
|
||||
case ID_MA:
|
||||
((Material *)id)->adt= BKE_copy_animdata(((Material *)id)->adt);
|
||||
break;
|
||||
case ID_NT:
|
||||
((bNodeTree *)id)->adt= BKE_copy_animdata(((bNodeTree *)id)->adt);
|
||||
break;
|
||||
case ID_SCE:
|
||||
((Scene *)id)->adt= BKE_copy_animdata(((Scene *)id)->adt);
|
||||
break;
|
||||
case ID_TE:
|
||||
((Tex *)id)->adt= BKE_copy_animdata(((Tex *)id)->adt);
|
||||
break;
|
||||
case ID_WO:
|
||||
((World *)id)->adt= BKE_copy_animdata(((World *)id)->adt);
|
||||
break;
|
||||
}
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
|
||||
if (adt) {
|
||||
IdAdtTemplate *iat = (IdAdtTemplate *)id;
|
||||
iat->adt= BKE_copy_animdata(iat->adt);
|
||||
}
|
||||
}
|
||||
|
||||
/* used everywhere in blenkernel and text.c */
|
||||
@@ -706,7 +679,8 @@ void *copy_libblock(void *rt)
|
||||
idn->flag |= LIB_NEW;
|
||||
if (id->properties) idn->properties = IDP_CopyProperty(id->properties);
|
||||
|
||||
id_copy_animdata(id);
|
||||
/* the duplicate should get a copy of the animdata */
|
||||
id_copy_animdata(idn);
|
||||
|
||||
return idn;
|
||||
}
|
||||
|
||||
@@ -172,15 +172,15 @@ void init_material(Material *ma)
|
||||
|
||||
ma->vol.density = 1.0f;
|
||||
ma->vol.emission = 0.0f;
|
||||
ma->vol.absorption = 1.0f;
|
||||
ma->vol.scattering = 1.0f;
|
||||
ma->vol.reflection = 1.0f;
|
||||
ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f;
|
||||
ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f;
|
||||
ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
|
||||
ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
|
||||
ma->vol.density_scale = 1.0f;
|
||||
ma->vol.depth_cutoff = 0.01f;
|
||||
ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
|
||||
ma->vol.stepsize = 0.2f;
|
||||
ma->vol.shade_stepsize = 0.2f;
|
||||
ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
|
||||
ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
|
||||
ma->vol.precache_resolution = 50;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -127,8 +128,8 @@ void clear_workob(Object *workob)
|
||||
{
|
||||
memset(workob, 0, sizeof(Object));
|
||||
|
||||
workob->size[0]= workob->size[1]= workob->size[2]= 1.0;
|
||||
|
||||
workob->size[0]= workob->size[1]= workob->size[2]= 1.0f;
|
||||
workob->rotmode= ROT_MODE_EUL;
|
||||
}
|
||||
|
||||
void copy_baseflags(struct Scene *scene)
|
||||
@@ -298,11 +299,8 @@ void free_object(Object *ob)
|
||||
|
||||
free_constraints(&ob->constraints);
|
||||
|
||||
if(ob->pd){
|
||||
if(ob->pd->tex)
|
||||
ob->pd->tex->id.us--;
|
||||
MEM_freeN(ob->pd);
|
||||
}
|
||||
free_partdeflect(ob->pd);
|
||||
|
||||
if(ob->soft) sbFree(ob->soft);
|
||||
if(ob->bsoft) bsbFree(ob->bsoft);
|
||||
if(ob->gpulamp.first) GPU_lamp_free(ob);
|
||||
@@ -1039,6 +1037,11 @@ Object *add_object(struct Scene *scene, int type)
|
||||
|
||||
ob->lay= scene->lay;
|
||||
|
||||
/* objects should default to having Euler XYZ rotations,
|
||||
* but rotations default to quaternions
|
||||
*/
|
||||
ob->rotmode= ROT_MODE_EUL;
|
||||
|
||||
base= scene_add_base(scene, ob);
|
||||
scene_select_base(scene, base);
|
||||
ob->recalc |= OB_RECALC;
|
||||
@@ -1064,6 +1067,9 @@ SoftBody *copy_softbody(SoftBody *sb)
|
||||
|
||||
sbn->pointcache= BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
|
||||
|
||||
if(sb->effector_weights)
|
||||
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
|
||||
|
||||
return sbn;
|
||||
}
|
||||
|
||||
@@ -1124,11 +1130,9 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
|
||||
psysn->pathcache= NULL;
|
||||
psysn->childcache= NULL;
|
||||
psysn->edit= NULL;
|
||||
psysn->effectors.first= psysn->effectors.last= 0;
|
||||
|
||||
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
|
||||
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
|
||||
psysn->reactevents.first = psysn->reactevents.last = NULL;
|
||||
psysn->renderdata = NULL;
|
||||
|
||||
psysn->pointcache= BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
|
||||
@@ -1263,7 +1267,7 @@ Object *copy_object(Object *ob)
|
||||
/* increase user numbers */
|
||||
id_us_plus((ID *)obn->data);
|
||||
id_us_plus((ID *)obn->dup_group);
|
||||
// FIXME: add this for animdata too...
|
||||
|
||||
|
||||
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
|
||||
|
||||
@@ -1273,6 +1277,8 @@ Object *copy_object(Object *ob)
|
||||
obn->pd= MEM_dupallocN(ob->pd);
|
||||
if(obn->pd->tex)
|
||||
id_us_plus(&(obn->pd->tex->id));
|
||||
if(obn->pd->rng)
|
||||
obn->pd->rng = MEM_dupallocN(ob->pd->rng);
|
||||
}
|
||||
obn->soft= copy_softbody(ob->soft);
|
||||
obn->bsoft = copy_bulletsoftbody(ob->bsoft);
|
||||
@@ -1582,12 +1588,34 @@ void object_scale_to_mat3(Object *ob, float mat[][3])
|
||||
// TODO: this should take rotation orders into account later...
|
||||
void object_rot_to_mat3(Object *ob, float mat[][3])
|
||||
{
|
||||
float vec[3];
|
||||
float rmat[3][3], dmat[3][3];
|
||||
|
||||
vec[0]= ob->rot[0]+ob->drot[0];
|
||||
vec[1]= ob->rot[1]+ob->drot[1];
|
||||
vec[2]= ob->rot[2]+ob->drot[2];
|
||||
EulToMat3(vec, mat);
|
||||
/* initialise the delta-rotation matrix, which will get (pre)multiplied
|
||||
* with the rotation matrix to yield the appropriate rotation
|
||||
*/
|
||||
Mat3One(dmat);
|
||||
|
||||
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
|
||||
if (ob->rotmode > 0) {
|
||||
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
|
||||
EulOToMat3(ob->rot, ob->rotmode, rmat);
|
||||
EulOToMat3(ob->drot, ob->rotmode, dmat);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
|
||||
AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat);
|
||||
AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat);
|
||||
}
|
||||
else {
|
||||
/* quats are normalised before use to eliminate scaling issues */
|
||||
NormalQuat(ob->quat);
|
||||
QuatToMat3(ob->quat, rmat);
|
||||
QuatToMat3(ob->dquat, dmat);
|
||||
}
|
||||
|
||||
/* combine these rotations */
|
||||
// XXX is this correct? if errors, change the order of multiplication...
|
||||
Mat3MulMat3(mat, dmat, rmat);
|
||||
}
|
||||
|
||||
void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
|
||||
@@ -1600,14 +1628,7 @@ void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
|
||||
object_scale_to_mat3(ob, smat);
|
||||
|
||||
/* rot */
|
||||
/* Quats arnt used yet */
|
||||
/*if(ob->transflag & OB_QUAT) {
|
||||
QuatMul(q1, ob->quat, ob->dquat);
|
||||
QuatToMat3(q1, rmat);
|
||||
}
|
||||
else {*/
|
||||
object_rot_to_mat3(ob, rmat);
|
||||
/*}*/
|
||||
Mat3MulMat3(mat, rmat, smat);
|
||||
}
|
||||
|
||||
@@ -1902,31 +1923,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
|
||||
|
||||
if(ob==NULL) return;
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
/* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
|
||||
stime= bsystem_time(scene, ob, ctime, 0.0);
|
||||
if(stime != ob->ctime) {
|
||||
|
||||
ob->ctime= stime;
|
||||
|
||||
if(ob->ipo) {
|
||||
calc_ipo(ob->ipo, stime);
|
||||
execute_ipo((ID *)ob, ob->ipo);
|
||||
}
|
||||
else
|
||||
do_all_object_actions(scene, ob);
|
||||
|
||||
/* do constraint ipos ..., note it needs stime (0 = all ipos) */
|
||||
do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0);
|
||||
}
|
||||
else {
|
||||
/* but, the drivers have to be done */
|
||||
if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime);
|
||||
/* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */
|
||||
do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* execute drivers only, as animation has already been done */
|
||||
BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_kdtree.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
|
||||
#include "BKE_boids.h"
|
||||
#include "BKE_cloth.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_lattice.h"
|
||||
@@ -96,8 +97,7 @@ int count_particles(ParticleSystem *psys){
|
||||
int tot=0;
|
||||
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
if(pa->alive == PARS_KILLED);
|
||||
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
|
||||
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
|
||||
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
|
||||
else tot++;
|
||||
}
|
||||
@@ -109,8 +109,7 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
|
||||
int tot=0;
|
||||
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
if(pa->alive == PARS_KILLED);
|
||||
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
|
||||
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0);
|
||||
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0);
|
||||
else if(p%totgr==cur) tot++;
|
||||
}
|
||||
@@ -302,15 +301,11 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
|
||||
/************************************************/
|
||||
void psys_free_settings(ParticleSettings *part)
|
||||
{
|
||||
if(part->pd) {
|
||||
MEM_freeN(part->pd);
|
||||
part->pd = NULL;
|
||||
}
|
||||
free_partdeflect(part->pd);
|
||||
free_partdeflect(part->pd2);
|
||||
|
||||
if(part->pd2) {
|
||||
MEM_freeN(part->pd2);
|
||||
part->pd2 = NULL;
|
||||
}
|
||||
if(part->effector_weights)
|
||||
MEM_freeN(part->effector_weights);
|
||||
|
||||
boid_free_settings(part->boids);
|
||||
}
|
||||
@@ -428,6 +423,7 @@ void psys_free_particles(ParticleSystem *psys)
|
||||
}
|
||||
void psys_free_pdd(ParticleSystem *psys)
|
||||
{
|
||||
if(psys->pdd) {
|
||||
if(psys->pdd->cdata)
|
||||
MEM_freeN(psys->pdd->cdata);
|
||||
psys->pdd->cdata = NULL;
|
||||
@@ -444,6 +440,7 @@ void psys_free_pdd(ParticleSystem *psys)
|
||||
MEM_freeN(psys->pdd->vedata);
|
||||
psys->pdd->vedata = NULL;
|
||||
}
|
||||
}
|
||||
/* free everything */
|
||||
void psys_free(Object *ob, ParticleSystem * psys)
|
||||
{
|
||||
@@ -466,9 +463,6 @@ void psys_free(Object *ob, ParticleSystem * psys)
|
||||
psys->totchild = 0;
|
||||
}
|
||||
|
||||
if(psys->effectors.first)
|
||||
psys_end_effectors(psys);
|
||||
|
||||
// check if we are last non-visible particle system
|
||||
for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){
|
||||
if(tpsys->part)
|
||||
@@ -493,10 +487,11 @@ void psys_free(Object *ob, ParticleSystem * psys)
|
||||
psys->pointcache = NULL;
|
||||
|
||||
BLI_freelistN(&psys->targets);
|
||||
BLI_freelistN(&psys->reactevents);
|
||||
|
||||
BLI_kdtree_free(psys->tree);
|
||||
|
||||
pdEndEffectors(&psys->effectors);
|
||||
|
||||
if(psys->frand)
|
||||
MEM_freeN(psys->frand);
|
||||
|
||||
@@ -1896,125 +1891,136 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu
|
||||
VecLerpf(state->co,state->co,par->co,clump);
|
||||
}
|
||||
}
|
||||
|
||||
int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb)
|
||||
void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
|
||||
{
|
||||
EffectedPoint point;
|
||||
ParticleKey state;
|
||||
EffectorData efd;
|
||||
EffectorCache *eff;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
EffectorWeights *weights = sim->psys->part->effector_weights;
|
||||
GuideEffectorData *data;
|
||||
PARTICLE_P;
|
||||
|
||||
if(!effectors)
|
||||
return;
|
||||
|
||||
LOOP_PARTICLES {
|
||||
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0);
|
||||
pd_point_from_particle(sim, pa, &state, &point);
|
||||
|
||||
for(eff = effectors->first; eff; eff=eff->next) {
|
||||
if(eff->pd->forcefield != PFIELD_GUIDE)
|
||||
continue;
|
||||
|
||||
if(!eff->guide_data)
|
||||
eff->guide_data = MEM_callocN(sizeof(GuideEffectorData)*psys->totpart, "GuideEffectorData");
|
||||
|
||||
data = eff->guide_data + p;
|
||||
|
||||
VECSUB(efd.vec_to_point, state.co, eff->guide_loc);
|
||||
VECCOPY(efd.nor, eff->guide_dir);
|
||||
efd.distance = VecLength(efd.vec_to_point);
|
||||
|
||||
VECCOPY(data->vec_to_point, efd.vec_to_point);
|
||||
data->strength = effector_falloff(eff, &efd, &point, weights);
|
||||
}
|
||||
}
|
||||
}
|
||||
int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
|
||||
{
|
||||
EffectorCache *eff;
|
||||
PartDeflect *pd;
|
||||
ParticleEffectorCache *ec;
|
||||
Object *eob;
|
||||
Curve *cu;
|
||||
ParticleKey key, par;
|
||||
GuideEffectorData *data;
|
||||
|
||||
float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0;
|
||||
float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f};
|
||||
float veffect[3]={0.0,0.0,0.0}, guidetime;
|
||||
float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
|
||||
float guidevec[4], guidedir[3], rot2[4], temp[3];
|
||||
float guidetime, radius, angle, totstrength = 0.0f;
|
||||
float vec_to_point[3];
|
||||
|
||||
effect[0]=effect[1]=effect[2]=0.0;
|
||||
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
|
||||
pd = eff->pd;
|
||||
|
||||
if(lb->first){
|
||||
for(ec = lb->first; ec; ec= ec->next){
|
||||
eob= ec->ob;
|
||||
if(ec->type & PSYS_EC_EFFECTOR){
|
||||
pd=eob->pd;
|
||||
if(pd->forcefield==PFIELD_GUIDE){
|
||||
cu = (Curve*)eob->data;
|
||||
if(pd->forcefield != PFIELD_GUIDE)
|
||||
continue;
|
||||
|
||||
distance=ec->distances[pa_num];
|
||||
mindist=pd->f_strength;
|
||||
data = eff->guide_data + index;
|
||||
|
||||
VECCOPY(pa_loc, ec->locations+3*pa_num);
|
||||
VECCOPY(pa_zero,pa_loc);
|
||||
VECADD(pa_zero,pa_zero,ec->firstloc);
|
||||
if(data->strength <= 0.0f)
|
||||
continue;
|
||||
|
||||
guidetime = time / (1.0 - pd->free_end);
|
||||
|
||||
/* WARNING: bails out with continue here */
|
||||
if(((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) || guidetime>1.0f) continue;
|
||||
if(guidetime>1.0f)
|
||||
continue;
|
||||
|
||||
if(guidetime>1.0f) continue;
|
||||
cu = (Curve*)eff->ob->data;
|
||||
|
||||
/* calculate contribution factor for this guide */
|
||||
f_force=1.0f;
|
||||
if(distance<=mindist);
|
||||
else if(pd->flag & PFIELD_USEMAX) {
|
||||
if(mindist>=pd->maxdist) f_force= 0.0f;
|
||||
else if(pd->f_power!=0.0f){
|
||||
f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
|
||||
f_force = (float)pow(f_force, pd->f_power);
|
||||
if(pd->flag & PFIELD_GUIDE_PATH_ADD) {
|
||||
if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(pd->f_power!=0.0f){
|
||||
f_force= 1.0f/(1.0f + distance-mindist);
|
||||
f_force = (float)pow(f_force, pd->f_power);
|
||||
else {
|
||||
if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pd->flag & PFIELD_GUIDE_PATH_ADD)
|
||||
where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius);
|
||||
else
|
||||
where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius);
|
||||
|
||||
Mat4MulVecfl(ec->ob->obmat,guidevec);
|
||||
Mat4Mul3Vecfl(ec->ob->obmat,guidedir);
|
||||
Mat4MulVecfl(eff->ob->obmat, guidevec);
|
||||
Mat4Mul3Vecfl(eff->ob->obmat, guidedir);
|
||||
|
||||
Normalize(guidedir);
|
||||
|
||||
VECCOPY(vec_to_point, data->vec_to_point);
|
||||
|
||||
if(guidetime != 0.0){
|
||||
/* curve direction */
|
||||
Crossf(temp, ec->firstdir, guidedir);
|
||||
angle=Inpf(ec->firstdir,guidedir)/(VecLength(ec->firstdir));
|
||||
Crossf(temp, eff->guide_dir, guidedir);
|
||||
angle = Inpf(eff->guide_dir, guidedir)/(VecLength(eff->guide_dir));
|
||||
angle = saacos(angle);
|
||||
VecRotToQuat(temp, angle, rot2);
|
||||
QuatMulVecf(rot2,pa_loc);
|
||||
QuatMulVecf(rot2, vec_to_point);
|
||||
|
||||
/* curve tilt */
|
||||
VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2);
|
||||
QuatMulVecf(rot2,pa_loc);
|
||||
|
||||
//vectoquat(guidedir, pd->kink_axis, (pd->kink_axis+1)%3, q);
|
||||
//QuatMul(par.rot,rot2,q);
|
||||
VecRotToQuat(guidedir, guidevec[3] - eff->guide_loc[3], rot2);
|
||||
QuatMulVecf(rot2, vec_to_point);
|
||||
}
|
||||
//else{
|
||||
// par.rot[0]=1.0f;
|
||||
// par.rot[1]=par.rot[2]=par.rot[3]=0.0f;
|
||||
//}
|
||||
|
||||
/* curve taper */
|
||||
if(cu->taperobj)
|
||||
VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
|
||||
VecMulf(vec_to_point, calc_taper(eff->scene, cu->taperobj, (int)(data->strength*guidetime*100.0), 100));
|
||||
|
||||
else{ /* curve size*/
|
||||
if(cu->flag & CU_PATH_RADIUS) {
|
||||
VecMulf(pa_loc, radius);
|
||||
VecMulf(vec_to_point, radius);
|
||||
}
|
||||
}
|
||||
par.co[0] = par.co[1] = par.co[2] = 0.0f;
|
||||
VECCOPY(key.co,pa_loc);
|
||||
VECCOPY(key.co, vec_to_point);
|
||||
do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0);
|
||||
do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
|
||||
VECCOPY(pa_loc,key.co);
|
||||
VECCOPY(vec_to_point, key.co);
|
||||
|
||||
VECADD(pa_loc,pa_loc,guidevec);
|
||||
VECSUB(pa_loc,pa_loc,pa_zero);
|
||||
VECADDFAC(effect,effect,pa_loc,f_force);
|
||||
VECADDFAC(veffect,veffect,guidedir,f_force);
|
||||
totforce+=f_force;
|
||||
}
|
||||
}
|
||||
VECADD(vec_to_point, vec_to_point, guidevec);
|
||||
//VECSUB(pa_loc,pa_loc,pa_zero);
|
||||
VECADDFAC(effect, effect, vec_to_point, data->strength);
|
||||
VECADDFAC(veffect, veffect, guidedir, data->strength);
|
||||
totstrength += data->strength;
|
||||
}
|
||||
|
||||
if(totforce!=0.0){
|
||||
if(totforce>1.0)
|
||||
VecMulf(effect,1.0f/totforce);
|
||||
CLAMP(totforce,0.0,1.0);
|
||||
VECADD(effect,effect,pa_zero);
|
||||
VecLerpf(state->co,state->co,effect,totforce);
|
||||
if(totstrength != 0.0){
|
||||
if(totstrength > 1.0)
|
||||
VecMulf(effect, 1.0f / totstrength);
|
||||
CLAMP(totstrength, 0.0, 1.0);
|
||||
//VECADD(effect,effect,pa_zero);
|
||||
VecLerpf(state->co, state->co, effect, totstrength);
|
||||
|
||||
Normalize(veffect);
|
||||
VecMulf(veffect, VecLength(state->vel));
|
||||
VECCOPY(state->vel, veffect);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static void do_rough(float *loc, float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
|
||||
@@ -2051,16 +2057,20 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
|
||||
}
|
||||
static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
|
||||
{
|
||||
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
|
||||
float force[3] = {0.0f,0.0f,0.0f};
|
||||
ParticleKey eff_key;
|
||||
ParticleData *pa;
|
||||
EffectedPoint epoint;
|
||||
|
||||
/* Don't apply effectors for dynamic hair, otherwise the effectors don't get applied twice. */
|
||||
if(sim->psys->flag & PSYS_HAIR_DYNAMICS)
|
||||
return;
|
||||
|
||||
VECCOPY(eff_key.co,(ca-1)->co);
|
||||
VECCOPY(eff_key.vel,(ca-1)->vel);
|
||||
QUATCOPY(eff_key.rot,(ca-1)->rot);
|
||||
|
||||
pa= sim->psys->particles+i;
|
||||
do_effectors(sim, i, pa, &eff_key, rootco, force, vel, dfra, cfra);
|
||||
pd_point_from_particle(sim, sim->psys->particles+i, &eff_key, &epoint);
|
||||
pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL);
|
||||
|
||||
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps);
|
||||
|
||||
@@ -2777,9 +2787,9 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
|
||||
do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec);
|
||||
|
||||
/* apply guide curves to path data */
|
||||
if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
|
||||
if(sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT)==0)
|
||||
/* ca is safe to cast, since only co and vel are used */
|
||||
do_guide(sim->scene, (ParticleKey*)ca, p, (float)k/(float)steps, &psys->effectors);
|
||||
do_guides(sim->psys->effectors, (ParticleKey*)ca, p, (float)k/(float)steps);
|
||||
|
||||
/* apply lattice */
|
||||
if(psys->lattice)
|
||||
@@ -3187,8 +3197,6 @@ void object_remove_particle_system(Scene *scene, Object *ob)
|
||||
}
|
||||
static void default_particle_settings(ParticleSettings *part)
|
||||
{
|
||||
int i;
|
||||
|
||||
part->type= PART_EMITTER;
|
||||
part->distr= PART_DISTR_JIT;
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
@@ -3199,7 +3207,7 @@ static void default_particle_settings(ParticleSettings *part)
|
||||
part->flag=PART_REACT_MULTIPLE|PART_HAIR_GEOMETRY|PART_EDISTR|PART_TRAND;
|
||||
|
||||
part->sta= 1.0;
|
||||
part->end= 100.0;
|
||||
part->end= 200.0;
|
||||
part->lifetime= 50.0;
|
||||
part->jitfac= 1.0;
|
||||
part->totpart= 1000;
|
||||
@@ -3249,10 +3257,6 @@ static void default_particle_settings(ParticleSettings *part)
|
||||
|
||||
part->keyed_loops = 1;
|
||||
|
||||
for(i=0; i<10; i++)
|
||||
part->effector_weight[i]=1.0f;
|
||||
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
part->ipo = NULL;
|
||||
#endif // XXX old animation system
|
||||
@@ -3261,6 +3265,9 @@ static void default_particle_settings(ParticleSettings *part)
|
||||
part->simplify_rate= 1.0f;
|
||||
part->simplify_transition= 0.1f;
|
||||
part->simplify_viewport= 0.8;
|
||||
|
||||
if(!part->effector_weights)
|
||||
part->effector_weights = BKE_add_effector_weights(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -3348,24 +3355,6 @@ void make_local_particlesettings(ParticleSettings *part)
|
||||
}
|
||||
}
|
||||
}
|
||||
void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
|
||||
{
|
||||
Base *base = scene->base.first;
|
||||
ParticleSystem *psys;
|
||||
int flush;
|
||||
|
||||
for(base = scene->base.first; base; base = base->next) {
|
||||
flush = 0;
|
||||
for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
|
||||
if(psys->part == part) {
|
||||
psys->recalc |= recalc;
|
||||
flush++;
|
||||
}
|
||||
}
|
||||
if(flush)
|
||||
DAG_id_flush_update(&base->object->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Textures */
|
||||
@@ -3421,9 +3410,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
mtex=ma->mtex[m];
|
||||
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
|
||||
float def=mtex->def_var;
|
||||
float var=mtex->varfac;
|
||||
short blend=mtex->blendtype;
|
||||
short neg=mtex->pmaptoneg;
|
||||
|
||||
if((mtex->texco & TEXCO_UV) && fw) {
|
||||
if(!get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texco))
|
||||
@@ -3438,18 +3425,18 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
ptex->time=0.0;
|
||||
setvars|=MAP_PA_TIME;
|
||||
}
|
||||
ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,var,blend,neg & MAP_PA_TIME);
|
||||
ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,mtex->timefac,blend);
|
||||
}
|
||||
if((event & mtex->pmapto) & MAP_PA_LENGTH)
|
||||
ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
|
||||
ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_CLUMP)
|
||||
ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
|
||||
ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_KINK)
|
||||
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
|
||||
ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_ROUGH)
|
||||
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,var,blend,neg & MAP_PA_ROUGH);
|
||||
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,mtex->roughfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_DENS)
|
||||
ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
|
||||
ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
|
||||
}
|
||||
}
|
||||
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
|
||||
@@ -3473,10 +3460,8 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
|
||||
if(ma) for(m=0; m<MAX_MTEX; m++){
|
||||
mtex=ma->mtex[m];
|
||||
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
|
||||
float var=mtex->varfac;
|
||||
float def=mtex->def_var;
|
||||
short blend=mtex->blendtype;
|
||||
short neg=mtex->pmaptoneg;
|
||||
|
||||
if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
|
||||
if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
|
||||
@@ -3493,29 +3478,31 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
|
||||
if((event & mtex->pmapto) & MAP_PA_TIME){
|
||||
/* the first time has to set the base value for time regardless of blend mode */
|
||||
if((setvars&MAP_PA_TIME)==0){
|
||||
ptex->time *= 1.0f - var;
|
||||
ptex->time += var * ((neg & MAP_PA_TIME)? 1.0f - value : value);
|
||||
int flip= (mtex->timefac < 0.0f);
|
||||
float timefac= fabsf(mtex->timefac);
|
||||
ptex->time *= 1.0f - timefac;
|
||||
ptex->time += timefac * ((flip)? 1.0f - value : value);
|
||||
setvars |= MAP_PA_TIME;
|
||||
}
|
||||
else
|
||||
ptex->time= texture_value_blend(def,ptex->time,value,var,blend,neg & MAP_PA_TIME);
|
||||
ptex->time= texture_value_blend(def,ptex->time,value,mtex->timefac,blend);
|
||||
}
|
||||
if((event & mtex->pmapto) & MAP_PA_LIFE)
|
||||
ptex->life= texture_value_blend(def,ptex->life,value,var,blend,neg & MAP_PA_LIFE);
|
||||
ptex->life= texture_value_blend(def,ptex->life,value,mtex->lifefac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_DENS)
|
||||
ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
|
||||
ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_SIZE)
|
||||
ptex->size= texture_value_blend(def,ptex->size,value,var,blend,neg & MAP_PA_SIZE);
|
||||
ptex->size= texture_value_blend(def,ptex->size,value,mtex->sizefac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_IVEL)
|
||||
ptex->ivel= texture_value_blend(def,ptex->ivel,value,var,blend,neg & MAP_PA_IVEL);
|
||||
ptex->ivel= texture_value_blend(def,ptex->ivel,value,mtex->ivelfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_PVEL)
|
||||
texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,var,blend);
|
||||
texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,mtex->pvelfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_LENGTH)
|
||||
ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
|
||||
ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_CLUMP)
|
||||
ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
|
||||
ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
|
||||
if((event & mtex->pmapto) & MAP_PA_KINK)
|
||||
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_CLUMP);
|
||||
ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
|
||||
}
|
||||
}
|
||||
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
|
||||
@@ -3646,7 +3633,7 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte
|
||||
|
||||
if(part->flag & PART_CHILD_EFFECT)
|
||||
/* state is safe to cast, since only co and vel are used */
|
||||
guided = do_guide(sim->scene, (ParticleKey*)state, cpa->parent, t, &(sim->psys->effectors));
|
||||
guided = do_guides(sim->psys->effectors, (ParticleKey*)state, cpa->parent, t);
|
||||
|
||||
if(guided==0){
|
||||
if(part->kink)
|
||||
@@ -3716,8 +3703,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
|
||||
Mat4MulVecfl(hairmat, state->co);
|
||||
Mat4Mul3Vecfl(hairmat, state->vel);
|
||||
|
||||
if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
|
||||
do_guide(sim->scene, state, p, state->time, &psys->effectors);
|
||||
if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) {
|
||||
do_guides(sim->psys->effectors, state, p, state->time);
|
||||
/* TODO: proper velocity handling */
|
||||
}
|
||||
|
||||
@@ -3905,8 +3892,6 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
|
||||
}
|
||||
|
||||
if(pa) {
|
||||
if(pa->alive == PARS_KILLED) return 0;
|
||||
|
||||
if(!always)
|
||||
if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
|
||||
|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_kdtree.h"
|
||||
#include "BLI_kdopbvh.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_anim.h"
|
||||
@@ -132,9 +132,6 @@ void psys_reset(ParticleSystem *psys, int mode)
|
||||
psys->totkeyed= 0;
|
||||
psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
|
||||
|
||||
if(psys->reactevents.first)
|
||||
BLI_freelistN(&psys->reactevents);
|
||||
|
||||
if(psys->edit && psys->free_edit) {
|
||||
psys->free_edit(psys->edit);
|
||||
psys->edit = NULL;
|
||||
@@ -1796,8 +1793,9 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
||||
/* and gravity in r_ve */
|
||||
bpa->gravity[0] = bpa->gravity[1] = 0.0f;
|
||||
bpa->gravity[2] = -1.0f;
|
||||
if(part->acc[2]!=0.0f)
|
||||
bpa->gravity[2] = part->acc[2];
|
||||
if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
|
||||
&& sim->scene->physics_settings.gravity[2]!=0.0f)
|
||||
bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
|
||||
|
||||
/* calculate rotation matrix */
|
||||
Projf(dvec, r_vel, pa->state.ave);
|
||||
@@ -1936,8 +1934,12 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
||||
|
||||
pa->dietime = pa->time + pa->lifetime;
|
||||
|
||||
if(pa->time >= cfra)
|
||||
if(pa->time > cfra)
|
||||
pa->alive = PARS_UNBORN;
|
||||
else if(pa->dietime <= cfra)
|
||||
pa->alive = PARS_DEAD;
|
||||
else
|
||||
pa->alive = PARS_ALIVE;
|
||||
|
||||
pa->state.time = cfra;
|
||||
}
|
||||
@@ -2203,556 +2205,37 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
|
||||
/************************************************/
|
||||
/* Effectors */
|
||||
/************************************************/
|
||||
static void update_particle_tree(ParticleSystem *psys)
|
||||
void psys_update_particle_tree(ParticleSystem *psys, float cfra)
|
||||
{
|
||||
if(psys) {
|
||||
PARTICLE_P;
|
||||
|
||||
if(!psys->tree || psys->tree_frame != psys->cfra) {
|
||||
if(!psys->tree || psys->tree_frame != cfra) {
|
||||
|
||||
BLI_kdtree_free(psys->tree);
|
||||
|
||||
psys->tree = BLI_kdtree_new(psys->totpart);
|
||||
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
if(pa->alive == PARS_ALIVE)
|
||||
if(pa->alive == PARS_ALIVE) {
|
||||
if(pa->state.time == cfra)
|
||||
BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
|
||||
else
|
||||
BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
|
||||
}
|
||||
}
|
||||
BLI_kdtree_balance(psys->tree);
|
||||
|
||||
psys->tree_frame = psys->cfra;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
|
||||
|
||||
static void psys_update_effectors(ParticleSimulationData *sim)
|
||||
{
|
||||
TexResult result[4];
|
||||
float tex_co[3], strength, mag_vec[3];
|
||||
int hasrgb;
|
||||
if(tex==NULL) return;
|
||||
|
||||
result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
|
||||
|
||||
strength= force_val*falloff;
|
||||
|
||||
VECCOPY(tex_co,pa_co);
|
||||
|
||||
if(is_2d){
|
||||
float fac=-Inpf(tex_co,obmat[2]);
|
||||
VECADDFAC(tex_co,tex_co,obmat[2],fac);
|
||||
}
|
||||
|
||||
if(object){
|
||||
VecSubf(tex_co,tex_co,obmat[3]);
|
||||
Mat4Mul3Vecfl(obmat,tex_co);
|
||||
}
|
||||
|
||||
hasrgb = multitex_ext(tex, tex_co, NULL,NULL, 1, result);
|
||||
|
||||
if(hasrgb && mode==PFIELD_TEX_RGB){
|
||||
mag_vec[0]= (0.5f-result->tr)*strength;
|
||||
mag_vec[1]= (0.5f-result->tg)*strength;
|
||||
mag_vec[2]= (0.5f-result->tb)*strength;
|
||||
}
|
||||
else{
|
||||
strength/=nabla;
|
||||
|
||||
tex_co[0]+= nabla;
|
||||
multitex_ext(tex, tex_co, NULL,NULL, 1, result+1);
|
||||
|
||||
tex_co[0]-= nabla;
|
||||
tex_co[1]+= nabla;
|
||||
multitex_ext(tex, tex_co, NULL,NULL, 1, result+2);
|
||||
|
||||
tex_co[1]-= nabla;
|
||||
tex_co[2]+= nabla;
|
||||
multitex_ext(tex, tex_co, NULL,NULL, 1, result+3);
|
||||
|
||||
if(mode==PFIELD_TEX_GRAD || !hasrgb){ /* if we dont have rgb fall back to grad */
|
||||
mag_vec[0]= (result[0].tin-result[1].tin)*strength;
|
||||
mag_vec[1]= (result[0].tin-result[2].tin)*strength;
|
||||
mag_vec[2]= (result[0].tin-result[3].tin)*strength;
|
||||
}
|
||||
else{ /*PFIELD_TEX_CURL*/
|
||||
float dbdy,dgdz,drdz,dbdx,dgdx,drdy;
|
||||
|
||||
dbdy= result[2].tb-result[0].tb;
|
||||
dgdz= result[3].tg-result[0].tg;
|
||||
drdz= result[3].tr-result[0].tr;
|
||||
dbdx= result[1].tb-result[0].tb;
|
||||
dgdx= result[1].tg-result[0].tg;
|
||||
drdy= result[2].tr-result[0].tr;
|
||||
|
||||
mag_vec[0]=(dbdy-dgdz)*strength;
|
||||
mag_vec[1]=(drdz-dbdx)*strength;
|
||||
mag_vec[2]=(dgdx-drdy)*strength;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_2d){
|
||||
float fac=-Inpf(mag_vec,obmat[2]);
|
||||
VECADDFAC(mag_vec,mag_vec,obmat[2],fac);
|
||||
}
|
||||
|
||||
VecAddf(field,field,mag_vec);
|
||||
}
|
||||
static void add_to_effectors(ParticleSimulationData *sim, ListBase *lb, Object *ob)
|
||||
{
|
||||
ParticleEffectorCache *ec;
|
||||
PartDeflect *pd= ob->pd;
|
||||
short type=0,i;
|
||||
|
||||
if(pd && ob != sim->ob){
|
||||
if(pd->forcefield == PFIELD_GUIDE) {
|
||||
if(ob->type==OB_CURVE) {
|
||||
Curve *cu= ob->data;
|
||||
if(cu->flag & CU_PATH) {
|
||||
if(cu->path==NULL || cu->path->data==NULL)
|
||||
makeDispListCurveTypes(sim->scene, ob, 0);
|
||||
if(cu->path && cu->path->data) {
|
||||
type |= PSYS_EC_EFFECTOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pd->forcefield)
|
||||
{
|
||||
type |= PSYS_EC_EFFECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
if(pd && pd->deflect)
|
||||
type |= PSYS_EC_DEFLECT;
|
||||
|
||||
if(type){
|
||||
ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
|
||||
ec->ob= ob;
|
||||
ec->type=type;
|
||||
ec->distances=0;
|
||||
ec->locations=0;
|
||||
ec->rng = rng_new(1);
|
||||
rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
|
||||
|
||||
BLI_addtail(lb, ec);
|
||||
}
|
||||
|
||||
type=0;
|
||||
|
||||
/* add particles as different effectors */
|
||||
if(ob->particlesystem.first){
|
||||
ParticleSystem *epsys=ob->particlesystem.first;
|
||||
ParticleSettings *epart=0;
|
||||
//Object *tob;
|
||||
|
||||
for(i=0; epsys; epsys=epsys->next,i++){
|
||||
if(!psys_check_enabled(ob, epsys))
|
||||
continue;
|
||||
type=0;
|
||||
if(epsys!=sim->psys || (sim->psys->part->flag & PART_SELF_EFFECT)){
|
||||
epart=epsys->part;
|
||||
|
||||
if((epsys->part->pd && epsys->part->pd->forcefield)
|
||||
|| (epsys->part->pd2 && epsys->part->pd2->forcefield))
|
||||
{
|
||||
type=PSYS_EC_PARTICLE;
|
||||
}
|
||||
|
||||
//if(epart->type==PART_REACTOR) {
|
||||
// tob=epsys->target_ob;
|
||||
// if(tob==0)
|
||||
// tob=ob;
|
||||
// if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==sim->psys)
|
||||
// type|=PSYS_EC_REACTOR;
|
||||
//}
|
||||
|
||||
if(type){
|
||||
ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
|
||||
ec->ob= ob;
|
||||
ec->type=type;
|
||||
ec->psys_nbr=i;
|
||||
ec->rng = rng_new(1);
|
||||
rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer())));
|
||||
|
||||
BLI_addtail(lb, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void psys_init_effectors_recurs(ParticleSimulationData *sim, Object *ob, ListBase *listb, int level)
|
||||
{
|
||||
Group *group;
|
||||
GroupObject *go;
|
||||
unsigned int layer= sim->ob->lay;
|
||||
|
||||
if(level>MAX_DUPLI_RECUR) return;
|
||||
|
||||
if(ob->lay & layer) {
|
||||
if(ob->pd || ob->particlesystem.first)
|
||||
add_to_effectors(sim, listb, ob);
|
||||
|
||||
if(ob->dup_group) {
|
||||
group= ob->dup_group;
|
||||
for(go= group->gobject.first; go; go= go->next)
|
||||
psys_init_effectors_recurs(sim, go->ob, listb, level+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psys_init_effectors(ParticleSimulationData *sim, Group *group)
|
||||
{
|
||||
ListBase *listb= &sim->psys->effectors;
|
||||
Base *base;
|
||||
|
||||
listb->first=listb->last=0;
|
||||
|
||||
if(group) {
|
||||
GroupObject *go;
|
||||
|
||||
for(go= group->gobject.first; go; go= go->next)
|
||||
psys_init_effectors_recurs(sim, go->ob, listb, 0);
|
||||
}
|
||||
else {
|
||||
for(base = sim->scene->base.first; base; base= base->next)
|
||||
psys_init_effectors_recurs(sim, base->object, listb, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void psys_end_effectors(ParticleSystem *psys)
|
||||
{
|
||||
/* NOTE:
|
||||
ec->ob is not valid in here anymore! - dg
|
||||
*/
|
||||
ParticleEffectorCache *ec = psys->effectors.first;
|
||||
|
||||
for(; ec; ec= ec->next){
|
||||
if(ec->distances)
|
||||
MEM_freeN(ec->distances);
|
||||
|
||||
if(ec->locations)
|
||||
MEM_freeN(ec->locations);
|
||||
|
||||
if(ec->face_minmax)
|
||||
MEM_freeN(ec->face_minmax);
|
||||
|
||||
if(ec->vert_cos)
|
||||
MEM_freeN(ec->vert_cos);
|
||||
|
||||
if(ec->tree)
|
||||
BLI_kdtree_free(ec->tree);
|
||||
|
||||
if(ec->rng)
|
||||
rng_free(ec->rng);
|
||||
}
|
||||
|
||||
BLI_freelistN(&psys->effectors);
|
||||
}
|
||||
|
||||
/* precalcs effectors and returns 1 if there were any collision object
|
||||
* so collision checks can be avoided as quickly as possible */
|
||||
static int precalc_effectors(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ListBase *lb=&psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleSettings *part=psys->part;
|
||||
PARTICLE_P;
|
||||
int totpart, collision = 0;
|
||||
float vec2[3],loc[3],radius,*co=0;
|
||||
|
||||
for(ec= lb->first; ec; ec= ec->next) {
|
||||
PartDeflect *pd= ec->ob->pd;
|
||||
co = NULL;
|
||||
|
||||
if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE
|
||||
&& part->phystype!=PART_PHYS_BOIDS) {
|
||||
float vec[4];
|
||||
|
||||
where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius);
|
||||
|
||||
Mat4MulVecfl(ec->ob->obmat,vec);
|
||||
Mat4Mul3Vecfl(ec->ob->obmat,vec2);
|
||||
|
||||
QUATCOPY(ec->firstloc,vec);
|
||||
VECCOPY(ec->firstdir,vec2);
|
||||
|
||||
/* TODO - use 'radius' to adjust the effector */
|
||||
|
||||
totpart=psys->totpart;
|
||||
|
||||
if(totpart){
|
||||
ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
|
||||
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
|
||||
|
||||
LOOP_PARTICLES {
|
||||
if(part->from == PART_FROM_PARTICLE) {
|
||||
VECCOPY(loc, pa->fuv);
|
||||
}
|
||||
else
|
||||
psys_particle_on_emitter(sim->psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
|
||||
|
||||
Mat4MulVecfl(sim->ob->obmat,loc);
|
||||
ec->distances[p]=VecLenf(loc,vec);
|
||||
VECSUB(loc,loc,vec);
|
||||
VECCOPY(ec->locations+3*p,loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ec->type==PSYS_EC_PARTICLE){
|
||||
ParticleSimulationData esim = {sim->scene, ec->ob, BLI_findlink(&ec->ob->particlesystem, ec->psys_nbr), NULL};
|
||||
ParticleSettings *epart = esim.psys->part;
|
||||
ParticleData *epa;
|
||||
int p, totepart = esim.psys->totpart;
|
||||
|
||||
if(psys->part->phystype==PART_PHYS_BOIDS){
|
||||
ParticleKey state;
|
||||
PartDeflect *pd;
|
||||
|
||||
pd= epart->pd;
|
||||
if(pd->forcefield==PFIELD_FORCE && totepart){
|
||||
KDTree *tree;
|
||||
|
||||
tree=BLI_kdtree_new(totepart);
|
||||
ec->tree=tree;
|
||||
|
||||
for(p=0, epa=esim.psys->particles; p<totepart; p++,epa++)
|
||||
if(epa->alive==PARS_ALIVE && psys_get_particle_state(&esim,p,&state,0))
|
||||
BLI_kdtree_insert(tree, p, state.co, NULL);
|
||||
|
||||
BLI_kdtree_balance(tree);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(ec->type==PSYS_EC_DEFLECT) {
|
||||
CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
|
||||
if(collmd) {
|
||||
collision_move_object(collmd, 1.0, 0.0);
|
||||
collision = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
||||
/* updates particle effectors and returns if any collision objects were found */
|
||||
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc)
|
||||
{
|
||||
psys_end_effectors(sim->psys);
|
||||
psys_init_effectors(sim, sim->psys->part->eff_group);
|
||||
return (precalc ? precalc_effectors(sim, cfra) : 0);
|
||||
}
|
||||
int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index)
|
||||
{
|
||||
SurfaceModifierData *surmd = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if(sur)
|
||||
surmd = sur;
|
||||
else if(pd && pd->flag&PFIELD_SURFACE)
|
||||
{
|
||||
surmd = (SurfaceModifierData *)modifiers_findByType ( ob, eModifierType_Surface );
|
||||
}
|
||||
|
||||
if(surmd) {
|
||||
/* closest point in the object surface is an effector */
|
||||
BVHTreeNearest nearest;
|
||||
|
||||
nearest.index = -1;
|
||||
nearest.dist = FLT_MAX;
|
||||
|
||||
BLI_bvhtree_find_nearest(surmd->bvhtree->tree, pco, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
|
||||
|
||||
if(nearest.index != -1) {
|
||||
VECCOPY(co, nearest.co);
|
||||
|
||||
if(nor) {
|
||||
VECCOPY(nor, nearest.no);
|
||||
}
|
||||
|
||||
if(vel) {
|
||||
MFace *mface = CDDM_get_face(surmd->dm, nearest.index);
|
||||
|
||||
VECCOPY(vel, surmd->v[mface->v1].co);
|
||||
VecAddf(vel, vel, surmd->v[mface->v2].co);
|
||||
VecAddf(vel, vel, surmd->v[mface->v3].co);
|
||||
if(mface->v4)
|
||||
VecAddf(vel, vel, surmd->v[mface->v4].co);
|
||||
|
||||
VecMulf(vel, mface->v4 ? 0.25f : 0.333f);
|
||||
}
|
||||
|
||||
if(index)
|
||||
*index = nearest.index;
|
||||
|
||||
ret = 1;
|
||||
}
|
||||
else {
|
||||
co[0] = co[1] = co[2] = 0.0f;
|
||||
|
||||
if(nor)
|
||||
nor[0] = nor[1] = nor[2] = 0.0f;
|
||||
|
||||
if(vel)
|
||||
vel[0] = vel[1] = vel[2] = 0.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* use center of object for distance calculus */
|
||||
VECCOPY(co, ob->obmat[3]);
|
||||
|
||||
if(nor) {
|
||||
VECCOPY(nor, ob->obmat[2]);
|
||||
}
|
||||
|
||||
if(vel) {
|
||||
Object obcopy = *ob;
|
||||
|
||||
VECCOPY(vel, ob->obmat[3]);
|
||||
|
||||
where_is_object_time(scene, ob, scene->r.cfra - 1.0);
|
||||
|
||||
VecSubf(vel, vel, ob->obmat[3]);
|
||||
|
||||
*ob = obcopy;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* calculate forces that all effectors apply to a particle*/
|
||||
void do_effectors(ParticleSimulationData *sim, int pa_no, ParticleData *pa, ParticleKey *state, float *rootco, float *force_field, float *vel,float framestep, float cfra)
|
||||
{
|
||||
Object *eob;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *epart;
|
||||
ParticleData *epa;
|
||||
ParticleKey estate;
|
||||
PartDeflect *pd;
|
||||
ListBase *lb=&psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
float distance, vec_to_part[3], pco[3], co[3];
|
||||
float falloff, charge = 0.0f, strength;
|
||||
int p, face_index=-1;
|
||||
|
||||
/* check all effector objects for interaction */
|
||||
if(lb->first){
|
||||
if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
|
||||
/* Only the charge of the effected particle is used for
|
||||
interaction, not fall-offs. If the fall-offs aren't the
|
||||
same this will be unphysical, but for animation this
|
||||
could be the wanted behavior. If you want physical
|
||||
correctness the fall-off should be spherical 2.0 anyways.
|
||||
*/
|
||||
charge = psys->part->pd->f_strength;
|
||||
}
|
||||
if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){
|
||||
charge += psys->part->pd2->f_strength;
|
||||
}
|
||||
for(ec = lb->first; ec; ec= ec->next){
|
||||
eob= ec->ob;
|
||||
if(ec->type & PSYS_EC_EFFECTOR){
|
||||
pd=eob->pd;
|
||||
if(psys->part->type!=PART_HAIR && psys->part->integrator)
|
||||
where_is_object_time(sim->scene, eob, cfra);
|
||||
|
||||
if(pd && pd->flag&PFIELD_SURFACE) {
|
||||
float velocity[3];
|
||||
/* using velocity corrected location allows for easier sliding over effector surface */
|
||||
VecCopyf(velocity, state->vel);
|
||||
VecMulf(velocity, psys_get_timestep(sim));
|
||||
VecAddf(pco, state->co, velocity);
|
||||
}
|
||||
else
|
||||
VECCOPY(pco, state->co);
|
||||
|
||||
effector_find_co(sim->scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index);
|
||||
|
||||
VecSubf(vec_to_part, state->co, co);
|
||||
|
||||
distance = VecLength(vec_to_part);
|
||||
|
||||
falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
|
||||
|
||||
strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
|
||||
|
||||
if(falloff<=0.0f)
|
||||
; /* don't do anything */
|
||||
else if(pd->forcefield==PFIELD_TEXTURE) {
|
||||
do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla,
|
||||
pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
|
||||
strength, falloff, force_field);
|
||||
} else {
|
||||
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
|
||||
state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size);
|
||||
}
|
||||
}
|
||||
if(ec->type & PSYS_EC_PARTICLE){
|
||||
ParticleSimulationData esim = {sim->scene, eob, BLI_findlink(&eob->particlesystem,ec->psys_nbr), NULL};
|
||||
int totepart, i;
|
||||
|
||||
epart = esim.psys->part;
|
||||
pd = epart->pd;
|
||||
totepart = esim.psys->totpart;
|
||||
|
||||
if(totepart <= 0)
|
||||
continue;
|
||||
|
||||
if(pd && pd->forcefield==PFIELD_HARMONIC){
|
||||
/* every particle is mapped to only one harmonic effector particle */
|
||||
p= pa_no%esim.psys->totpart;
|
||||
totepart= p+1;
|
||||
}
|
||||
else{
|
||||
p=0;
|
||||
}
|
||||
|
||||
esim.psys->lattice= psys_get_lattice(sim);
|
||||
|
||||
for(; p<totepart; p++){
|
||||
/* particle skips itself as effector */
|
||||
if(esim.psys == psys && p == pa_no) continue;
|
||||
|
||||
epa = esim.psys->particles + p;
|
||||
estate.time = cfra;
|
||||
if(psys_get_particle_state(&esim, p, &estate, 0)){
|
||||
VECSUB(vec_to_part, state->co, estate.co);
|
||||
distance = VecLength(vec_to_part);
|
||||
|
||||
for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
|
||||
if(pd==NULL || pd->forcefield==0) continue;
|
||||
|
||||
falloff = effector_falloff(pd, estate.vel, vec_to_part);
|
||||
|
||||
strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
|
||||
|
||||
if(falloff<=0.0f)
|
||||
; /* don't do anything */
|
||||
else
|
||||
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
|
||||
state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size);
|
||||
}
|
||||
}
|
||||
else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
|
||||
/* first step after key release */
|
||||
psys_get_particle_state(&esim, p, &estate, 1);
|
||||
VECADD(vel, vel, estate.vel);
|
||||
/* TODO: add rotation handling here too */
|
||||
}
|
||||
}
|
||||
|
||||
if(esim.psys->lattice){
|
||||
end_latt_deform(esim.psys->lattice);
|
||||
esim.psys->lattice= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pdEndEffectors(&sim->psys->effectors);
|
||||
sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
|
||||
precalc_guides(sim, sim->psys->effectors);
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
@@ -2763,9 +2246,10 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ParticleData *pa = sim->psys->particles + p;
|
||||
EffectedPoint epoint;
|
||||
ParticleKey states[5], tkey;
|
||||
float timestep = psys_get_timestep(sim);
|
||||
float force[3],tvel[3],dx[4][3],dv[4][3];
|
||||
float force[3],impulse[3],dx[4][3],dv[4][3];
|
||||
float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra;
|
||||
int i, steps=1;
|
||||
|
||||
@@ -2791,10 +2275,11 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
|
||||
|
||||
for(i=0; i<steps; i++){
|
||||
force[0]=force[1]=force[2]=0.0;
|
||||
tvel[0]=tvel[1]=tvel[2]=0.0;
|
||||
impulse[0]=impulse[1]=impulse[2]=0.0;
|
||||
/* add effectors */
|
||||
if(part->type != PART_HAIR)
|
||||
do_effectors(sim, p, pa, states+i, states->co, force, tvel, dfra, fra);
|
||||
pd_point_from_particle(sim, pa, states+i, &epoint);
|
||||
if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
|
||||
pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
|
||||
|
||||
/* calculate air-particle interaction */
|
||||
if(part->dragfac!=0.0f){
|
||||
@@ -2813,10 +2298,17 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
|
||||
VecMulf(force,1.0f/pa_mass);
|
||||
|
||||
/* add global acceleration (gravitation) */
|
||||
VECADD(force,force,part->acc);
|
||||
if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY
|
||||
/* normal gravity is too strong for hair so it's disabled by default */
|
||||
&& (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
|
||||
float gravity[3];
|
||||
VECCOPY(gravity, sim->scene->physics_settings.gravity);
|
||||
VecMulf(gravity, part->effector_weights->global_gravity);
|
||||
VECADD(force,force,gravity);
|
||||
}
|
||||
|
||||
/* calculate next state */
|
||||
VECADD(states[i].vel,states[i].vel,tvel);
|
||||
VECADD(states[i].vel,states[i].vel,impulse);
|
||||
|
||||
switch(part->integrator){
|
||||
case PART_INT_EULER:
|
||||
@@ -2889,6 +2381,8 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
|
||||
if(part->dampfac!=0.0)
|
||||
VecMulf(pa->state.vel,1.0f-part->dampfac);
|
||||
|
||||
VECCOPY(pa->state.ave, states->ave);
|
||||
|
||||
/* finally we do guides */
|
||||
time=(cfra-pa->time)/pa->lifetime;
|
||||
CLAMP(time,0.0,1.0);
|
||||
@@ -2898,7 +2392,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
|
||||
tkey.time=pa->state.time;
|
||||
|
||||
if(part->type != PART_HAIR) {
|
||||
if(do_guide(sim->scene, &tkey, p, time, &sim->psys->effectors)) {
|
||||
if(do_guides(sim->psys->effectors, &tkey, p, time)) {
|
||||
VECCOPY(pa->state.co,tkey.co);
|
||||
/* guides don't produce valid velocity */
|
||||
VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
|
||||
@@ -3129,7 +2623,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
|
||||
|
||||
VECCOPY(col->vel,vel);
|
||||
|
||||
col->ob = col->ob_t;
|
||||
col->hit_ob = col->ob;
|
||||
col->hit_md = col->md;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3146,7 +2641,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
|
||||
|
||||
VECCOPY(col->vel,vel);
|
||||
|
||||
col->ob = col->ob_t;
|
||||
col->hit_ob = col->ob;
|
||||
col->hit_md = col->md;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3163,13 +2659,11 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
|
||||
/* 1. check for all possible deflectors for closest intersection on particle path */
|
||||
/* 2. if deflection was found kill the particle or calculate new coordinates */
|
||||
static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
|
||||
Object *ob = NULL, *skip_ob = NULL;
|
||||
Object *ground_ob = NULL;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ListBase *lb=&sim->psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleKey reaction_state;
|
||||
ParticleCollision col;
|
||||
ParticleData *pa = sim->psys->particles + p;
|
||||
ParticleCollision col;
|
||||
ColliderCache *coll;
|
||||
BVHTreeRayHit hit;
|
||||
float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
|
||||
float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
|
||||
@@ -3185,11 +2679,11 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
||||
BoidParticle *bpa = pa->boid;
|
||||
radius = pa->size;
|
||||
boid_z = pa->state.co[2];
|
||||
skip_ob = bpa->ground;
|
||||
ground_ob = bpa->ground;
|
||||
}
|
||||
|
||||
/* 10 iterations to catch multiple deflections */
|
||||
if(lb->first) while(deflections < max_deflections){
|
||||
if(sim->colliders) while(deflections < max_deflections){
|
||||
/* 1. */
|
||||
|
||||
VECSUB(ray_dir, col.co2, col.co1);
|
||||
@@ -3201,32 +2695,25 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
||||
if(hit.dist == 0.0f)
|
||||
hit.dist = col.ray_len = 0.000001f;
|
||||
|
||||
for(ec=lb->first; ec; ec=ec->next){
|
||||
if(ec->type & PSYS_EC_DEFLECT){
|
||||
ob= ec->ob;
|
||||
|
||||
for(coll = sim->colliders->first; coll; coll=coll->next){
|
||||
/* for boids: don't check with current ground object */
|
||||
if(ob==skip_ob)
|
||||
if(coll->ob == ground_ob)
|
||||
continue;
|
||||
|
||||
/* particles should not collide with emitter at birth */
|
||||
if(ob==sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
|
||||
if(coll->ob == sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
|
||||
continue;
|
||||
|
||||
if(part->type!=PART_HAIR)
|
||||
where_is_object_time(sim->scene, sim->ob, cfra);
|
||||
|
||||
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
|
||||
col.ob_t = ob;
|
||||
col.ob = coll->ob;
|
||||
col.md = coll->collmd;
|
||||
|
||||
if(col.md && col.md->bvhtree)
|
||||
BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. */
|
||||
if(hit.index>=0) {
|
||||
PartDeflect *pd = col.ob->pd;
|
||||
PartDeflect *pd = col.hit_ob->pd;
|
||||
int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
|
||||
float co[3]; /* point of collision */
|
||||
float vec[3]; /* movement through collision */
|
||||
@@ -3253,9 +2740,6 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
||||
|
||||
/* particle is dead so we don't need to calculate further */
|
||||
deflections=max_deflections;
|
||||
|
||||
/* store for reactors */
|
||||
copy_particle_key(&reaction_state, &pa->state, 0);
|
||||
}
|
||||
else {
|
||||
float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
|
||||
@@ -3416,7 +2900,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
|
||||
|
||||
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
|
||||
skip = 1; /* only hair, keyed and baked stuff can have paths */
|
||||
else if(part->ren_as != PART_DRAW_PATH)
|
||||
else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
|
||||
skip = 1; /* particle visualization must be set as path */
|
||||
else if(!psys->renderdata) {
|
||||
if(part->draw_as != PART_DRAW_REND)
|
||||
@@ -3555,8 +3039,11 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
|
||||
psys->hair_out_dm->release(psys->hair_out_dm);
|
||||
|
||||
psys->clmd->point_cache = psys->pointcache;
|
||||
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
|
||||
|
||||
psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0);
|
||||
|
||||
psys->clmd->sim_parms->effector_weights = NULL;
|
||||
}
|
||||
static void hair_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
@@ -3586,7 +3073,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
|
||||
if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
|
||||
do_hair_dynamics(sim);
|
||||
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
psys_update_effectors(sim);
|
||||
|
||||
psys_update_path_cache(sim, cfra);
|
||||
|
||||
@@ -3648,12 +3135,12 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part=psys->part;
|
||||
KDTree *tree=0;
|
||||
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||
//IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||
/* Material *ma=give_current_material(sim->ob, part->omat); */
|
||||
BoidBrainData bbd;
|
||||
PARTICLE_P;
|
||||
float timestep;
|
||||
int totpart, check_collisions = 0;
|
||||
int totpart;
|
||||
/* current time */
|
||||
float ctime, ipotime; // XXX old animation system
|
||||
/* frame & time changes */
|
||||
@@ -3703,15 +3190,6 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
}
|
||||
else{
|
||||
pa->loop = 0;
|
||||
if(cfra <= pa->time)
|
||||
pa->alive = PARS_UNBORN;
|
||||
/* without dynamics the state is allways known so no need to kill */
|
||||
else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)){
|
||||
if(cfra < pa->dietime)
|
||||
pa->alive = PARS_ALIVE;
|
||||
}
|
||||
else
|
||||
pa->alive = PARS_KILLED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3721,7 +3199,10 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
else{
|
||||
BLI_srandom(31415926 + (int)cfra + psys->seed);
|
||||
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
psys_update_effectors(sim);
|
||||
|
||||
if(part->type != PART_HAIR)
|
||||
sim->colliders = get_collider_cache(sim->scene, NULL);
|
||||
|
||||
if(part->phystype==PART_PHYS_BOIDS){
|
||||
ParticleTarget *pt = psys->targets.first;
|
||||
@@ -3731,13 +3212,13 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
bbd.dfra = dfra;
|
||||
bbd.timestep = timestep;
|
||||
|
||||
update_particle_tree(psys);
|
||||
psys_update_particle_tree(psys, cfra);
|
||||
|
||||
boids_precalc_rules(part, cfra);
|
||||
|
||||
for(; pt; pt=pt->next) {
|
||||
if(pt->ob)
|
||||
update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1));
|
||||
psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3798,7 +3279,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
apply_particle_forces(sim, p, pa_dfra, cfra);
|
||||
|
||||
/* deflection */
|
||||
if(check_collisions)
|
||||
if(sim->colliders)
|
||||
deflect_particle(sim, p, pa_dfra, cfra);
|
||||
|
||||
/* rotations */
|
||||
@@ -3812,6 +3293,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
boid_body(&bbd, pa);
|
||||
|
||||
/* deflection */
|
||||
if(sim->colliders)
|
||||
deflect_particle(sim, p, pa_dfra, cfra);
|
||||
}
|
||||
break;
|
||||
@@ -3837,9 +3319,9 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
//push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
|
||||
}
|
||||
}
|
||||
|
||||
free_collider_cache(&sim->colliders);
|
||||
}
|
||||
if(psys->reactevents.first)
|
||||
BLI_freelistN(&psys->reactevents);
|
||||
|
||||
if(tree)
|
||||
BLI_kdtree_free(tree);
|
||||
@@ -3850,7 +3332,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||
//IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||
/* Material *ma = give_current_material(sim->ob,part->omat); */
|
||||
PARTICLE_P;
|
||||
float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
|
||||
@@ -3860,7 +3342,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
|
||||
if(part->from!=PART_FROM_PARTICLE)
|
||||
vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
|
||||
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
psys_update_effectors(sim);
|
||||
|
||||
disp= (float)get_current_display_percentage(psys)/100.0f;
|
||||
|
||||
@@ -4195,6 +3677,13 @@ static void system_step(ParticleSimulationData *sim, float cfra)
|
||||
else if(framenr > endframe) {
|
||||
framenr= endframe;
|
||||
}
|
||||
|
||||
if(framenr == startframe) {
|
||||
BKE_ptcache_id_reset(sim->scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
cache->simframe= framenr;
|
||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
}
|
||||
}
|
||||
|
||||
/* verify if we need to reallocate */
|
||||
@@ -4226,7 +3715,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
|
||||
if(alloc) {
|
||||
realloc_particles(sim, totpart);
|
||||
|
||||
if(usecache && !only_children_changed) {
|
||||
if(oldtotpart && usecache && !only_children_changed) {
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
|
||||
BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
|
||||
}
|
||||
@@ -4286,7 +3775,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
|
||||
pa->alive = PARS_ALIVE;
|
||||
}
|
||||
}
|
||||
else if(sim->ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
|
||||
else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) {
|
||||
psys_reset(psys, PSYS_RESET_CACHE_MISS);
|
||||
psys->cfra=cfra;
|
||||
psys->recalc = 0;
|
||||
@@ -4383,7 +3872,7 @@ static int hair_needs_recalc(ParticleSystem *psys)
|
||||
/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
|
||||
void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSimulationData sim = {scene, ob, psys, NULL};
|
||||
ParticleSimulationData sim = {scene, ob, psys, NULL, NULL};
|
||||
float cfra;
|
||||
|
||||
/* drawdata is outdated after ANY change */
|
||||
|
||||
@@ -292,6 +292,9 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
|
||||
else
|
||||
BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
|
||||
|
||||
if(cfra > pa->time)
|
||||
cfra1 = MAX2(cfra1, pa->time);
|
||||
|
||||
dfra = cfra2 - cfra1;
|
||||
|
||||
VecMulf(keys[1].vel, dfra / frs_sec);
|
||||
@@ -2266,6 +2269,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&pidlist2);
|
||||
}
|
||||
|
||||
if(bake || cache->flag & PTCACHE_REDO_NEEDED)
|
||||
|
||||
@@ -402,6 +402,10 @@ Scene *add_scene(char *name)
|
||||
|
||||
sce->toolsettings->proportional_size = 1.0f;
|
||||
|
||||
sce->physics_settings.gravity[0] = 0.0f;
|
||||
sce->physics_settings.gravity[1] = 0.0f;
|
||||
sce->physics_settings.gravity[2] = -9.81f;
|
||||
sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
|
||||
|
||||
sce->unit.scale_length = 1.0f;
|
||||
|
||||
|
||||
@@ -2067,7 +2067,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
|
||||
if(rendering)
|
||||
BLI_strncpy(sce->id.name+2, scenename, 64);
|
||||
|
||||
RE_GetResultImage(re, &rres);
|
||||
RE_AcquireResultImage(re, &rres);
|
||||
|
||||
if(rres.rectf) {
|
||||
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
|
||||
@@ -2081,6 +2081,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
|
||||
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
|
||||
}
|
||||
|
||||
RE_ReleaseResultImage(re);
|
||||
|
||||
BIF_end_render_callbacks();
|
||||
|
||||
/* restore */
|
||||
|
||||
@@ -126,6 +126,7 @@ struct SmokeModifierData;
|
||||
// forward declerations
|
||||
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
|
||||
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
|
||||
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs);
|
||||
|
||||
#define TRI_UVOFFSET (1./4.)
|
||||
|
||||
@@ -279,6 +280,26 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
|
||||
{
|
||||
// init collision points
|
||||
SmokeCollSettings *scs = smd->coll;
|
||||
|
||||
// copy obmat
|
||||
Mat4CpyMat4(scs->mat, ob->obmat);
|
||||
Mat4CpyMat4(scs->mat_old, ob->obmat);
|
||||
|
||||
fill_scs_points(ob, dm, scs);
|
||||
}
|
||||
|
||||
if(!smd->coll->bvhtree)
|
||||
{
|
||||
smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs)
|
||||
{
|
||||
MVert *mvert = dm->getVertArray(dm);
|
||||
MFace *mface = dm->getFaceArray(dm);
|
||||
int i = 0, divs = 0;
|
||||
@@ -287,10 +308,6 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
|
||||
int newdivs = 0;
|
||||
int quads = 0, facecounter = 0;
|
||||
|
||||
// copy obmat
|
||||
Mat4CpyMat4(scs->mat, ob->obmat);
|
||||
Mat4CpyMat4(scs->mat_old, ob->obmat);
|
||||
|
||||
// count quads
|
||||
for(i = 0; i < dm->getNumFaces(dm); i++)
|
||||
{
|
||||
@@ -416,16 +433,6 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
|
||||
MEM_freeN(tridivs);
|
||||
}
|
||||
|
||||
if(!smd->coll->bvhtree)
|
||||
{
|
||||
smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*! init triangle divisions */
|
||||
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len)
|
||||
{
|
||||
@@ -832,8 +839,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
|
||||
size_t i = 0;
|
||||
size_t index = 0;
|
||||
int badcell = 0;
|
||||
if(pa->alive == PARS_KILLED) continue;
|
||||
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
|
||||
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
|
||||
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
|
||||
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
|
||||
// VECCOPY(pos, pa->state.co);
|
||||
@@ -1184,7 +1190,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
|
||||
// simulate the actual smoke (c++ code in intern/smoke)
|
||||
// DG: interesting commenting this line + deactivating loading of noise files
|
||||
if(framenr!=startframe)
|
||||
{
|
||||
if(sds->flags & MOD_SMOKE_DISSOLVE)
|
||||
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
|
||||
smoke_step(sds->fluid, smd->time);
|
||||
}
|
||||
|
||||
// create shadows before writing cache so we get nice shadows for sstartframe, too
|
||||
if(get_lamp(scene, light))
|
||||
@@ -1195,7 +1205,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
|
||||
if(sds->wt)
|
||||
{
|
||||
if(framenr!=startframe)
|
||||
{
|
||||
if(sds->flags & MOD_SMOKE_DISSOLVE)
|
||||
smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
|
||||
smoke_turbulence_step(sds->wt, sds->fluid);
|
||||
}
|
||||
|
||||
cache_wt->flag |= PTCACHE_SIMULATION_VALID;
|
||||
cache_wt->simframe= framenr;
|
||||
|
||||
@@ -1550,11 +1550,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
|
||||
float f,windfactor = 0.25f;
|
||||
/*see if we have wind*/
|
||||
if(do_effector) {
|
||||
EffectedPoint epoint;
|
||||
float speed[3]={0.0f,0.0f,0.0f};
|
||||
float pos[3];
|
||||
VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
|
||||
VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec);
|
||||
pdDoEffectors(scene, do_effector, pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
||||
pd_point_from_soft(scene, pos, vel, -1, &epoint);
|
||||
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
|
||||
|
||||
VecMulf(speed,windfactor);
|
||||
VecAddf(vel,vel,speed);
|
||||
}
|
||||
@@ -1591,12 +1594,11 @@ static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
|
||||
SoftBody *sb = ob->soft;
|
||||
ListBase *do_effector = NULL;
|
||||
|
||||
do_effector= pdInitEffectors(scene, ob,NULL);
|
||||
do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
|
||||
if (sb){
|
||||
_scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
|
||||
}
|
||||
if(do_effector)
|
||||
pdEndEffectors(do_effector);
|
||||
pdEndEffectors(&do_effector);
|
||||
}
|
||||
|
||||
static void *exec_scan_for_ext_spring_forces(void *data)
|
||||
@@ -1614,7 +1616,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
|
||||
int i, totthread,left,dec;
|
||||
int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
|
||||
|
||||
do_effector= pdInitEffectors(scene, ob,NULL);
|
||||
do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
|
||||
|
||||
/* figure the number of threads while preventing pretty pointless threading overhead */
|
||||
if(scene->r.mode & R_FIXED_THREADS)
|
||||
@@ -1662,8 +1664,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
|
||||
/* clean up */
|
||||
MEM_freeN(sb_threads);
|
||||
|
||||
if(do_effector)
|
||||
pdEndEffectors(do_effector);
|
||||
pdEndEffectors(&do_effector);
|
||||
}
|
||||
|
||||
|
||||
@@ -2226,19 +2227,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
|
||||
/* done goal stuff */
|
||||
|
||||
/* gravitation */
|
||||
if (sb){
|
||||
float gravity = sb->grav * sb_grav_force_scale(ob);
|
||||
bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
|
||||
if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
|
||||
float gravity[3];
|
||||
VECCOPY(gravity, scene->physics_settings.gravity);
|
||||
VecMulf(gravity, sb_grav_force_scale(ob)*bp->mass*sb->effector_weights->global_gravity); /* individual mass of node here */
|
||||
VecAddf(bp->force, bp->force, gravity);
|
||||
}
|
||||
|
||||
/* particle field & vortex */
|
||||
if(do_effector) {
|
||||
EffectedPoint epoint;
|
||||
float kd;
|
||||
float force[3]= {0.0f, 0.0f, 0.0f};
|
||||
float speed[3]= {0.0f, 0.0f, 0.0f};
|
||||
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
|
||||
|
||||
pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
||||
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
|
||||
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
|
||||
|
||||
/* apply forcefield*/
|
||||
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
|
||||
@@ -2341,6 +2345,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
|
||||
left = totpoint;
|
||||
dec = totpoint/totthread +1;
|
||||
for(i=0; i<totthread; i++) {
|
||||
sb_threads[i].scene = scene;
|
||||
sb_threads[i].ob = ob;
|
||||
sb_threads[i].forcetime = forcetime;
|
||||
sb_threads[i].timenow = timenow;
|
||||
@@ -2381,7 +2386,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
|
||||
*/
|
||||
SoftBody *sb= ob->soft; /* is supposed to be there */
|
||||
BodyPoint *bproot;
|
||||
ListBase *do_effector;
|
||||
ListBase *do_effector = NULL;
|
||||
float iks, gravity;
|
||||
float fieldfactor = -1.0f, windfactor = 0.25;
|
||||
int do_deflector,do_selfcollision,do_springcollision,do_aero;
|
||||
@@ -2401,7 +2406,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
|
||||
sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL);
|
||||
|
||||
/* after spring scan because it uses Effoctors too */
|
||||
do_effector= pdInitEffectors(scene, ob,NULL);
|
||||
do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights);
|
||||
|
||||
if (do_deflector) {
|
||||
float defforce[3];
|
||||
@@ -2414,7 +2419,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
|
||||
if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
|
||||
|
||||
/* finish matrix and solve */
|
||||
if(do_effector) pdEndEffectors(do_effector);
|
||||
pdEndEffectors(&do_effector);
|
||||
}
|
||||
|
||||
|
||||
@@ -2443,8 +2448,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
|
||||
BodyPoint *bp;
|
||||
BodyPoint *bproot;
|
||||
BodySpring *bs;
|
||||
ListBase *do_effector;
|
||||
float iks, ks, kd, gravity;
|
||||
ListBase *do_effector = NULL;
|
||||
float iks, ks, kd, gravity[3] = {0.0f,0.0f,0.0f};
|
||||
float fieldfactor = -1.0f, windfactor = 0.25f;
|
||||
float tune = sb->ballstiff;
|
||||
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
|
||||
@@ -2460,7 +2465,10 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
|
||||
*/
|
||||
|
||||
|
||||
gravity = sb->grav * sb_grav_force_scale(ob);
|
||||
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
|
||||
VECCOPY(gravity, scene->physics_settings.gravity);
|
||||
VecMulf(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity);
|
||||
}
|
||||
|
||||
/* check conditions for various options */
|
||||
do_deflector= query_external_colliders(scene, ob);
|
||||
@@ -2473,7 +2481,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
|
||||
|
||||
if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow);
|
||||
/* after spring scan because it uses Effoctors too */
|
||||
do_effector= pdInitEffectors(scene, ob,NULL);
|
||||
do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
|
||||
|
||||
if (do_deflector) {
|
||||
float defforce[3];
|
||||
@@ -2631,16 +2639,17 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
|
||||
|
||||
|
||||
/* gravitation */
|
||||
bp->force[2]-= gravity*bp->mass; /* individual mass of node here */
|
||||
VECADDFAC(bp->force, bp->force, gravity, bp->mass); /* individual mass of node here */
|
||||
|
||||
|
||||
/* particle field & vortex */
|
||||
if(do_effector) {
|
||||
EffectedPoint epoint;
|
||||
float force[3]= {0.0f, 0.0f, 0.0f};
|
||||
float speed[3]= {0.0f, 0.0f, 0.0f};
|
||||
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
|
||||
|
||||
pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
||||
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
|
||||
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
|
||||
|
||||
/* apply forcefield*/
|
||||
VecMulf(force,fieldfactor* eval_sb_fric_force_scale);
|
||||
@@ -2819,7 +2828,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
|
||||
}
|
||||
/* cleanup */
|
||||
#endif
|
||||
if(do_effector) pdEndEffectors(do_effector);
|
||||
pdEndEffectors(&do_effector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3635,6 +3644,9 @@ SoftBody *sbNew(Scene *scene)
|
||||
|
||||
sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
|
||||
|
||||
if(!sb->effector_weights)
|
||||
sb->effector_weights = BKE_add_effector_weights(NULL);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
@@ -3644,6 +3656,8 @@ void sbFree(SoftBody *sb)
|
||||
free_softbody_intern(sb);
|
||||
BKE_ptcache_free_list(&sb->ptcaches);
|
||||
sb->pointcache = NULL;
|
||||
if(sb->effector_weights)
|
||||
MEM_freeN(sb->effector_weights);
|
||||
MEM_freeN(sb);
|
||||
}
|
||||
|
||||
@@ -3684,6 +3698,9 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
|
||||
BodyPoint *bp;
|
||||
int a;
|
||||
|
||||
if(!sb || !sb->bpoint)
|
||||
return;
|
||||
|
||||
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
|
||||
/* store where goals are now */
|
||||
VECCOPY(bp->origS, bp->origE);
|
||||
|
||||
@@ -559,6 +559,36 @@ void default_mtex(MTex *mtex)
|
||||
mtex->norfac= 1.0;
|
||||
mtex->varfac= 1.0;
|
||||
mtex->dispfac=0.2;
|
||||
mtex->colspecfac= 1.0f;
|
||||
mtex->mirrfac= 1.0f;
|
||||
mtex->alphafac= 1.0f;
|
||||
mtex->difffac= 1.0f;
|
||||
mtex->specfac= 1.0f;
|
||||
mtex->emitfac= 1.0f;
|
||||
mtex->hardfac= 1.0f;
|
||||
mtex->raymirrfac= 1.0f;
|
||||
mtex->translfac= 1.0f;
|
||||
mtex->ambfac= 1.0f;
|
||||
mtex->colemitfac= 1.0f;
|
||||
mtex->colreflfac= 1.0f;
|
||||
mtex->coltransfac= 1.0f;
|
||||
mtex->densfac= 1.0f;
|
||||
mtex->scatterfac= 1.0f;
|
||||
mtex->reflfac= 1.0f;
|
||||
mtex->shadowfac= 1.0f;
|
||||
mtex->zenupfac= 1.0f;
|
||||
mtex->zendownfac= 1.0f;
|
||||
mtex->blendfac= 1.0f;
|
||||
mtex->timefac= 1.0f;
|
||||
mtex->lengthfac= 1.0f;
|
||||
mtex->clumpfac= 1.0f;
|
||||
mtex->kinkfac= 1.0f;
|
||||
mtex->roughfac= 1.0f;
|
||||
mtex->padensfac= 1.0f;
|
||||
mtex->lifefac= 1.0f;
|
||||
mtex->sizefac= 1.0f;
|
||||
mtex->ivelfac= 1.0f;
|
||||
mtex->pvelfac= 1.0f;
|
||||
mtex->normapspace= MTEX_NSPACE_TANGENT;
|
||||
}
|
||||
|
||||
@@ -984,6 +1014,7 @@ struct VoxelData *BKE_add_voxeldata(void)
|
||||
vd->interp_type= TEX_VD_LINEAR;
|
||||
vd->file_format= TEX_VD_SMOKE;
|
||||
vd->int_multiplier = 1.0;
|
||||
vd->extend = TEX_CLIP;
|
||||
vd->object = NULL;
|
||||
|
||||
return vd;
|
||||
|
||||
@@ -86,15 +86,20 @@ World *add_world(char *name)
|
||||
|
||||
wrld= alloc_libblock(&G.main->world, ID_WO, name);
|
||||
|
||||
wrld->horb= 0.6f;
|
||||
wrld->skytype= WO_SKYBLEND;
|
||||
wrld->horr= 0.25f;
|
||||
wrld->horg= 0.25f;
|
||||
wrld->horb= 0.25f;
|
||||
wrld->zenr= 0.1f;
|
||||
wrld->zeng= 0.1f;
|
||||
wrld->zenb= 0.1f;
|
||||
wrld->skytype= 0;
|
||||
wrld->stardist= 15.0f;
|
||||
wrld->starsize= 2.0f;
|
||||
|
||||
wrld->exp= 0.0f;
|
||||
wrld->exposure=wrld->range= 1.0f;
|
||||
|
||||
wrld->aodist= 5.0f;
|
||||
wrld->aodist= 10.0f;
|
||||
wrld->aosamp= 5;
|
||||
wrld->aoenergy= 1.0f;
|
||||
wrld->aobias= 0.05f;
|
||||
|
||||
@@ -178,7 +178,7 @@ float power_of_2(float val);
|
||||
*/
|
||||
|
||||
/* Defines for rotation orders
|
||||
* WARNING: must match the ePchan_RotMode in DNA_action_types.h
|
||||
* WARNING: must match the eRotationModes in DNA_action_types.h
|
||||
* order matters - types are saved to file!
|
||||
*/
|
||||
typedef enum eEulerRotationOrders {
|
||||
|
||||
@@ -31,14 +31,15 @@
|
||||
#ifndef BLI_THREADS_H
|
||||
#define BLI_THREADS_H
|
||||
|
||||
/* one custom lock available now. can be extended */
|
||||
#define LOCK_IMAGE 0
|
||||
#define LOCK_CUSTOM1 1
|
||||
#include <pthread.h>
|
||||
|
||||
/* for tables, button in UI, etc */
|
||||
#define BLENDER_MAX_THREADS 8
|
||||
|
||||
struct ListBase;
|
||||
|
||||
/* Threading API */
|
||||
|
||||
void BLI_init_threads (struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
|
||||
int BLI_available_threads(struct ListBase *threadbase);
|
||||
int BLI_available_thread_index(struct ListBase *threadbase);
|
||||
@@ -48,18 +49,46 @@ void BLI_remove_thread_index(struct ListBase *threadbase, int index);
|
||||
void BLI_remove_threads(struct ListBase *threadbase);
|
||||
void BLI_end_threads (struct ListBase *threadbase);
|
||||
|
||||
void BLI_lock_thread (int type);
|
||||
void BLI_unlock_thread (int type);
|
||||
/* System Information */
|
||||
|
||||
int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */
|
||||
|
||||
/* exported by preview render, it has to ensure render buffers are not freed while draw */
|
||||
void BLI_lock_malloc_thread(void);
|
||||
void BLI_unlock_malloc_thread(void);
|
||||
/* Global Mutex Locks
|
||||
*
|
||||
* One custom lock available now. can be extended. */
|
||||
|
||||
/* ThreadedWorker is a simple tool for dispatching work to a limited number of threads in a transparent
|
||||
* fashion from the caller's perspective
|
||||
* */
|
||||
#define LOCK_IMAGE 0
|
||||
#define LOCK_PREVIEW 1
|
||||
#define LOCK_CUSTOM1 2
|
||||
|
||||
void BLI_lock_thread(int type);
|
||||
void BLI_unlock_thread(int type);
|
||||
|
||||
/* Mutex Lock */
|
||||
|
||||
typedef pthread_mutex_t ThreadMutex;
|
||||
|
||||
void BLI_mutex_init(ThreadMutex *mutex);
|
||||
void BLI_mutex_lock(ThreadMutex *mutex);
|
||||
void BLI_mutex_unlock(ThreadMutex *mutex);
|
||||
void BLI_mutex_end(ThreadMutex *mutex);
|
||||
|
||||
/* Read/Write Mutex Lock */
|
||||
|
||||
#define THREAD_LOCK_READ 1
|
||||
#define THREAD_LOCK_WRITE 2
|
||||
|
||||
typedef pthread_rwlock_t ThreadRWMutex;
|
||||
|
||||
void BLI_rw_mutex_init(ThreadRWMutex *mutex);
|
||||
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
|
||||
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
|
||||
void BLI_rw_mutex_end(ThreadRWMutex *mutex);
|
||||
|
||||
/* ThreadedWorker
|
||||
*
|
||||
* A simple tool for dispatching work to a limited number of threads
|
||||
* in a transparent fashion from the caller's perspective. */
|
||||
|
||||
struct ThreadedWorker;
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
* The Original Code is: all of this file, with exception of below:
|
||||
*
|
||||
* Contributor(s): Peter O'Gorman
|
||||
* The functions osxdlopen() and osxerror()
|
||||
* are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -102,202 +100,6 @@ void PIL_dynlib_close(PILdynlib *lib) {
|
||||
free(lib);
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef __APPLE__ /* MacOS X */
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define ERR_STR_LEN 256
|
||||
|
||||
struct PILdynlib {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
static char *osxerror(int setget, const char *str, ...)
|
||||
{
|
||||
static char errstr[ERR_STR_LEN];
|
||||
static int err_filled = 0;
|
||||
char *retval;
|
||||
NSLinkEditErrors ler;
|
||||
int lerno;
|
||||
const char *dylderrstr;
|
||||
const char *file;
|
||||
va_list arg;
|
||||
if (setget <= 0)
|
||||
{
|
||||
va_start(arg, str);
|
||||
strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
|
||||
vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
|
||||
va_end(arg);
|
||||
/* We prefer to use the dyld error string if setget is 0 */
|
||||
if (setget == 0) {
|
||||
NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
|
||||
// printf("dyld: %s\n",dylderrstr);
|
||||
if (dylderrstr && strlen(dylderrstr))
|
||||
strncpy(errstr,dylderrstr,ERR_STR_LEN);
|
||||
}
|
||||
err_filled = 1;
|
||||
retval = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!err_filled)
|
||||
retval = NULL;
|
||||
else
|
||||
retval = errstr;
|
||||
err_filled = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void *osxdlopen(const char *path, int mode)
|
||||
{
|
||||
void *module = 0;
|
||||
NSObjectFileImage ofi = 0;
|
||||
NSObjectFileImageReturnCode ofirc;
|
||||
static int (*make_private_module_public) (NSModule module) = 0;
|
||||
unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
|
||||
|
||||
/* If we got no path, the app wants the global namespace, use -1 as the marker
|
||||
in this case */
|
||||
if (!path)
|
||||
return (void *)-1;
|
||||
|
||||
/* Create the object file image, works for things linked with the -bundle arg to ld */
|
||||
ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
|
||||
switch (ofirc)
|
||||
{
|
||||
case NSObjectFileImageSuccess:
|
||||
/* It was okay, so use NSLinkModule to link in the image */
|
||||
if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
|
||||
module = NSLinkModule(ofi, path,flags);
|
||||
/* Don't forget to destroy the object file image, unless you like leaks */
|
||||
NSDestroyObjectFileImage(ofi);
|
||||
/* If the mode was global, then change the module, this avoids
|
||||
multiply defined symbol errors to first load private then make
|
||||
global. Silly, isn't it. */
|
||||
if ((mode & RTLD_GLOBAL))
|
||||
{
|
||||
if (!make_private_module_public)
|
||||
{
|
||||
_dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
|
||||
(unsigned long *)&make_private_module_public);
|
||||
}
|
||||
make_private_module_public(module);
|
||||
}
|
||||
break;
|
||||
case NSObjectFileImageInappropriateFile:
|
||||
/* It may have been a dynamic library rather than a bundle, try to load it */
|
||||
module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
break;
|
||||
case NSObjectFileImageFailure:
|
||||
osxerror(0,"Object file setup failure : \"%s\"", path);
|
||||
return 0;
|
||||
case NSObjectFileImageArch:
|
||||
osxerror(0,"No object for this architecture : \"%s\"", path);
|
||||
return 0;
|
||||
case NSObjectFileImageFormat:
|
||||
osxerror(0,"Bad object file format : \"%s\"", path);
|
||||
return 0;
|
||||
case NSObjectFileImageAccess:
|
||||
osxerror(0,"Can't read object file : \"%s\"", path);
|
||||
return 0;
|
||||
}
|
||||
if (!module)
|
||||
osxerror(0, "Can not open \"%s\"", path);
|
||||
return module;
|
||||
}
|
||||
|
||||
PILdynlib *PIL_dynlib_open(char *name) {
|
||||
void *handle= osxdlopen(name, RTLD_LAZY);
|
||||
|
||||
if (handle) {
|
||||
PILdynlib *lib= malloc(sizeof(*lib));
|
||||
lib->handle= handle;
|
||||
|
||||
return lib;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname)
|
||||
{
|
||||
int sym_len = strlen(symname);
|
||||
void *value = NULL;
|
||||
char *malloc_sym = NULL;
|
||||
NSSymbol *nssym = 0;
|
||||
malloc_sym = malloc(sym_len + 2);
|
||||
if (malloc_sym)
|
||||
{
|
||||
sprintf(malloc_sym, "_%s", symname);
|
||||
/* If the lib->handle is -1, if is the app global context */
|
||||
if (lib->handle == (void *)-1)
|
||||
{
|
||||
/* Global context, use NSLookupAndBindSymbol */
|
||||
if (NSIsSymbolNameDefined(malloc_sym))
|
||||
{
|
||||
nssym = NSLookupAndBindSymbol(malloc_sym);
|
||||
}
|
||||
}
|
||||
/* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image
|
||||
for libraries, and NSLookupSymbolInModule for bundles */
|
||||
else
|
||||
{
|
||||
/* Check for both possible magic numbers depending on x86/ppc byte order */
|
||||
if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
|
||||
(((struct mach_header *)lib->handle)->magic == MH_CIGAM))
|
||||
{
|
||||
if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym))
|
||||
{
|
||||
nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle,
|
||||
malloc_sym,
|
||||
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
|
||||
| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
nssym = NSLookupSymbolInModule(lib->handle, malloc_sym);
|
||||
}
|
||||
}
|
||||
if (!nssym)
|
||||
{
|
||||
osxerror(0, "symname \"%s\" Not found", symname);
|
||||
}
|
||||
value = NSAddressOfSymbol(nssym);
|
||||
free(malloc_sym);
|
||||
}
|
||||
else
|
||||
{
|
||||
osxerror(-1, "Unable to allocate memory");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
char *PIL_dynlib_get_error_as_string(PILdynlib* lib)
|
||||
{
|
||||
return osxerror(1, (char *)NULL);
|
||||
}
|
||||
|
||||
void PIL_dynlib_close(PILdynlib *lib)
|
||||
{
|
||||
if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) ||
|
||||
(((struct mach_header *)lib->handle)->magic == MH_CIGAM))
|
||||
{
|
||||
osxerror(-1, "Can't remove dynamic libraries on darwin");
|
||||
}
|
||||
if (!NSUnLinkModule(lib->handle, 0))
|
||||
{
|
||||
osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle));
|
||||
}
|
||||
|
||||
free(lib);
|
||||
}
|
||||
|
||||
#else /* Unix */
|
||||
|
||||
#include <dlfcn.h>
|
||||
@@ -334,4 +136,4 @@ void PIL_dynlib_close(PILdynlib *lib) {
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user