forked from bartvdbraak/blender
Merged changes in the trunk up to revision 49478.
Conflicts resolved: source/blender/blenkernel/intern/library.c source/blender/blenloader/intern/readfile.c source/blender/editors/interface/resources.c source/blender/makesrna/intern/rna_scene.c
This commit is contained in:
commit
4ea2fb8b0a
@ -280,8 +280,10 @@ if 'blenderlite' in B.targets:
|
||||
if env['OURPLATFORM']=='darwin':
|
||||
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
|
||||
print "Available " + env['MACOSX_SDK_CHECK']
|
||||
if not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "MacOSX10.5.sdk not available:" + B.bc.ENDC + " using MacOSX10.6.sdk"
|
||||
if not 'Mac OS X 10.6' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.7.sdk"
|
||||
elif not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.6.sdk"
|
||||
else:
|
||||
print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
|
||||
|
||||
|
@ -32,6 +32,8 @@ elif cmd_res[:2]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
elif cmd_res[:2]=='11':
|
||||
MAC_CUR_VER='10.7'
|
||||
elif cmd_res[:2]=='12':
|
||||
MAC_CUR_VER='10.8'
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
@ -75,7 +77,7 @@ else :
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.6/7 with Xcode 4.x
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
@ -83,6 +85,14 @@ else :
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
# OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
@ -333,8 +343,8 @@ if not WITH_OSX_STATICPYTHON:
|
||||
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
#for 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_DEPLOYMENT_TARGET == '10.7':
|
||||
#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk"):
|
||||
LLIBS = ['stdc++']
|
||||
else:
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
|
@ -693,11 +693,23 @@ def UnixPyBundle(target=None, source=None, env=None):
|
||||
run("rm -r '%s/turtle.py'" % py_target)
|
||||
run("rm -f '%s/lib-dynload/_tkinter.so'" % py_target)
|
||||
|
||||
if env['WITH_BF_PYTHON_INSTALL_NUMPY']:
|
||||
numpy_src = py_src + "/site-packages/numpy"
|
||||
numpy_target = py_target + "/site-packages/numpy"
|
||||
|
||||
if os.path.exists(numpy_src):
|
||||
print 'Install numpy from:'
|
||||
print '\t"%s" into...' % numpy_src
|
||||
print '\t"%s"\n' % numpy_target
|
||||
|
||||
run("cp -R '%s' '%s'" % (numpy_src, os.path.dirname(numpy_target)))
|
||||
else:
|
||||
print 'Failed to find numpy at %s, skipping copying' % numpy_src
|
||||
|
||||
run("find '%s' -type d -name 'test' -prune -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -type d -name '__pycache__' -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -name '*.py[co]' -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -name '*.so' -exec strip -s {} ';'" % py_target)
|
||||
|
||||
|
||||
#### END ACTION STUFF #########
|
||||
|
||||
|
@ -135,7 +135,7 @@ def validate_arguments(args, bc):
|
||||
'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
|
||||
'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
|
||||
'WITHOUT_BF_INSTALL',
|
||||
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK',
|
||||
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK', 'WITH_BF_PYTHON_INSTALL_NUMPY'
|
||||
'WITHOUT_BF_OVERWRITE_INSTALL',
|
||||
'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH',
|
||||
'WITH_GHOST_COCOA',
|
||||
@ -520,6 +520,7 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_PYTHON_INSTALL', 'dont install Python modules if true', False)),
|
||||
(BoolVariable('WITH_BF_PYTHON_INSTALL_NUMPY', 'install Python mumpy module', False)),
|
||||
(BoolVariable('WITHOUT_BF_PYTHON_UNPACK', 'dont remove and unpack Python modules everytime if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_OVERWRITE_INSTALL', 'dont remove existing files before breating the new install directory (set to False when making packages for others)', False)),
|
||||
(BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
|
||||
|
@ -19,4 +19,4 @@ The execution context is as a non keyword, string argument in:
|
||||
|
||||
# group add popup
|
||||
import bpy
|
||||
bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
|
||||
bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
|
||||
|
@ -172,7 +172,7 @@ General functions
|
||||
|
||||
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
|
||||
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False)
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True)
|
||||
|
||||
Converts the all of the datablocks of the given type from the given blend.
|
||||
|
||||
@ -186,6 +186,8 @@ General functions
|
||||
:type load_actions: bool
|
||||
:arg verbose: Whether or not to print debugging information (e.g., "SceneName: Scene")
|
||||
:type verbose: bool
|
||||
:arg load_scripts: Whether or not to load text datablocks as well (can be disabled for some extra security)
|
||||
:type load_scripts: bool
|
||||
|
||||
.. function:: LibNew(name, type, data)
|
||||
|
||||
|
@ -56,7 +56,69 @@ To enable line length checks use this instead.
|
||||
User Interface Layout
|
||||
=====================
|
||||
|
||||
TODO: Thomas
|
||||
Some notes to keep in mind when writing UI layouts:
|
||||
|
||||
* UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
|
||||
General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong.
|
||||
|
||||
Example layouts:
|
||||
|
||||
* layout()
|
||||
|
||||
The basic layout is a simple Top -> Bottom layout.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
|
||||
* layout.row()
|
||||
|
||||
Use row(), when you want more than 1 propertey in one line.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
|
||||
* layout.column()
|
||||
|
||||
Use column(), when you want your properties in a column.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
* layout.split()
|
||||
|
||||
This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other.
|
||||
Don't use split, when you simply want two properties in a row. Use row() for that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
Declaration names:
|
||||
|
||||
Try to only use these variable names for layout declarations:
|
||||
|
||||
* row for a row() layout
|
||||
* col for a column() layout
|
||||
* split for a split() layout
|
||||
* flow for a column_flow() layout
|
||||
* sub for a sub layout (a column inside a column for example)
|
||||
|
||||
|
||||
Script Efficiency
|
||||
|
@ -979,6 +979,7 @@ def pycontext2sphinx(basepath):
|
||||
"meta_ball": ("MetaBall", False),
|
||||
"object": ("Object", False),
|
||||
"particle_edit_object": ("Object", False),
|
||||
"particle_settings": ("ParticleSettings", False),
|
||||
"particle_system": ("ParticleSystem", False),
|
||||
"particle_system_editable": ("ParticleSystem", False),
|
||||
"pose_bone": ("PoseBone", False),
|
||||
|
28
extern/bullet2/patches/ghost_character.patch
vendored
Normal file
28
extern/bullet2/patches/ghost_character.patch
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
Index: extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
|
||||
===================================================================
|
||||
--- extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (revision 49183)
|
||||
+++ extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (working copy)
|
||||
@@ -77,6 +77,9 @@
|
||||
if (convexResult.m_hitCollisionObject == m_me)
|
||||
return btScalar(1.0);
|
||||
|
||||
+ if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
+ return btScalar(1.0);
|
||||
+
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@@ -173,7 +176,12 @@
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
-
|
||||
+ btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
+ btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
+
|
||||
+ if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
+ continue;
|
||||
+
|
||||
if (collisionPair->m_algorithm)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
|
||||
|
4
extern/bullet2/readme.txt
vendored
4
extern/bullet2/readme.txt
vendored
@ -13,3 +13,7 @@ Originally committed in blender svn revision: 45908.
|
||||
Apply patches/make_id.patch to prevent duplicated define of MAKE_ID macro in blender
|
||||
side and bullet side.
|
||||
Sergey
|
||||
|
||||
Apply patches/ghost_character.path to prevent characters from colliding with ghost objects.
|
||||
Mitchell
|
||||
|
||||
|
@ -77,6 +77,9 @@ public:
|
||||
if (convexResult.m_hitCollisionObject == m_me)
|
||||
return btScalar(1.0);
|
||||
|
||||
if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
return btScalar(1.0);
|
||||
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@ -173,7 +176,12 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld*
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
|
||||
btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
|
||||
if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
continue;
|
||||
|
||||
if (collisionPair->m_algorithm)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
|
||||
|
||||
|
@ -209,7 +209,7 @@ void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, doub
|
||||
if( ix >= width-2 ) ix = width-2;
|
||||
if( iy >= height-2 ) iy = height-2;
|
||||
|
||||
Offset offset = { ix-x, iy-y, fx, fy };
|
||||
Offset offset = { (short)(ix-x), (short)(iy-y), (unsigned char)fx, (unsigned char)fy };
|
||||
grid->offset[y*width+x] = offset;
|
||||
}
|
||||
}
|
||||
|
4
extern/libmv/libmv/simple_pipeline/detect.cc
vendored
4
extern/libmv/libmv/simple_pipeline/detect.cc
vendored
@ -66,7 +66,7 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height
|
||||
Feature *all_features = new Feature[num_features];
|
||||
|
||||
for(int i = 0; i < num_features; ++i) {
|
||||
Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 };
|
||||
Feature a = { (float)nonmax[i].x, (float)nonmax[i].y, (float)scores[i], 0 };
|
||||
all_features[i] = a;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* det
|
||||
for(int y=16; y<height-16; y++) {
|
||||
for(int x=16; x<width-16; x++) {
|
||||
int s = scores[y*width+x];
|
||||
Feature f = { x+8, y+8, s, 16 };
|
||||
Feature f = { (float)x+8.0f, (float)y+8.0f, (float)s, 16 };
|
||||
if(s>min) detected[i++] = f;
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +163,8 @@
|
||||
|
||||
#include "Eigen/Core"
|
||||
|
||||
// Visual Studio 2010 or older version
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||
// Visual Studio 2012 or older version
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
namespace std {
|
||||
inline bool isfinite(double x) { return _finite(x); }
|
||||
inline bool isinf (double x) { return !_finite(x) && !_isnan(x); }
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_
|
||||
#define CERES_INTERNAL_COLLECTIONS_PORT_H_
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#else
|
||||
|
@ -321,7 +321,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
|
||||
// Find maximum deviation from the segment.
|
||||
float maxd = 0;
|
||||
int maxi = -1;
|
||||
int i_max = -1;
|
||||
int ci, cinc, endi;
|
||||
|
||||
// Traverse the segment in lexilogical order so that the
|
||||
@ -350,7 +350,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
if (d > maxd)
|
||||
{
|
||||
maxd = d;
|
||||
maxi = ci;
|
||||
i_max = ci;
|
||||
}
|
||||
ci = (ci+cinc) % pn;
|
||||
}
|
||||
@ -359,7 +359,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
|
||||
// If the max deviation is larger than accepted error,
|
||||
// add new point, else continue to next segment.
|
||||
if (maxi != -1 && maxd > (maxError*maxError))
|
||||
if (i_max != -1 && maxd > (maxError*maxError))
|
||||
{
|
||||
// Add space for the new point.
|
||||
simplified.resize(simplified.size()+4);
|
||||
@ -372,10 +372,10 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
simplified[j*4+3] = simplified[(j-1)*4+3];
|
||||
}
|
||||
// Add the point.
|
||||
simplified[(i+1)*4+0] = points[maxi*4+0];
|
||||
simplified[(i+1)*4+1] = points[maxi*4+1];
|
||||
simplified[(i+1)*4+2] = points[maxi*4+2];
|
||||
simplified[(i+1)*4+3] = maxi;
|
||||
simplified[(i+1)*4+0] = points[i_max*4+0];
|
||||
simplified[(i+1)*4+1] = points[i_max*4+1];
|
||||
simplified[(i+1)*4+2] = points[i_max*4+2];
|
||||
simplified[(i+1)*4+3] = i_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -399,7 +399,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
const int bi = simplified[ii*4+3];
|
||||
|
||||
// Find maximum deviation from the segment.
|
||||
int maxi = -1;
|
||||
int i_max = -1;
|
||||
int ci = (ai+1) % pn;
|
||||
|
||||
// Tessellate only outer edges or edges between areas.
|
||||
@ -423,19 +423,19 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
if (bx > ax || (bx == ax && bz > az))
|
||||
{
|
||||
const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
|
||||
maxi = (ai + n/2) % pn;
|
||||
i_max = (ai + n/2) % pn;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
|
||||
maxi = (ai + (n+1)/2) % pn;
|
||||
i_max = (ai + (n+1)/2) % pn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the max deviation is larger than accepted error,
|
||||
// add new point, else continue to next segment.
|
||||
if (maxi != -1)
|
||||
if (i_max != -1)
|
||||
{
|
||||
// Add space for the new point.
|
||||
simplified.resize(simplified.size()+4);
|
||||
@ -448,10 +448,10 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
|
||||
simplified[j*4+3] = simplified[(j-1)*4+3];
|
||||
}
|
||||
// Add the point.
|
||||
simplified[(i+1)*4+0] = points[maxi*4+0];
|
||||
simplified[(i+1)*4+1] = points[maxi*4+1];
|
||||
simplified[(i+1)*4+2] = points[maxi*4+2];
|
||||
simplified[(i+1)*4+3] = maxi;
|
||||
simplified[(i+1)*4+0] = points[i_max*4+0];
|
||||
simplified[(i+1)*4+1] = points[i_max*4+1];
|
||||
simplified[(i+1)*4+2] = points[i_max*4+2];
|
||||
simplified[(i+1)*4+3] = i_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -305,7 +305,7 @@ static int triangulate(int n, const int* verts, int* indices, int* tris)
|
||||
while (n > 3)
|
||||
{
|
||||
int minLen = -1;
|
||||
int mini = -1;
|
||||
int i_min = -1;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int i1 = next(i, n);
|
||||
@ -321,12 +321,12 @@ static int triangulate(int n, const int* verts, int* indices, int* tris)
|
||||
if (minLen < 0 || len < minLen)
|
||||
{
|
||||
minLen = len;
|
||||
mini = i;
|
||||
i_min = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mini == -1)
|
||||
if (i_min == -1)
|
||||
{
|
||||
// Should not happen.
|
||||
/* printf("mini == -1 ntris=%d n=%d\n", ntris, n);
|
||||
@ -338,7 +338,7 @@ static int triangulate(int n, const int* verts, int* indices, int* tris)
|
||||
return -ntris;
|
||||
}
|
||||
|
||||
int i = mini;
|
||||
int i = i_min;
|
||||
int i1 = next(i, n);
|
||||
int i2 = next(i1, n);
|
||||
|
||||
|
@ -579,23 +579,23 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
||||
const float* vb = &edge[b*3];
|
||||
// Find maximum deviation along the segment.
|
||||
float maxd = 0;
|
||||
int maxi = -1;
|
||||
int i_max = -1;
|
||||
for (int m = a+1; m < b; ++m)
|
||||
{
|
||||
float d = distancePtSeg(&edge[m*3],va,vb);
|
||||
if (d > maxd)
|
||||
{
|
||||
maxd = d;
|
||||
maxi = m;
|
||||
i_max = m;
|
||||
}
|
||||
}
|
||||
// If the max deviation is larger than accepted error,
|
||||
// add new point, else continue to next segment.
|
||||
if (maxi != -1 && maxd > rcSqr(sampleMaxError))
|
||||
if (i_max != -1 && maxd > rcSqr(sampleMaxError))
|
||||
{
|
||||
for (int m = nidx; m > k; --m)
|
||||
idx[m] = idx[m-1];
|
||||
idx[k+1] = maxi;
|
||||
idx[k+1] = i_max;
|
||||
nidx++;
|
||||
}
|
||||
else
|
||||
|
@ -56,8 +56,8 @@ public:
|
||||
AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency);
|
||||
|
||||
virtual void recalculateCoefficients(AUD_SampleRate rate,
|
||||
std::vector<float>& b,
|
||||
std::vector<float>& a);
|
||||
std::vector<float>& b,
|
||||
std::vector<float>& a);
|
||||
};
|
||||
|
||||
#endif //__AUD_BUTTERWORTHFACTORY_H__
|
||||
|
@ -56,8 +56,8 @@ public:
|
||||
* \param[out] a The output filter coefficients.
|
||||
*/
|
||||
virtual void recalculateCoefficients(AUD_SampleRate rate,
|
||||
std::vector<float>& b,
|
||||
std::vector<float>& a)=0;
|
||||
std::vector<float>& b,
|
||||
std::vector<float>& a)=0;
|
||||
};
|
||||
|
||||
#endif // __AUD_DYNAMICIIRFILTERFACTORY_H__
|
||||
|
@ -68,8 +68,8 @@ public:
|
||||
* \param length How long fading should last in seconds.
|
||||
*/
|
||||
AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory,
|
||||
AUD_FadeType type = AUD_FADE_IN,
|
||||
float start = 0.0f, float length = 1.0f);
|
||||
AUD_FadeType type = AUD_FADE_IN,
|
||||
float start = 0.0f, float length = 1.0f);
|
||||
|
||||
/**
|
||||
* Returns the fading type.
|
||||
|
@ -136,8 +136,8 @@ public:
|
||||
inline AUD_Vector3 cross(const AUD_Vector3& op) const
|
||||
{
|
||||
return AUD_Vector3(m_y * op.m_z - m_z * op.m_y,
|
||||
m_z * op.m_x - m_x * op.m_z,
|
||||
m_x * op.m_y - m_y * op.m_x);
|
||||
m_z * op.m_x - m_x * op.m_z,
|
||||
m_x * op.m_y - m_y * op.m_x);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -442,10 +442,10 @@ extern void AUD_closeReadDevice(AUD_Device* device);
|
||||
* The sound is therefore bandpassed, rectified and resampled.
|
||||
*/
|
||||
extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
||||
float attack, float release, float threshold,
|
||||
int accumulate, int additive, int square,
|
||||
float sthreshold, double samplerate,
|
||||
int* length);
|
||||
float attack, float release, float threshold,
|
||||
int accumulate, int additive, int square,
|
||||
float sthreshold, double samplerate,
|
||||
int* length);
|
||||
|
||||
/**
|
||||
* Pauses a playing sound after a specific amount of time.
|
||||
@ -493,7 +493,7 @@ extern void AUD_setSequencerFPS(AUD_Sound* sequencer, float fps);
|
||||
* \return The entry added.
|
||||
*/
|
||||
extern AUD_SEntry* AUD_addSequence(AUD_Sound* sequencer, AUD_Sound* sound,
|
||||
float begin, float end, float skip);
|
||||
float begin, float end, float skip);
|
||||
|
||||
/**
|
||||
* Removes an entry from the scene.
|
||||
@ -567,8 +567,8 @@ extern void AUD_setSequencerAnimData(AUD_Sound* sequencer, AUD_AnimateableProper
|
||||
* \param cone_volume_outer The volume outside the outer cone.
|
||||
*/
|
||||
extern void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float volume_min,
|
||||
float distance_max, float distance_reference, float attenuation,
|
||||
float cone_angle_outer, float cone_angle_inner, float cone_volume_outer);
|
||||
float distance_max, float distance_reference, float attenuation,
|
||||
float cone_angle_outer, float cone_angle_inner, float cone_volume_outer);
|
||||
|
||||
/**
|
||||
* Updates all non-animated parameters of the entry.
|
||||
@ -578,7 +578,7 @@ extern void AUD_updateSequenceData(AUD_SEntry* entry, float volume_max, float vo
|
||||
* \param model The distance model for distance calculation.
|
||||
*/
|
||||
extern void AUD_updateSequencerData(AUD_Sound* sequencer, float speed_of_sound,
|
||||
float factor, AUD_DistanceModel model);
|
||||
float factor, AUD_DistanceModel model);
|
||||
|
||||
/**
|
||||
* Sets the audio output specification of the sound scene to the specs of the
|
||||
|
@ -52,43 +52,43 @@ public:
|
||||
// Construction methods
|
||||
BOP_BSPNode(const MT_Plane3& plane);
|
||||
~BOP_BSPNode();
|
||||
unsigned int addFace(const BOP_BSPPoints& pts,
|
||||
const MT_Plane3& plane);
|
||||
BOP_TAG classifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
unsigned int addFace(const BOP_BSPPoints& pts,
|
||||
const MT_Plane3& plane);
|
||||
BOP_TAG classifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
|
||||
protected:
|
||||
BOP_TAG testPoint(const MT_Point3& p) const;
|
||||
BOP_TAG classifyFaceIN(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG classifyFaceOUT(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFaceIN(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFaceOUT(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG classifyFaceIN(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG classifyFaceOUT(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFaceIN(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG simplifiedClassifyFaceOUT(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
bool hasSameOrientation(const MT_Plane3& plane) const;
|
||||
int compChildren() const;
|
||||
int splitTriangle(MT_Point3* res,
|
||||
const MT_Plane3& plane,
|
||||
const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const BOP_TAG tag) const;
|
||||
int splitTriangle(MT_Point3* res,
|
||||
const MT_Plane3& plane,
|
||||
const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const BOP_TAG tag) const;
|
||||
|
||||
public:
|
||||
// Inline acces methods
|
||||
|
@ -50,22 +50,22 @@ public:
|
||||
virtual ~BOP_BSPTree();
|
||||
void addMesh(BOP_Mesh* mesh, BOP_Faces& facesList);
|
||||
void addFace(BOP_Mesh* mesh, BOP_Face* face);
|
||||
virtual void addFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane);
|
||||
BOP_TAG classifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG filterFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
BOP_Face* face);
|
||||
BOP_TAG simplifiedClassifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
virtual void addFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane);
|
||||
BOP_TAG classifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
BOP_TAG filterFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
BOP_Face* face);
|
||||
BOP_TAG simplifiedClassifyFace(const MT_Point3& p1,
|
||||
const MT_Point3& p2,
|
||||
const MT_Point3& p3,
|
||||
const MT_Plane3& plane) const;
|
||||
unsigned int getDeep() const;
|
||||
void print();
|
||||
inline void setRoot(BOP_BSPNode* root) {m_root=root;};
|
||||
|
@ -547,13 +547,32 @@ static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool Carve_checkDegeneratedFace(MeshSet<3>::face_t *face)
|
||||
static bool Carve_checkDegeneratedFace(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, MeshSet<3>::face_t *face)
|
||||
{
|
||||
/* only tris and quads for now */
|
||||
if (face->n_edges == 3) {
|
||||
uint v1, v2, v3;
|
||||
|
||||
v1 = vertexToIndex_map->find(face->edge->prev->vert)->second;
|
||||
v2 = vertexToIndex_map->find(face->edge->vert)->second;
|
||||
v3 = vertexToIndex_map->find(face->edge->next->vert)->second;
|
||||
|
||||
if (v1 == v2 || v2 == v3 || v1 == v3)
|
||||
return true;
|
||||
|
||||
return triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->vert->v) < DBL_EPSILON;
|
||||
}
|
||||
else if (face->n_edges == 4) {
|
||||
uint v1, v2, v3, v4;
|
||||
|
||||
v1 = vertexToIndex_map->find(face->edge->prev->vert)->second;
|
||||
v2 = vertexToIndex_map->find(face->edge->vert)->second;
|
||||
v3 = vertexToIndex_map->find(face->edge->next->vert)->second;
|
||||
v4 = vertexToIndex_map->find(face->edge->next->next->vert)->second;
|
||||
|
||||
if (v1 == v2 || v1 == v3 || v1 == v4 || v2 == v3 || v2 == v4 || v3 == v4)
|
||||
return true;
|
||||
|
||||
return triangleArea(face->edge->vert->v, face->edge->next->vert->v, face->edge->next->next->vert->v) +
|
||||
triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->next->vert->v) < DBL_EPSILON;
|
||||
}
|
||||
@ -595,8 +614,14 @@ static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::Face
|
||||
MeshSet<3>::face_iter face_iter = poly->faceBegin();
|
||||
for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) {
|
||||
MeshSet<3>::face_t *f = *face_iter;
|
||||
|
||||
if (Carve_checkDegeneratedFace(&vertexToIndex_map, f))
|
||||
continue;
|
||||
|
||||
ofaces[oface_num.getAttribute(f)].push_back(i);
|
||||
|
||||
MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
|
||||
|
||||
for (; edge_iter != f->end(); ++edge_iter) {
|
||||
int index = vertexToIndex_map[edge_iter->vert];
|
||||
vi[index].push_back(i);
|
||||
@ -659,36 +684,27 @@ static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::Face
|
||||
}
|
||||
}
|
||||
|
||||
bool degenerativeFace = false;
|
||||
// add all information except vertices to the output mesh
|
||||
outputMesh->FaceSet().push_back(BSP_MFace());
|
||||
BSP_MFace& outFace = outputMesh->FaceSet().back();
|
||||
outFace.m_verts.clear();
|
||||
outFace.m_plane.setValue(f->plane.N.v);
|
||||
outFace.m_orig_face = orig;
|
||||
|
||||
if (!result) {
|
||||
/* merged triangles are already checked for degenerative quad */
|
||||
degenerativeFace = Carve_checkDegeneratedFace(f);
|
||||
}
|
||||
|
||||
if (!degenerativeFace) {
|
||||
// add all information except vertices to the output mesh
|
||||
outputMesh->FaceSet().push_back(BSP_MFace());
|
||||
BSP_MFace& outFace = outputMesh->FaceSet().back();
|
||||
outFace.m_verts.clear();
|
||||
outFace.m_plane.setValue(f->plane.N.v);
|
||||
outFace.m_orig_face = orig;
|
||||
|
||||
// if we merged faces, use the list of common vertices; otherwise
|
||||
// use the faces's vertices
|
||||
if (result) {
|
||||
// make quat using verts stored in result
|
||||
outFace.m_verts.push_back(quadverts[0]);
|
||||
outFace.m_verts.push_back(quadverts[1]);
|
||||
outFace.m_verts.push_back(quadverts[2]);
|
||||
outFace.m_verts.push_back(quadverts[3]);
|
||||
} else {
|
||||
MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
|
||||
for (; edge_iter != f->end(); ++edge_iter) {
|
||||
//int index = ofacevert_num.getAttribute(f, edge_iter.idx());
|
||||
int index = vertexToIndex_map[edge_iter->vert];
|
||||
outFace.m_verts.push_back( index );
|
||||
}
|
||||
// if we merged faces, use the list of common vertices; otherwise
|
||||
// use the faces's vertices
|
||||
if (result) {
|
||||
// make quat using verts stored in result
|
||||
outFace.m_verts.push_back(quadverts[0]);
|
||||
outFace.m_verts.push_back(quadverts[1]);
|
||||
outFace.m_verts.push_back(quadverts[2]);
|
||||
outFace.m_verts.push_back(quadverts[3]);
|
||||
} else {
|
||||
MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
|
||||
for (; edge_iter != f->end(); ++edge_iter) {
|
||||
//int index = ofacevert_num.getAttribute(f, edge_iter.idx());
|
||||
int index = vertexToIndex_map[edge_iter->vert];
|
||||
outFace.m_verts.push_back( index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +306,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
|
||||
for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) {
|
||||
bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
|
||||
uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), object_is_light(*b_ob));
|
||||
CYCLES_LOCAL_LAYER_HACK(render_layer.use_localview, ob_layer);
|
||||
hide = hide || !(ob_layer & scene_layer);
|
||||
|
||||
if(!hide) {
|
||||
|
@ -144,16 +144,20 @@ void BlenderSync::sync_particles(Object *ob, BL::Object b_ob)
|
||||
BL::Object::particle_systems_iterator b_psys;
|
||||
for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
|
||||
if (use_particle_system(*b_psys)) {
|
||||
int pa_index = 0;
|
||||
BL::ParticleSystem::particles_iterator b_pa;
|
||||
for(b_psys->particles.begin(b_pa), index = 0; b_pa != b_psys->particles.end(); ++b_pa, ++index) {
|
||||
if(use_particle(*b_pa)) {
|
||||
Particle pa;
|
||||
|
||||
pa.index = pa_index;
|
||||
pa.age = b_scene.frame_current() - b_pa->birth_time();
|
||||
pa.lifetime = b_pa->lifetime();
|
||||
|
||||
ob->particles.push_back(pa);
|
||||
}
|
||||
|
||||
++pa_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,9 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
|
||||
layer = layername.c_str();
|
||||
}
|
||||
else {
|
||||
render_layer.use_localview = (b_v3d.local_view() ? true : false);
|
||||
render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view());
|
||||
CYCLES_LOCAL_LAYER_HACK(render_layer.use_localview, render_layer.scene_layer);
|
||||
render_layer.layer = render_layer.scene_layer;
|
||||
render_layer.holdout_layer = 0;
|
||||
render_layer.material_override = PointerRNA_NULL;
|
||||
@ -245,6 +247,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
|
||||
render_layer.material_override = b_rlay->material_override();
|
||||
render_layer.use_background = b_rlay->use_sky();
|
||||
render_layer.use_viewport_visibility = false;
|
||||
render_layer.use_localview = false;
|
||||
render_layer.samples = b_rlay->samples();
|
||||
}
|
||||
|
||||
|
@ -127,10 +127,25 @@ private:
|
||||
BL::Material material_override;
|
||||
bool use_background;
|
||||
bool use_viewport_visibility;
|
||||
bool use_localview;
|
||||
int samples;
|
||||
} render_layer;
|
||||
};
|
||||
|
||||
/* we don't have spare bits for localview (normally 20-28)
|
||||
* because PATH_RAY_LAYER_SHIFT uses 20-32.
|
||||
* So - check if we have localview and if so, shift local
|
||||
* view bits down to 1-8, since this is done for the view
|
||||
* port only - it should be OK and not conflict with
|
||||
* render layers. - Campbell.
|
||||
*
|
||||
* ... as an alternative we could use uint64_t
|
||||
*/
|
||||
#define CYCLES_LOCAL_LAYER_HACK(use_localview, layer) \
|
||||
if (use_localview) { \
|
||||
layer >>= 20; \
|
||||
} (void)0
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BLENDER_SYNC_H__ */
|
||||
|
@ -378,19 +378,10 @@ void BVH::pack_instances(size_t nodes_size)
|
||||
int mesh_tri_offset = mesh->tri_offset;
|
||||
|
||||
/* fill in node indexes for instances */
|
||||
if(
|
||||
/* XXX, brecht. check this is needed!. it could be a bug elsewhere
|
||||
* /mango/pro/scenes/04_2e/04_2e.blend r2158. on Ian's system 192.168.3.27 - campbell */
|
||||
(bvh->pack.is_leaf.size() != 0) &&
|
||||
|
||||
/* previously only checked this */
|
||||
bvh->pack.is_leaf[0])
|
||||
{
|
||||
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
|
||||
pack.object_node[object_offset++] = -noffset-1;
|
||||
}
|
||||
else {
|
||||
else
|
||||
pack.object_node[object_offset++] = noffset;
|
||||
}
|
||||
|
||||
mesh_map[mesh] = pack.object_node[object_offset-1];
|
||||
|
||||
|
@ -298,15 +298,12 @@ public:
|
||||
{
|
||||
string build_options = " -cl-fast-relaxed-math ";
|
||||
|
||||
/* Multi Closure for nVidia cards */
|
||||
if(platform_name == "NVIDIA CUDA")
|
||||
build_options += "-D__KERNEL_SHADING__ -D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose ";
|
||||
|
||||
/* No Float3 for Apple */
|
||||
|
||||
else if(platform_name == "Apple")
|
||||
build_options += "-D__CL_NO_FLOAT3__ -D__KERNEL_OPENCL_APPLE__ ";
|
||||
|
||||
/* Basic shading for AMD cards (non Apple) */
|
||||
|
||||
else if(platform_name == "AMD Accelerated Parallel Processing")
|
||||
build_options += "-D__CL_NO_FLOAT3__ -D__KERNEL_OPENCL_AMD__ ";
|
||||
|
||||
|
@ -87,8 +87,8 @@ __device_inline void sample_cos_hemisphere(const float3 N,
|
||||
}
|
||||
|
||||
__device_inline void sample_uniform_hemisphere(const float3 N,
|
||||
float randu, float randv,
|
||||
float3 *omega_in, float *pdf)
|
||||
float randu, float randv,
|
||||
float3 *omega_in, float *pdf)
|
||||
{
|
||||
float z = randu;
|
||||
float r = sqrtf(max(0.0f, 1.0f - z*z));
|
||||
|
@ -169,20 +169,27 @@ __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
|
||||
return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
|
||||
}
|
||||
|
||||
__device float particle_age(KernelGlobals *kg, int particle)
|
||||
__device_inline float particle_index(KernelGlobals *kg, int particle)
|
||||
{
|
||||
int offset = particle*PARTICLE_SIZE;
|
||||
float4 f = kernel_tex_fetch(__particles, offset);
|
||||
return f.x;
|
||||
}
|
||||
|
||||
__device float particle_lifetime(KernelGlobals *kg, int particle)
|
||||
__device float particle_age(KernelGlobals *kg, int particle)
|
||||
{
|
||||
int offset = particle*PARTICLE_SIZE;
|
||||
float4 f = kernel_tex_fetch(__particles, offset);
|
||||
return f.y;
|
||||
}
|
||||
|
||||
__device float particle_lifetime(KernelGlobals *kg, int particle)
|
||||
{
|
||||
int offset = particle*PARTICLE_SIZE;
|
||||
float4 f = kernel_tex_fetch(__particles, offset);
|
||||
return f.z;
|
||||
}
|
||||
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@ -288,7 +288,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
|
||||
if(sd.flag & SD_HOLDOUT_MASK)
|
||||
holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
|
||||
else
|
||||
shader_holdout_eval(kg, &sd);
|
||||
holdout_weight = shader_holdout_eval(kg, &sd);
|
||||
|
||||
/* any throughput is ok, should all be identical here */
|
||||
L_transparent += average(holdout_weight*throughput);
|
||||
@ -655,7 +655,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
|
||||
if(sd.flag & SD_HOLDOUT_MASK)
|
||||
holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
|
||||
else
|
||||
shader_holdout_eval(kg, &sd);
|
||||
holdout_weight = shader_holdout_eval(kg, &sd);
|
||||
|
||||
/* any throughput is ok, should all be identical here */
|
||||
L_transparent += average(holdout_weight*throughput);
|
||||
|
@ -172,6 +172,8 @@ enum PathRayFlag {
|
||||
|
||||
PATH_RAY_ALL = (1|2|4|8|16|32|64|128|256|512),
|
||||
|
||||
/* this gives collisions with localview bits
|
||||
* see: CYCLES_LOCAL_LAYER_HACK(), grr - Campbell */
|
||||
PATH_RAY_LAYER_SHIFT = (32-20)
|
||||
};
|
||||
|
||||
|
@ -101,6 +101,12 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
|
||||
float data;
|
||||
|
||||
switch(type) {
|
||||
case NODE_INFO_PAR_INDEX: {
|
||||
uint particle_id = object_particle_id(kg, sd->object);
|
||||
data = particle_index(kg, particle_id);
|
||||
stack_store_float(stack, out_offset, data);
|
||||
break;
|
||||
}
|
||||
case NODE_INFO_PAR_AGE: {
|
||||
uint particle_id = object_particle_id(kg, sd->object);
|
||||
data = particle_age(kg, particle_id);
|
||||
|
@ -114,6 +114,7 @@ typedef enum NodeObjectInfo {
|
||||
} NodeObjectInfo;
|
||||
|
||||
typedef enum NodeParticleInfo {
|
||||
NODE_INFO_PAR_INDEX,
|
||||
NODE_INFO_PAR_AGE,
|
||||
NODE_INFO_PAR_LIFETIME
|
||||
} NodeParticleInfo;
|
||||
|
@ -194,10 +194,11 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
||||
|
||||
/* sum area */
|
||||
if(have_emission) {
|
||||
bool transform_applied = mesh->transform_applied;
|
||||
Transform tfm = object->tfm;
|
||||
int object_id = j;
|
||||
|
||||
if(mesh->transform_applied)
|
||||
if(transform_applied)
|
||||
object_id = ~object_id;
|
||||
|
||||
for(size_t i = 0; i < mesh->triangles.size(); i++) {
|
||||
@ -211,9 +212,15 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
||||
offset++;
|
||||
|
||||
Mesh::Triangle t = mesh->triangles[i];
|
||||
float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
|
||||
float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
|
||||
float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
|
||||
float3 p1 = mesh->verts[t.v[0]];
|
||||
float3 p2 = mesh->verts[t.v[1]];
|
||||
float3 p3 = mesh->verts[t.v[2]];
|
||||
|
||||
if(!transform_applied) {
|
||||
p1 = transform_point(&tfm, p1);
|
||||
p2 = transform_point(&tfm, p2);
|
||||
p3 = transform_point(&tfm, p3);
|
||||
}
|
||||
|
||||
totarea += triangle_area(p1, p2, p3);
|
||||
}
|
||||
|
@ -1798,12 +1798,15 @@ void ObjectInfoNode::compile(OSLCompiler& compiler)
|
||||
ParticleInfoNode::ParticleInfoNode()
|
||||
: ShaderNode("particle_info")
|
||||
{
|
||||
add_output("Index", SHADER_SOCKET_FLOAT);
|
||||
add_output("Age", SHADER_SOCKET_FLOAT);
|
||||
add_output("Lifetime", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void ParticleInfoNode::attributes(AttributeRequestSet *attributes)
|
||||
{
|
||||
if(!output("Index")->links.empty())
|
||||
attributes->add(ATTR_STD_PARTICLE);
|
||||
if(!output("Age")->links.empty())
|
||||
attributes->add(ATTR_STD_PARTICLE);
|
||||
if(!output("Lifetime")->links.empty())
|
||||
@ -1816,6 +1819,12 @@ void ParticleInfoNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderOutput *out;
|
||||
|
||||
out = output("Index");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, out->stack_offset);
|
||||
}
|
||||
|
||||
out = output("Age");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
|
@ -111,8 +111,9 @@ void Object::apply_transform()
|
||||
mesh->compute_bounds();
|
||||
compute_bounds(false);
|
||||
}
|
||||
|
||||
tfm = transform_identity();
|
||||
|
||||
/* tfm is not reset to identity, all code that uses it needs to check the
|
||||
transform_applied boolean */
|
||||
}
|
||||
|
||||
void Object::tag_update(Scene *scene)
|
||||
@ -269,7 +270,7 @@ void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene,
|
||||
/* pack in texture */
|
||||
int offset = i*PARTICLE_SIZE;
|
||||
|
||||
particles[offset] = make_float4(pa.age, pa.lifetime, 0.0f, 0.0f);
|
||||
particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f);
|
||||
|
||||
i++;
|
||||
|
||||
|
@ -36,6 +36,7 @@ struct Transform;
|
||||
/* Object */
|
||||
|
||||
struct Particle {
|
||||
int index;
|
||||
float age;
|
||||
float lifetime;
|
||||
};
|
||||
|
@ -117,7 +117,7 @@ Patch *SubdAccBuilder::run(SubdFace *face)
|
||||
memcpy(patch->hull, position, sizeof(float3)*20);
|
||||
return patch;
|
||||
}
|
||||
else if(face->num_edges() == 4) {
|
||||
else if(face->num_edges() == 4) {
|
||||
GregoryQuadPatch *patch = new GregoryQuadPatch();
|
||||
memcpy(patch->hull, position, sizeof(float3)*20);
|
||||
return patch;
|
||||
@ -644,7 +644,7 @@ Patch *SubdLinearBuilder::run(SubdFace *face)
|
||||
hull = lpatch->hull;
|
||||
patch = lpatch;
|
||||
}
|
||||
else if(face->num_edges() == 4) {
|
||||
else if(face->num_edges() == 4) {
|
||||
LinearQuadPatch *lpatch = new LinearQuadPatch();
|
||||
hull = lpatch->hull;
|
||||
patch = lpatch;
|
||||
|
@ -26,6 +26,12 @@
|
||||
#include "util_path.h"
|
||||
#include "util_types.h"
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if (BOOST_VERSION < 104400)
|
||||
# define BOOST_FILESYSTEM_VERSION 2
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@ -115,7 +121,11 @@ void Cache::clear_except(const string& name, const set<string>& except)
|
||||
boost::filesystem::directory_iterator it(dir), it_end;
|
||||
|
||||
for(; it != it_end; it++) {
|
||||
#if (BOOST_FILESYSTEM_VERSION == 2)
|
||||
string filename = it->path().filename();
|
||||
#else
|
||||
string filename = it->path().filename().string();
|
||||
#endif
|
||||
|
||||
if(boost::starts_with(filename, name))
|
||||
if(except.find(filename) == except.end())
|
||||
|
@ -26,6 +26,12 @@ OIIO_NAMESPACE_USING
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if (BOOST_VERSION < 104400)
|
||||
# define BOOST_FILESYSTEM_VERSION 2
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@ -58,7 +64,11 @@ string path_user_get(const string& sub)
|
||||
|
||||
string path_filename(const string& path)
|
||||
{
|
||||
#if (BOOST_FILESYSTEM_VERSION == 2)
|
||||
return boost::filesystem::path(path).filename();
|
||||
#else
|
||||
return boost::filesystem::path(path).filename().string();
|
||||
#endif
|
||||
}
|
||||
|
||||
string path_dirname(const string& path)
|
||||
|
@ -174,7 +174,7 @@ BuildQuadrics(
|
||||
vector<LOD_Edge>::iterator edge_it = edges.begin();
|
||||
vector<LOD_Edge>::const_iterator edge_end = edges.end();
|
||||
|
||||
for (; edge_it != edge_end; ++edge_it) {
|
||||
for (; edge_it != edge_end; ++edge_it) {
|
||||
|
||||
MT_Vector3 target = TargetVertex(*edge_it);
|
||||
|
||||
@ -235,7 +235,7 @@ ComputeEdgeCosts(
|
||||
vector<LOD_EdgeInd>::const_iterator edge_it = edges.begin();
|
||||
vector<LOD_EdgeInd>::const_iterator edge_end = edges.end();
|
||||
|
||||
for (; edge_it != edge_end; ++edge_it) {
|
||||
for (; edge_it != edge_end; ++edge_it) {
|
||||
|
||||
MT_Vector3 target = TargetVertex(edge_set[*edge_it]);
|
||||
|
||||
|
@ -16,6 +16,13 @@
|
||||
|
||||
#include "mvmcoords.h"
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1600
|
||||
// sdt::greater
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
|
||||
using std::vector;
|
||||
|
||||
void MeanValueMeshCoords::clear()
|
||||
|
@ -278,7 +278,7 @@ public:
|
||||
GHOST_TUns8 mask[16][2],
|
||||
int hotX,
|
||||
int hotY) = 0;
|
||||
|
||||
|
||||
virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
|
||||
GHOST_TUns8 *mask,
|
||||
int sizex, int sizey,
|
||||
|
@ -48,7 +48,7 @@ GHOST_DisplayManagerX11(
|
||||
GHOST_DisplayManager(),
|
||||
m_system(system)
|
||||
{
|
||||
//nothing to do.
|
||||
/* nothing to do. */
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
@ -87,7 +87,7 @@ getNumDisplaySettings(
|
||||
XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes);
|
||||
|
||||
#else
|
||||
// We only have one X11 setting at the moment.
|
||||
/* We only have one X11 setting at the moment. */
|
||||
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
|
||||
numSettings = GHOST_TInt32(1);
|
||||
#endif
|
||||
@ -144,8 +144,8 @@ getDisplaySetting(
|
||||
setting.bpp = DefaultDepth(x_display, DefaultScreen(x_display));
|
||||
#endif
|
||||
|
||||
// Don't think it's possible to get this value from X!
|
||||
// So let's guess!!
|
||||
/* Don't think it's possible to get this value from X!
|
||||
* So let's guess!! */
|
||||
setting.frequency = 60;
|
||||
|
||||
return GHOST_kSuccess;
|
||||
@ -171,11 +171,10 @@ setCurrentDisplaySetting(
|
||||
const GHOST_DisplaySetting& setting)
|
||||
{
|
||||
#ifdef WITH_X11_XF86VMODE
|
||||
//
|
||||
// Mode switching code ported from Quake 2:
|
||||
// ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
|
||||
// See linux/gl_glx.c:GLimp_SetMode
|
||||
//
|
||||
/* Mode switching code ported from Quake 2:
|
||||
* ftp: ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
|
||||
* See linux/gl_glx.c:GLimp_SetMode
|
||||
*/
|
||||
int majorVersion, minorVersion;
|
||||
XF86VidModeModeInfo **vidmodes;
|
||||
Display *dpy = m_system->getXDisplay();
|
||||
@ -187,7 +186,7 @@ setCurrentDisplaySetting(
|
||||
|
||||
scrnum = DefaultScreen(dpy);
|
||||
|
||||
// Get video mode list
|
||||
/* Get video mode list */
|
||||
majorVersion = minorVersion = 0;
|
||||
if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
|
||||
fprintf(stderr, "Error: XF86VidMode extension missing!\n");
|
||||
@ -228,20 +227,21 @@ setCurrentDisplaySetting(
|
||||
actualWidth, actualHeight);
|
||||
# endif
|
||||
|
||||
// change to the mode
|
||||
/* change to the mode */
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
|
||||
|
||||
// Move the viewport to top left
|
||||
/* Move the viewport to top left */
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
}
|
||||
else
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
XFlush(dpy);
|
||||
return GHOST_kSuccess;
|
||||
|
||||
#else
|
||||
// Just pretend the request was successful.
|
||||
/* Just pretend the request was successful. */
|
||||
return GHOST_kSuccess;
|
||||
#endif
|
||||
}
|
||||
|
@ -144,23 +144,23 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char
|
||||
break;
|
||||
}
|
||||
|
||||
// We are now converting
|
||||
/* We are now converting */
|
||||
state = STATE_CONVERTING;
|
||||
break;
|
||||
|
||||
case STATE_CONVERTING:
|
||||
bothDigits = true;
|
||||
|
||||
// Create a buffer to hold the hex. For example, if %20, this
|
||||
// buffer would hold 20 (in ASCII)
|
||||
/* Create a buffer to hold the hex. For example, if %20, this
|
||||
* buffer would hold 20 (in ASCII) */
|
||||
memset(tempNumBuf, 0, sizeof(tempNumBuf));
|
||||
|
||||
// Conversion complete (i.e. don't convert again next iter)
|
||||
/* Conversion complete (i.e. don't convert again next iter) */
|
||||
state = STATE_SEARCH;
|
||||
|
||||
strncpy(tempNumBuf, &encodedIn[i], 2);
|
||||
|
||||
// Ensure both characters are hexadecimal
|
||||
/* Ensure both characters are hexadecimal */
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
if (!isxdigit(tempNumBuf[j]))
|
||||
@ -170,16 +170,16 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char
|
||||
if (!bothDigits)
|
||||
break;
|
||||
|
||||
// Convert two hexadecimal characters into one character
|
||||
/* Convert two hexadecimal characters into one character */
|
||||
sscanf(tempNumBuf, "%x", &asciiCharacter);
|
||||
|
||||
// Ensure we aren't going to overflow
|
||||
/* Ensure we aren't going to overflow */
|
||||
assert(strlen(decodedOut) < bufferSize);
|
||||
|
||||
// Concatenate this character onto the output
|
||||
/* Concatenate this character onto the output */
|
||||
strncat(decodedOut, (char *)&asciiCharacter, 1);
|
||||
|
||||
// Skip the next character
|
||||
/* Skip the next character */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
@ -58,8 +58,11 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
/* annoying for official builds, just adds noise and most prople don't own these */
|
||||
puts("ndof: spacenavd not found");
|
||||
/* This isn't a hard error, just means the user doesn't have a 3D mouse. */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,11 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h> // for fprintf only
|
||||
#include <cstdlib> // for exit
|
||||
#include <stdio.h> /* for fprintf only */
|
||||
#include <cstdlib> /* for exit */
|
||||
|
||||
#include <pwd.h> // for get home without use getenv()
|
||||
#include <limits.h> // for PATH_MAX
|
||||
#include <pwd.h> /* for get home without use getenv() */
|
||||
#include <limits.h> /* for PATH_MAX */
|
||||
|
||||
#ifdef PREFIX
|
||||
static const char *static_path = PREFIX "/share";
|
||||
|
@ -32,7 +32,6 @@
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
|
||||
#include "GHOST_SystemX11.h"
|
||||
#include "GHOST_WindowX11.h"
|
||||
#include "GHOST_WindowManager.h"
|
||||
@ -44,11 +43,11 @@
|
||||
#include "GHOST_DisplayManagerX11.h"
|
||||
#include "GHOST_EventDragnDrop.h"
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
#include "GHOST_NDOFManagerX11.h"
|
||||
# include "GHOST_NDOFManagerX11.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XDND
|
||||
#include "GHOST_DropTargetX11.h"
|
||||
# include "GHOST_DropTargetX11.h"
|
||||
#endif
|
||||
|
||||
#include "GHOST_Debug.h"
|
||||
@ -61,20 +60,19 @@
|
||||
#include <X11/XF86keysym.h>
|
||||
#endif
|
||||
|
||||
// For timing
|
||||
|
||||
/* For timing */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdio.h> // for fprintf only
|
||||
#include <cstdlib> // for exit
|
||||
#include <stdio.h> /* for fprintf only */
|
||||
#include <cstdlib> /* for exit */
|
||||
|
||||
static GHOST_TKey
|
||||
convertXKey(KeySym key);
|
||||
|
||||
//these are for copy and select copy
|
||||
/* these are for copy and select copy */
|
||||
static char *txt_cut_buffer = NULL;
|
||||
static char *txt_select_buffer = NULL;
|
||||
|
||||
@ -90,7 +88,7 @@ GHOST_SystemX11(
|
||||
|
||||
if (!m_display) {
|
||||
std::cerr << "Unable to open a display" << std::endl;
|
||||
abort(); //was return before, but this would just mean it will crash later
|
||||
abort(); /* was return before, but this would just mean it will crash later */
|
||||
}
|
||||
|
||||
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
|
||||
@ -128,13 +126,13 @@ GHOST_SystemX11(
|
||||
m_last_warp = 0;
|
||||
|
||||
|
||||
// compute the initial time
|
||||
/* compute the initial time */
|
||||
timeval tv;
|
||||
if (gettimeofday(&tv, NULL) == -1) {
|
||||
GHOST_ASSERT(false, "Could not instantiate timer!");
|
||||
}
|
||||
|
||||
// Taking care not to overflow the tv.tv_sec*1000
|
||||
/* Taking care not to overflow the tv.tv_sec*1000 */
|
||||
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
|
||||
@ -190,7 +188,7 @@ getMilliSeconds() const
|
||||
GHOST_ASSERT(false, "Could not compute time!");
|
||||
}
|
||||
|
||||
// Taking care not to overflow the tv.tv_sec*1000
|
||||
/* Taking care not to overflow the tv.tv_sec*1000 */
|
||||
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
|
||||
}
|
||||
|
||||
@ -254,16 +252,16 @@ createWindow(
|
||||
|
||||
|
||||
|
||||
window = new GHOST_WindowX11(
|
||||
this, m_display, title, left, top, width, height, state, parentWindow, type, stereoVisual
|
||||
);
|
||||
window = new GHOST_WindowX11(this, m_display, title,
|
||||
left, top, width, height,
|
||||
state, parentWindow, type, stereoVisual);
|
||||
|
||||
if (window) {
|
||||
// Both are now handle in GHOST_WindowX11.cpp
|
||||
// Focus and Delete atoms.
|
||||
/* Both are now handle in GHOST_WindowX11.cpp
|
||||
* Focus and Delete atoms. */
|
||||
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
/* Store the pointer to the window */
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
|
||||
@ -313,10 +311,10 @@ findGhostWindow(
|
||||
|
||||
if (xwind == 0) return NULL;
|
||||
|
||||
// It is not entirely safe to do this as the backptr may point
|
||||
// to a window that has recently been removed.
|
||||
// We should always check the window manager's list of windows
|
||||
// and only process events on these windows.
|
||||
/* It is not entirely safe to do this as the backptr may point
|
||||
* to a window that has recently been removed.
|
||||
* We should always check the window manager's list of windows
|
||||
* and only process events on these windows. */
|
||||
|
||||
vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
|
||||
|
||||
@ -411,8 +409,8 @@ GHOST_SystemX11::
|
||||
processEvents(
|
||||
bool waitForEvent)
|
||||
{
|
||||
// Get all the current events -- translate them into
|
||||
// ghost events and call base class pushEvent() method.
|
||||
/* Get all the current events -- translate them into
|
||||
* ghost events and call base class pushEvent() method. */
|
||||
|
||||
bool anyProcessed = false;
|
||||
|
||||
@ -519,8 +517,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
XExposeEvent & xee = xe->xexpose;
|
||||
|
||||
if (xee.count == 0) {
|
||||
// Only generate a single expose event
|
||||
// per read of the event queue.
|
||||
/* Only generate a single expose event
|
||||
* per read of the event queue. */
|
||||
|
||||
g_event = new
|
||||
GHOST_Event(
|
||||
@ -761,7 +759,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
break;
|
||||
}
|
||||
|
||||
// change of size, border, layer etc.
|
||||
/* change of size, border, layer etc. */
|
||||
case ConfigureNotify:
|
||||
{
|
||||
/* XConfigureEvent & xce = xe->xconfigure; */
|
||||
@ -780,12 +778,11 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
{
|
||||
XFocusChangeEvent &xfe = xe->xfocus;
|
||||
|
||||
// TODO: make sure this is the correct place for activate/deactivate
|
||||
/* TODO: make sure this is the correct place for activate/deactivate */
|
||||
// printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
|
||||
|
||||
// May have to look at the type of event and filter some
|
||||
// out.
|
||||
|
||||
/* May have to look at the type of event and filter some out. */
|
||||
|
||||
GHOST_TEventType gtype = (xfe.type == FocusIn) ?
|
||||
GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
|
||||
|
||||
@ -860,7 +857,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
|
||||
case DestroyNotify:
|
||||
::exit(-1);
|
||||
// We're not interested in the following things.(yet...)
|
||||
/* We're not interested in the following things.(yet...) */
|
||||
case NoExpose:
|
||||
case GraphicsExpose:
|
||||
break;
|
||||
@ -945,8 +942,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
nxe.xselection.target = xse->target;
|
||||
nxe.xselection.time = xse->time;
|
||||
|
||||
/*Check to see if the requestor is asking for String*/
|
||||
if (xse->target == utf8_string || xse->target == string || xse->target == compound_text || xse->target == c_string) {
|
||||
/* Check to see if the requestor is asking for String */
|
||||
if (xse->target == utf8_string ||
|
||||
xse->target == string ||
|
||||
xse->target == compound_text ||
|
||||
xse->target == c_string)
|
||||
{
|
||||
if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) {
|
||||
XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace,
|
||||
(unsigned char *)txt_select_buffer, strlen(txt_select_buffer));
|
||||
@ -968,11 +969,11 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
XFlush(m_display);
|
||||
}
|
||||
else {
|
||||
//Change property to None because we do not support anything but STRING
|
||||
/* Change property to None because we do not support anything but STRING */
|
||||
nxe.xselection.property = None;
|
||||
}
|
||||
|
||||
//Send the event to the client 0 0 == False, SelectionNotify
|
||||
/* Send the event to the client 0 0 == False, SelectionNotify */
|
||||
XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
|
||||
XFlush(m_display);
|
||||
break;
|
||||
@ -1023,14 +1024,14 @@ getModifierKeys(
|
||||
GHOST_ModifierKeys& keys) const
|
||||
{
|
||||
|
||||
// analyse the masks retuned from XQueryPointer.
|
||||
/* analyse the masks retuned from XQueryPointer. */
|
||||
|
||||
memset((void *)m_keyboard_vector, 0, sizeof(m_keyboard_vector));
|
||||
|
||||
XQueryKeymap(m_display, (char *)m_keyboard_vector);
|
||||
|
||||
// now translate key symobols into keycodes and
|
||||
// test with vector.
|
||||
/* now translate key symobols into keycodes and
|
||||
* test with vector. */
|
||||
|
||||
const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L);
|
||||
const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R);
|
||||
@ -1041,16 +1042,16 @@ getModifierKeys(
|
||||
const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
|
||||
const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
|
||||
|
||||
// shift
|
||||
/* shift */
|
||||
keys.set(GHOST_kModifierKeyLeftShift, ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightShift, ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0);
|
||||
// control
|
||||
/* control */
|
||||
keys.set(GHOST_kModifierKeyLeftControl, ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightControl, ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0);
|
||||
// alt
|
||||
/* alt */
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
|
||||
// super (windows) - only one GHOST-kModifierKeyOS, so mapping to either
|
||||
/* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
|
||||
keys.set(GHOST_kModifierKeyOS, ( ((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) ) != 0);
|
||||
|
||||
@ -1123,9 +1124,9 @@ setCursorPosition(
|
||||
GHOST_TInt32 y
|
||||
) {
|
||||
|
||||
// This is a brute force move in screen coordinates
|
||||
// XWarpPointer does relative moves so first determine the
|
||||
// current pointer position.
|
||||
/* This is a brute force move in screen coordinates
|
||||
* XWarpPointer does relative moves so first determine the
|
||||
* current pointer position. */
|
||||
|
||||
int cx, cy;
|
||||
if (getCursorPosition(cx, cy) == GHOST_kFailure) {
|
||||
@ -1336,15 +1337,15 @@ convertXKey(KeySym key)
|
||||
|
||||
/* from xclip.c xcout() v0.11 */
|
||||
|
||||
#define XCLIB_XCOUT_NONE 0 /* no context */
|
||||
#define XCLIB_XCOUT_NONE 0 /* no context */
|
||||
#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */
|
||||
#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
|
||||
#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
|
||||
#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */
|
||||
#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */
|
||||
#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */
|
||||
#define XCLIB_XCOUT_FALLBACK_TEXT 6
|
||||
|
||||
// Retrieves the contents of a selections.
|
||||
/* Retrieves the contents of a selections. */
|
||||
void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
|
||||
Atom sel, Atom target, unsigned char **txt,
|
||||
unsigned long *len, unsigned int *context) const
|
||||
@ -1361,15 +1362,15 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
|
||||
Window win = window->getXWindow();
|
||||
|
||||
switch (*context) {
|
||||
// There is no context, do an XConvertSelection()
|
||||
/* There is no context, do an XConvertSelection() */
|
||||
case XCLIB_XCOUT_NONE:
|
||||
// Initialise return length to 0
|
||||
/* Initialise return length to 0 */
|
||||
if (*len > 0) {
|
||||
free(*txt);
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
// Send a selection request
|
||||
/* Send a selection request */
|
||||
XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime);
|
||||
*context = XCLIB_XCOUT_SENTCONVSEL;
|
||||
return;
|
||||
@ -1391,22 +1392,22 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
|
||||
return;
|
||||
}
|
||||
|
||||
// find the size and format of the data in property
|
||||
/* find the size and format of the data in property */
|
||||
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
|
||||
AnyPropertyType, &pty_type, &pty_format,
|
||||
&pty_items, &pty_size, &buffer);
|
||||
XFree(buffer);
|
||||
|
||||
if (pty_type == m_incr) {
|
||||
// start INCR mechanism by deleting property
|
||||
/* start INCR mechanism by deleting property */
|
||||
XDeleteProperty(m_display, win, m_xclip_out);
|
||||
XFlush(m_display);
|
||||
*context = XCLIB_XCOUT_INCR;
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's not incr, and not format == 8, then there's
|
||||
// nothing in the selection (that xclip understands, anyway)
|
||||
/* if it's not incr, and not format == 8, then there's
|
||||
* nothing in the selection (that xclip understands, anyway) */
|
||||
|
||||
if (pty_format != 8) {
|
||||
*context = XCLIB_XCOUT_NONE;
|
||||
@ -1418,73 +1419,73 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
|
||||
False, AnyPropertyType, &pty_type,
|
||||
&pty_format, &pty_items, &pty_size, &buffer);
|
||||
|
||||
// finished with property, delete it
|
||||
/* finished with property, delete it */
|
||||
XDeleteProperty(m_display, win, m_xclip_out);
|
||||
|
||||
// copy the buffer to the pointer for returned data
|
||||
/* copy the buffer to the pointer for returned data */
|
||||
ltxt = (unsigned char *) malloc(pty_items);
|
||||
memcpy(ltxt, buffer, pty_items);
|
||||
|
||||
// set the length of the returned data
|
||||
/* set the length of the returned data */
|
||||
*len = pty_items;
|
||||
*txt = ltxt;
|
||||
|
||||
// free the buffer
|
||||
/* free the buffer */
|
||||
XFree(buffer);
|
||||
|
||||
*context = XCLIB_XCOUT_NONE;
|
||||
|
||||
// complete contents of selection fetched, return 1
|
||||
/* complete contents of selection fetched, return 1 */
|
||||
return;
|
||||
|
||||
case XCLIB_XCOUT_INCR:
|
||||
// To use the INCR method, we basically delete the
|
||||
// property with the selection in it, wait for an
|
||||
// event indicating that the property has been created,
|
||||
// then read it, delete it, etc.
|
||||
/* To use the INCR method, we basically delete the
|
||||
* property with the selection in it, wait for an
|
||||
* event indicating that the property has been created,
|
||||
* then read it, delete it, etc. */
|
||||
|
||||
// make sure that the event is relevant
|
||||
/* make sure that the event is relevant */
|
||||
if (evt.type != PropertyNotify)
|
||||
return;
|
||||
|
||||
// skip unless the property has a new value
|
||||
/* skip unless the property has a new value */
|
||||
if (evt.xproperty.state != PropertyNewValue)
|
||||
return;
|
||||
|
||||
// check size and format of the property
|
||||
/* check size and format of the property */
|
||||
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
|
||||
AnyPropertyType, &pty_type, &pty_format,
|
||||
&pty_items, &pty_size, (unsigned char **) &buffer);
|
||||
|
||||
if (pty_format != 8) {
|
||||
// property does not contain text, delete it
|
||||
// to tell the other X client that we have read
|
||||
// it and to send the next property
|
||||
/* property does not contain text, delete it
|
||||
* to tell the other X client that we have read
|
||||
* it and to send the next property */
|
||||
XFree(buffer);
|
||||
XDeleteProperty(m_display, win, m_xclip_out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pty_size == 0) {
|
||||
// no more data, exit from loop
|
||||
/* no more data, exit from loop */
|
||||
XFree(buffer);
|
||||
XDeleteProperty(m_display, win, m_xclip_out);
|
||||
*context = XCLIB_XCOUT_NONE;
|
||||
|
||||
// this means that an INCR transfer is now
|
||||
// complete, return 1
|
||||
/* this means that an INCR transfer is now
|
||||
* complete, return 1 */
|
||||
return;
|
||||
}
|
||||
|
||||
XFree(buffer);
|
||||
|
||||
// if we have come this far, the propery contains
|
||||
// text, we know the size.
|
||||
/* if we have come this far, the property contains
|
||||
* text, we know the size. */
|
||||
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
|
||||
False, AnyPropertyType, &pty_type, &pty_format,
|
||||
&pty_items, &pty_size, (unsigned char **) &buffer);
|
||||
|
||||
// allocate memory to accommodate data in *txt
|
||||
/* allocate memory to accommodate data in *txt */
|
||||
if (*len == 0) {
|
||||
*len = pty_items;
|
||||
ltxt = (unsigned char *) malloc(*len);
|
||||
@ -1494,13 +1495,13 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
|
||||
ltxt = (unsigned char *) realloc(ltxt, *len);
|
||||
}
|
||||
|
||||
// add data to ltxt
|
||||
/* add data to ltxt */
|
||||
memcpy(<xt[*len - pty_items], buffer, pty_items);
|
||||
|
||||
*txt = ltxt;
|
||||
XFree(buffer);
|
||||
|
||||
// delete property to get the next item
|
||||
/* delete property to get the next item */
|
||||
XDeleteProperty(m_display, win, m_xclip_out);
|
||||
XFlush(m_display);
|
||||
return;
|
||||
@ -1514,7 +1515,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
|
||||
Atom target = m_utf8_string;
|
||||
Window owner;
|
||||
|
||||
// from xclip.c doOut() v0.11
|
||||
/* from xclip.c doOut() v0.11 */
|
||||
unsigned char *sel_buf;
|
||||
unsigned long sel_len = 0;
|
||||
XEvent evt;
|
||||
|
@ -335,7 +335,7 @@ protected:
|
||||
/** Modified state : are there unsaved changes */
|
||||
bool m_isUnsavedChanges;
|
||||
|
||||
/** Stores wether this is a full screen window. */
|
||||
/** Stores whether this is a full screen window. */
|
||||
bool m_fullScreen;
|
||||
|
||||
/** Stereo visual created. Only necessary for 'real' stereo support,
|
||||
|
@ -81,9 +81,9 @@ protected:
|
||||
GHOST_TSuccess activateDrawingContext( ) { return GHOST_kFailure; }
|
||||
~GHOST_WindowNULL( ) { /* nothing */ }
|
||||
GHOST_TSuccess setWindowCursorVisibility( bool visible ) { return GHOST_kSuccess; }
|
||||
GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; }
|
||||
GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; }
|
||||
GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; }
|
||||
GHOST_TSuccess invalidate() { return GHOST_kSuccess; }
|
||||
GHOST_TSuccess invalidate() { return GHOST_kSuccess; }
|
||||
GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; }
|
||||
|
||||
|
||||
|
@ -1343,7 +1343,7 @@ static int EnumPixelFormats(HDC hdc)
|
||||
::DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
w = WeightPixelFormat(pfd);
|
||||
// be strict on stereo
|
||||
if (!((sPreferredFormat.dwFlags ^ pfd.dwFlags) & PFD_STEREO)) {
|
||||
if (!((sPreferredFormat.dwFlags ^ pfd.dwFlags) & PFD_STEREO)) {
|
||||
if (w > weight) {
|
||||
weight = w;
|
||||
iPixelFormat = i;
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "GHOST_DropTargetX11.h"
|
||||
#endif
|
||||
|
||||
// For standard X11 cursors
|
||||
/* For standard X11 cursors */
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
@ -53,8 +53,8 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
// For obscure full screen mode stuuf
|
||||
// lifted verbatim from blut.
|
||||
/* For obscure full screen mode stuuf
|
||||
* lifted verbatim from blut. */
|
||||
|
||||
typedef struct {
|
||||
long flags;
|
||||
@ -95,7 +95,7 @@ typedef struct {
|
||||
f.write('\n')
|
||||
*/
|
||||
|
||||
// See the python script above to regenerate the 48x48 icon within blender
|
||||
/* See the python script above to regenerate the 48x48 icon within blender */
|
||||
#define BLENDER_ICON_WIDTH 48
|
||||
#define BLENDER_ICON_HEIGHT 48
|
||||
static unsigned char BLENDER_ICON_48x48x24[] = {
|
||||
@ -178,13 +178,13 @@ GHOST_WindowX11(
|
||||
m_custom_cursor(None)
|
||||
{
|
||||
|
||||
// Set up the minimum atrributes that we require and see if
|
||||
// X can find us a visual matching those requirements.
|
||||
/* Set up the minimum atrributes that we require and see if
|
||||
* X can find us a visual matching those requirements. */
|
||||
|
||||
int attributes[40], i, samples;
|
||||
Atom atoms[2];
|
||||
int natom;
|
||||
int glxVersionMajor, glxVersionMinor; // As in GLX major.minor
|
||||
int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* initialize incase X11 fails to load */
|
||||
@ -251,11 +251,11 @@ GHOST_WindowX11(
|
||||
}
|
||||
}
|
||||
|
||||
// Create a bunch of attributes needed to create an X window.
|
||||
/* Create a bunch of attributes needed to create an X window. */
|
||||
|
||||
|
||||
// First create a colormap for the window and visual.
|
||||
// This seems pretty much a legacy feature as we are in rgba mode anyway.
|
||||
/* First create a colormap for the window and visual.
|
||||
* This seems pretty much a legacy feature as we are in rgba mode anyway. */
|
||||
|
||||
XSetWindowAttributes xattributes;
|
||||
memset(&xattributes, 0, sizeof(xattributes));
|
||||
@ -268,7 +268,7 @@ GHOST_WindowX11(
|
||||
|
||||
xattributes.border_pixel = 0;
|
||||
|
||||
// Specify which events we are interested in hearing.
|
||||
/* Specify which events we are interested in hearing. */
|
||||
|
||||
xattributes.event_mask =
|
||||
ExposureMask | StructureNotifyMask |
|
||||
@ -277,7 +277,7 @@ GHOST_WindowX11(
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | FocusChangeMask | PropertyChangeMask;
|
||||
|
||||
// create the window!
|
||||
/* create the window! */
|
||||
|
||||
;
|
||||
if (parentWindow == 0) {
|
||||
@ -287,7 +287,7 @@ GHOST_WindowX11(
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
0, // no border.
|
||||
0, /* no border. */
|
||||
m_visual->depth,
|
||||
InputOutput,
|
||||
m_visual->visual,
|
||||
@ -311,12 +311,12 @@ GHOST_WindowX11(
|
||||
|
||||
|
||||
m_window = XCreateWindow(m_display,
|
||||
parentWindow, // reparent against embedder
|
||||
parentWindow, /* reparent against embedder */
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
0, // no border.
|
||||
0, /* no border. */
|
||||
m_visual->depth,
|
||||
InputOutput,
|
||||
m_visual->visual,
|
||||
@ -353,9 +353,9 @@ GHOST_WindowX11(
|
||||
m_post_init = False;
|
||||
m_post_state = GHOST_kWindowStateNormal;
|
||||
}
|
||||
|
||||
// Create some hints for the window manager on how
|
||||
// we want this window treated.
|
||||
|
||||
/* Create some hints for the window manager on how
|
||||
* we want this window treated. */
|
||||
|
||||
XSizeHints *xsizehints = XAllocSizeHints();
|
||||
xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
|
||||
@ -363,8 +363,8 @@ GHOST_WindowX11(
|
||||
xsizehints->y = top;
|
||||
xsizehints->width = width;
|
||||
xsizehints->height = height;
|
||||
xsizehints->min_width = 320; // size hints, could be made apart of the ghost api
|
||||
xsizehints->min_height = 240; // limits are also arbitrary, but should not allow 1x1 window
|
||||
xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
|
||||
xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
|
||||
xsizehints->max_width = 65535;
|
||||
xsizehints->max_height = 65535;
|
||||
XSetWMNormalHints(m_display, m_window, xsizehints);
|
||||
@ -404,7 +404,7 @@ GHOST_WindowX11(
|
||||
m_xic = NULL;
|
||||
#endif
|
||||
|
||||
// Set the window icon
|
||||
/* Set the window icon */
|
||||
XWMHints *xwmhints = XAllocWMHints();
|
||||
XImage *x_image, *mask_image;
|
||||
Pixmap icon_pixmap, mask_pixmap;
|
||||
@ -442,7 +442,7 @@ GHOST_WindowX11(
|
||||
XPutImage(display, icon_pixmap, gc_icon, x_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
|
||||
XPutImage(display, mask_pixmap, gc_mask, mask_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
|
||||
|
||||
// Now the pixmap is ok to assign to the window as a hint
|
||||
/* Now the pixmap is ok to assign to the window as a hint */
|
||||
xwmhints->icon_pixmap = icon_pixmap;
|
||||
xwmhints->icon_mask = mask_pixmap;
|
||||
XFreeGC(display, gc_icon);
|
||||
@ -455,7 +455,7 @@ GHOST_WindowX11(
|
||||
xwmhints->flags = InputHint | IconPixmapHint | IconMaskHint | StateHint;
|
||||
XSetWMHints(display, m_window, xwmhints);
|
||||
XFree(xwmhints);
|
||||
// done setting the icon
|
||||
/* done setting the icon */
|
||||
|
||||
setTitle(title);
|
||||
|
||||
@ -463,7 +463,7 @@ GHOST_WindowX11(
|
||||
initXInputDevices();
|
||||
#endif
|
||||
|
||||
// now set up the rendering context.
|
||||
/* now set up the rendering context. */
|
||||
if (installDrawingContext(type) == GHOST_kSuccess) {
|
||||
m_valid_setup = true;
|
||||
GHOST_PRINT("Created window\n");
|
||||
@ -748,8 +748,8 @@ setTitle(
|
||||
(const unsigned char *) title.ReadPtr(),
|
||||
title.Length());
|
||||
|
||||
// This should convert to valid x11 string
|
||||
// and getTitle would need matching change
|
||||
/* This should convert to valid x11 string
|
||||
* and getTitle would need matching change */
|
||||
XStoreName(m_display, m_window, title);
|
||||
|
||||
XFlush(m_display);
|
||||
@ -772,8 +772,8 @@ GHOST_WindowX11::
|
||||
getWindowBounds(
|
||||
GHOST_Rect& bounds) const
|
||||
{
|
||||
// Getting the window bounds under X11 is not
|
||||
// really supported (nor should it be desired).
|
||||
/* Getting the window bounds under X11 is not
|
||||
* really supported (nor should it be desired). */
|
||||
getClientBounds(bounds);
|
||||
}
|
||||
|
||||
@ -848,7 +848,7 @@ screenToClient(
|
||||
GHOST_TInt32& outX,
|
||||
GHOST_TInt32& outY) const
|
||||
{
|
||||
// This is correct!
|
||||
/* This is correct! */
|
||||
|
||||
int ax, ay;
|
||||
Window temp;
|
||||
@ -1274,18 +1274,18 @@ GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
invalidate()
|
||||
{
|
||||
// So the idea of this function is to generate an expose event
|
||||
// for the window.
|
||||
// Unfortunately X does not handle expose events for you and
|
||||
// it is the client's job to refresh the dirty part of the window.
|
||||
// We need to queue up invalidate calls and generate GHOST events
|
||||
// for them in the system.
|
||||
|
||||
// We implement this by setting a boolean in this class to concatenate
|
||||
// all such calls into a single event for this window.
|
||||
|
||||
// At the same time we queue the dirty windows in the system class
|
||||
// and generate events for them at the next processEvents call.
|
||||
/* So the idea of this function is to generate an expose event
|
||||
* for the window.
|
||||
* Unfortunately X does not handle expose events for you and
|
||||
* it is the client's job to refresh the dirty part of the window.
|
||||
* We need to queue up invalidate calls and generate GHOST events
|
||||
* for them in the system.
|
||||
*
|
||||
* We implement this by setting a boolean in this class to concatenate
|
||||
* all such calls into a single event for this window.
|
||||
*
|
||||
* At the same time we queue the dirty windows in the system class
|
||||
* and generate events for them at the next processEvents call. */
|
||||
|
||||
if (m_invalid_window == false) {
|
||||
m_system->addDirtyWindow(this);
|
||||
@ -1384,7 +1384,7 @@ GHOST_WindowX11::
|
||||
installDrawingContext(
|
||||
GHOST_TDrawingContextType type)
|
||||
{
|
||||
// only support openGL for now.
|
||||
/* only support openGL for now. */
|
||||
GHOST_TSuccess success;
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
|
@ -63,6 +63,9 @@
|
||||
#include <stdio.h> /* needed for FILE* */
|
||||
#include "MEM_sys_types.h" /* needed for uintptr_t */
|
||||
|
||||
/* some GNU attributes are only available from GCC 4.3 */
|
||||
#define MEM_GNU_ATTRIBUTES (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -71,7 +74,7 @@ extern "C" {
|
||||
* by vmemh. If the pointer was not previously allocated by this
|
||||
* module, the result is undefined.*/
|
||||
size_t MEM_allocN_len(const void *vmemh)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
#endif
|
||||
;
|
||||
@ -90,7 +93,7 @@ extern "C" {
|
||||
* Duplicates a block of memory, and returns a pointer to the
|
||||
* newly allocated block. */
|
||||
void *MEM_dupallocN(void *vmemh)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
#endif
|
||||
;
|
||||
@ -101,7 +104,7 @@ extern "C" {
|
||||
* as a system realloc but just makes a new allocation and copies
|
||||
* over from existing memory. */
|
||||
void *MEM_reallocN(void *vmemh, size_t len)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
__attribute__((alloc_size(2)))
|
||||
#endif
|
||||
@ -112,7 +115,7 @@ extern "C" {
|
||||
* memory is cleared. The name must be static, because only a
|
||||
* pointer to it is stored ! */
|
||||
void *MEM_callocN(size_t len, const char *str)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
__attribute__((nonnull(2)))
|
||||
__attribute__((alloc_size(1)))
|
||||
@ -124,7 +127,7 @@ extern "C" {
|
||||
* name must be a static, because only a pointer to it is stored !
|
||||
* */
|
||||
void *MEM_mallocN(size_t len, const char *str)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
__attribute__((nonnull(2)))
|
||||
__attribute__((alloc_size(1)))
|
||||
@ -136,7 +139,7 @@ extern "C" {
|
||||
* Can be free'd with MEM_freeN as usual.
|
||||
* */
|
||||
void *MEM_mapallocN(size_t len, const char *str)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
__attribute__((nonnull(2)))
|
||||
__attribute__((alloc_size(1)))
|
||||
@ -188,7 +191,7 @@ extern "C" {
|
||||
|
||||
/** Get the peak memory usage in bytes, including mmap allocations. */
|
||||
uintptr_t MEM_get_peak_memory(void)
|
||||
#ifdef __GNUC__
|
||||
#if MEM_GNU_ATTRIBUTES
|
||||
__attribute__((warn_unused_result))
|
||||
#endif
|
||||
;
|
||||
|
@ -54,6 +54,14 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* Only for debugging:
|
||||
* store original buffer's name when doing MEM_dupallocN
|
||||
* helpful to profile issues with non-freed "dup_alloc" buffers,
|
||||
* but this introduces some overhead to memory header and makes
|
||||
* things slower a bit, so betterto keep disabled by default
|
||||
*/
|
||||
//#define DEBUG_MEMDUPLINAME
|
||||
|
||||
/* Only for debugging:
|
||||
* lets you count the allocations so as to find the allocator of unfreed memory
|
||||
* in situations where the leak is predictable */
|
||||
@ -96,6 +104,10 @@ typedef struct MemHead {
|
||||
#ifdef DEBUG_MEMCOUNTER
|
||||
int _count;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MEMDUPLINAME
|
||||
int need_free_name, pad;
|
||||
#endif
|
||||
} MemHead;
|
||||
|
||||
typedef struct MemTail {
|
||||
@ -243,13 +255,36 @@ void *MEM_dupallocN(void *vmemh)
|
||||
if (vmemh) {
|
||||
MemHead *memh = vmemh;
|
||||
memh--;
|
||||
|
||||
|
||||
#ifndef DEBUG_MEMDUPLINAME
|
||||
if (memh->mmap)
|
||||
newp = MEM_mapallocN(memh->len, "dupli_mapalloc");
|
||||
else
|
||||
newp = MEM_mallocN(memh->len, "dupli_alloc");
|
||||
|
||||
if (newp == NULL) return NULL;
|
||||
#else
|
||||
{
|
||||
MemHead *nmemh;
|
||||
char *name = malloc(strlen(memh->name) + 24);
|
||||
|
||||
if (memh->mmap) {
|
||||
sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
|
||||
newp = MEM_mapallocN(memh->len, name);
|
||||
}
|
||||
else {
|
||||
sprintf(name, "%s %s", "dupli_alloc", memh->name);
|
||||
newp = MEM_mallocN(memh->len, name);
|
||||
}
|
||||
|
||||
if (newp == NULL) return NULL;
|
||||
|
||||
nmemh = newp;
|
||||
nmemh--;
|
||||
|
||||
nmemh->need_free_name = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy(newp, vmemh, memh->len);
|
||||
}
|
||||
@ -289,6 +324,10 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str)
|
||||
memh->len = len;
|
||||
memh->mmap = 0;
|
||||
memh->tag2 = MEMTAG2;
|
||||
|
||||
#ifdef DEBUG_MEMDUPLINAME
|
||||
memh->need_free_name = 0;
|
||||
#endif
|
||||
|
||||
memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
|
||||
memt->tag3 = MEMTAG3;
|
||||
@ -605,7 +644,7 @@ void MEM_printmemlist_pydict(void)
|
||||
MEM_printmemlist_internal(1);
|
||||
}
|
||||
|
||||
short MEM_freeN(void *vmemh) /* anders compileertie niet meer */
|
||||
short MEM_freeN(void *vmemh)
|
||||
{
|
||||
short error = 0;
|
||||
MemTail *memt;
|
||||
@ -733,6 +772,11 @@ static void rem_memblock(MemHead *memh)
|
||||
totblock--;
|
||||
mem_in_use -= memh->len;
|
||||
|
||||
#ifdef DEBUG_MEMDUPLINAME
|
||||
if (memh->need_free_name)
|
||||
free((char *) memh->name);
|
||||
#endif
|
||||
|
||||
if (memh->mmap) {
|
||||
mmap_in_use -= memh->len;
|
||||
if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
|
||||
|
3
intern/iksolver/extern/IK_solver.h
vendored
3
intern/iksolver/extern/IK_solver.h
vendored
@ -163,6 +163,9 @@ float IK_SolverGetPoleAngle(IK_Solver *solver);
|
||||
|
||||
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
|
||||
|
||||
#define IK_STRETCH_STIFF_EPS 0.001f
|
||||
#define IK_STRETCH_STIFF_MIN 0.001f
|
||||
#define IK_STRETCH_STIFF_MAX 1e10
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "TNT/svd.h"
|
||||
|
||||
IK_QJacobian::IK_QJacobian()
|
||||
: m_sdls(true), m_min_damp(1.0)
|
||||
: m_sdls(true), m_min_damp(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -106,16 +106,16 @@ void IK_QJacobian::ArmMatrices(int dof, int task_size)
|
||||
|
||||
void IK_QJacobian::SetBetas(int id, int, const MT_Vector3& v)
|
||||
{
|
||||
m_beta[id] = v.x();
|
||||
m_beta[id+1] = v.y();
|
||||
m_beta[id+2] = v.z();
|
||||
m_beta[id + 0] = v.x();
|
||||
m_beta[id + 1] = v.y();
|
||||
m_beta[id + 2] = v.z();
|
||||
}
|
||||
|
||||
void IK_QJacobian::SetDerivatives(int id, int dof_id, const MT_Vector3& v, MT_Scalar norm_weight)
|
||||
{
|
||||
m_jacobian[id][dof_id] = v.x()*m_weight_sqrt[dof_id];
|
||||
m_jacobian[id+1][dof_id] = v.y()*m_weight_sqrt[dof_id];
|
||||
m_jacobian[id+2][dof_id] = v.z()*m_weight_sqrt[dof_id];
|
||||
m_jacobian[id + 0][dof_id] = v.x() * m_weight_sqrt[dof_id];
|
||||
m_jacobian[id + 1][dof_id] = v.y() * m_weight_sqrt[dof_id];
|
||||
m_jacobian[id + 2][dof_id] = v.z() * m_weight_sqrt[dof_id];
|
||||
|
||||
m_d_norm_weight[dof_id] = norm_weight;
|
||||
}
|
||||
@ -194,7 +194,7 @@ void IK_QJacobian::SubTask(IK_QJacobian& jacobian)
|
||||
// doesn't work well at all
|
||||
int i;
|
||||
for (i = 0; i < m_d_theta.size(); i++)
|
||||
m_d_theta[i] = m_d_theta[i] + /*m_min_damp**/jacobian.AngleUpdate(i);
|
||||
m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i);
|
||||
}
|
||||
|
||||
void IK_QJacobian::Restrict(TVector& d_theta, TMatrix& null)
|
||||
@ -230,7 +230,7 @@ void IK_QJacobian::InvertSDLS()
|
||||
// DLS. The SDLS damps individual singular values, instead of using a single
|
||||
// damping term.
|
||||
|
||||
MT_Scalar max_angle_change = MT_PI/4.0;
|
||||
MT_Scalar max_angle_change = MT_PI / 4.0;
|
||||
MT_Scalar epsilon = 1e-10;
|
||||
int i, j;
|
||||
|
||||
@ -239,35 +239,35 @@ void IK_QJacobian::InvertSDLS()
|
||||
|
||||
for (i = 0; i < m_dof; i++) {
|
||||
m_norm[i] = 0.0;
|
||||
for (j = 0; j < m_task_size; j+=3) {
|
||||
for (j = 0; j < m_task_size; j += 3) {
|
||||
MT_Scalar n = 0.0;
|
||||
n += m_jacobian[j][i]*m_jacobian[j][i];
|
||||
n += m_jacobian[j+1][i]*m_jacobian[j+1][i];
|
||||
n += m_jacobian[j+2][i]*m_jacobian[j+2][i];
|
||||
n += m_jacobian[j][i] * m_jacobian[j][i];
|
||||
n += m_jacobian[j + 1][i] * m_jacobian[j + 1][i];
|
||||
n += m_jacobian[j + 2][i] * m_jacobian[j + 2][i];
|
||||
m_norm[i] += sqrt(n);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i<m_svd_w.size(); i++) {
|
||||
for (i = 0; i < m_svd_w.size(); i++) {
|
||||
if (m_svd_w[i] <= epsilon)
|
||||
continue;
|
||||
|
||||
MT_Scalar wInv = 1.0/m_svd_w[i];
|
||||
MT_Scalar wInv = 1.0 / m_svd_w[i];
|
||||
MT_Scalar alpha = 0.0;
|
||||
MT_Scalar N = 0.0;
|
||||
|
||||
// compute alpha and N
|
||||
for (j=0; j<m_svd_u.num_rows(); j+=3) {
|
||||
alpha += m_svd_u[j][i]*m_beta[j];
|
||||
alpha += m_svd_u[j+1][i]*m_beta[j+1];
|
||||
alpha += m_svd_u[j+2][i]*m_beta[j+2];
|
||||
for (j = 0; j < m_svd_u.num_rows(); j += 3) {
|
||||
alpha += m_svd_u[j][i] * m_beta[j];
|
||||
alpha += m_svd_u[j + 1][i] * m_beta[j + 1];
|
||||
alpha += m_svd_u[j + 2][i] * m_beta[j + 2];
|
||||
|
||||
// note: for 1 end effector, N will always be 1, since U is
|
||||
// orthogonal, .. so could be optimized
|
||||
MT_Scalar tmp;
|
||||
tmp = m_svd_u[j][i]*m_svd_u[j][i];
|
||||
tmp += m_svd_u[j+1][i]*m_svd_u[j+1][i];
|
||||
tmp += m_svd_u[j+2][i]*m_svd_u[j+2][i];
|
||||
tmp = m_svd_u[j][i] * m_svd_u[j][i];
|
||||
tmp += m_svd_u[j + 1][i] * m_svd_u[j + 1][i];
|
||||
tmp += m_svd_u[j + 2][i] * m_svd_u[j + 2][i];
|
||||
N += sqrt(tmp);
|
||||
}
|
||||
alpha *= wInv;
|
||||
@ -278,14 +278,14 @@ void IK_QJacobian::InvertSDLS()
|
||||
|
||||
for (j = 0; j < m_d_theta.size(); j++) {
|
||||
MT_Scalar v = m_svd_v[j][i];
|
||||
M += MT_abs(v)*m_norm[j];
|
||||
M += MT_abs(v) * m_norm[j];
|
||||
|
||||
// compute tmporary dTheta's
|
||||
m_d_theta_tmp[j] = v*alpha;
|
||||
m_d_theta_tmp[j] = v * alpha;
|
||||
|
||||
// find largest absolute dTheta
|
||||
// multiply with weight to prevent unnecessary damping
|
||||
abs_dtheta = MT_abs(m_d_theta_tmp[j])*m_weight_sqrt[j];
|
||||
abs_dtheta = MT_abs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
|
||||
if (abs_dtheta > max_dtheta)
|
||||
max_dtheta = abs_dtheta;
|
||||
}
|
||||
@ -295,19 +295,19 @@ void IK_QJacobian::InvertSDLS()
|
||||
// compute damping term and damp the dTheta's
|
||||
MT_Scalar gamma = max_angle_change;
|
||||
if (N < M)
|
||||
gamma *= N/M;
|
||||
gamma *= N / M;
|
||||
|
||||
MT_Scalar damp = (gamma < max_dtheta)? gamma/max_dtheta: 1.0;
|
||||
MT_Scalar damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
|
||||
|
||||
for (j = 0; j < m_d_theta.size(); j++) {
|
||||
// slight hack: we do 0.80*, so that if there is some oscillation,
|
||||
// the system can still converge (for joint limits). also, it's
|
||||
// better to go a little to slow than to far
|
||||
|
||||
MT_Scalar dofdamp = damp/m_weight[j];
|
||||
MT_Scalar dofdamp = damp / m_weight[j];
|
||||
if (dofdamp > 1.0) dofdamp = 1.0;
|
||||
|
||||
m_d_theta[j] += 0.80*dofdamp*m_d_theta_tmp[j];
|
||||
m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
|
||||
}
|
||||
|
||||
if (damp < m_min_damp)
|
||||
@ -317,7 +317,7 @@ void IK_QJacobian::InvertSDLS()
|
||||
// weight + prevent from doing angle updates with angles > max_angle_change
|
||||
MT_Scalar max_angle = 0.0, abs_angle;
|
||||
|
||||
for (j = 0; j<m_dof; j++) {
|
||||
for (j = 0; j < m_dof; j++) {
|
||||
m_d_theta[j] *= m_weight[j];
|
||||
|
||||
abs_angle = MT_abs(m_d_theta[j]);
|
||||
@ -327,9 +327,9 @@ void IK_QJacobian::InvertSDLS()
|
||||
}
|
||||
|
||||
if (max_angle > max_angle_change) {
|
||||
MT_Scalar damp = (max_angle_change)/(max_angle_change + max_angle);
|
||||
MT_Scalar damp = (max_angle_change) / (max_angle_change + max_angle);
|
||||
|
||||
for (j = 0; j<m_dof; j++)
|
||||
for (j = 0; j < m_dof; j++)
|
||||
m_d_theta[j] *= damp;
|
||||
}
|
||||
}
|
||||
@ -360,20 +360,20 @@ void IK_QJacobian::InvertDLS()
|
||||
int i, j;
|
||||
MT_Scalar w_min = MT_INFINITY;
|
||||
|
||||
for (i = 0; i <m_svd_w.size() ; i++) {
|
||||
for (i = 0; i < m_svd_w.size(); i++) {
|
||||
if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min)
|
||||
w_min = m_svd_w[i];
|
||||
}
|
||||
|
||||
// compute lambda damping term
|
||||
|
||||
MT_Scalar d = x_length/max_angle_change;
|
||||
MT_Scalar d = x_length / max_angle_change;
|
||||
MT_Scalar lambda;
|
||||
|
||||
if (w_min <= d/2)
|
||||
lambda = d/2;
|
||||
if (w_min <= d / 2)
|
||||
lambda = d / 2;
|
||||
else if (w_min < d)
|
||||
lambda = sqrt(w_min*(d - w_min));
|
||||
lambda = sqrt(w_min * (d - w_min));
|
||||
else
|
||||
lambda = 0.0;
|
||||
|
||||
@ -393,17 +393,17 @@ void IK_QJacobian::InvertDLS()
|
||||
|
||||
for (i = 0; i < m_svd_w.size(); i++) {
|
||||
if (m_svd_w[i] > epsilon) {
|
||||
MT_Scalar wInv = m_svd_w[i]/(m_svd_w[i]*m_svd_w[i] + lambda);
|
||||
MT_Scalar wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda);
|
||||
|
||||
// compute V*Winv*Ut*Beta
|
||||
m_svd_u_beta[i] *= wInv;
|
||||
|
||||
for (j = 0; j<m_d_theta.size(); j++)
|
||||
m_d_theta[j] += m_svd_v[j][i]*m_svd_u_beta[i];
|
||||
for (j = 0; j < m_d_theta.size(); j++)
|
||||
m_d_theta[j] += m_svd_v[j][i] * m_svd_u_beta[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j<m_d_theta.size(); j++)
|
||||
for (j = 0; j < m_d_theta.size(); j++)
|
||||
m_d_theta[j] *= m_weight[j];
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ void IK_QJacobian::Lock(int dof_id, MT_Scalar delta)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m_task_size; i++) {
|
||||
m_beta[i] -= m_jacobian[i][dof_id]*delta;
|
||||
m_beta[i] -= m_jacobian[i][dof_id] * delta;
|
||||
m_jacobian[i][dof_id] = 0.0;
|
||||
}
|
||||
|
||||
@ -431,7 +431,7 @@ MT_Scalar IK_QJacobian::AngleUpdateNorm() const
|
||||
MT_Scalar mx = 0.0, dtheta_abs;
|
||||
|
||||
for (i = 0; i < m_d_theta.size(); i++) {
|
||||
dtheta_abs = MT_abs(m_d_theta[i]*m_d_norm_weight[i]);
|
||||
dtheta_abs = MT_abs(m_d_theta[i] * m_d_norm_weight[i]);
|
||||
if (dtheta_abs > mx)
|
||||
mx = dtheta_abs;
|
||||
}
|
||||
|
@ -45,22 +45,22 @@ IK_QJacobianSolver::IK_QJacobianSolver()
|
||||
|
||||
MT_Scalar IK_QJacobianSolver::ComputeScale()
|
||||
{
|
||||
std::vector<IK_QSegment*>::iterator seg;
|
||||
float length = 0.0f;
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
MT_Scalar length = 0.0f;
|
||||
|
||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
||||
length += (*seg)->MaxExtension();
|
||||
|
||||
if(length == 0.0f)
|
||||
return 1.0f;
|
||||
if (length == 0.0)
|
||||
return 1.0;
|
||||
else
|
||||
return 1.0f/length;
|
||||
return 1.0 / length;
|
||||
}
|
||||
|
||||
void IK_QJacobianSolver::Scale(float scale, std::list<IK_QTask*>& tasks)
|
||||
void IK_QJacobianSolver::Scale(MT_Scalar scale, std::list<IK_QTask *>& tasks)
|
||||
{
|
||||
std::list<IK_QTask*>::iterator task;
|
||||
std::vector<IK_QSegment*>::iterator seg;
|
||||
std::list<IK_QTask *>::iterator task;
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
|
||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
||||
(*task)->Scale(scale);
|
||||
@ -82,13 +82,13 @@ void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
|
||||
AddSegmentList(child);
|
||||
}
|
||||
|
||||
bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
|
||||
bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *>& tasks)
|
||||
{
|
||||
m_segments.clear();
|
||||
AddSegmentList(root);
|
||||
|
||||
// assign each segment a unique id for the jacobian
|
||||
std::vector<IK_QSegment*>::iterator seg;
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
int num_dof = 0;
|
||||
|
||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||
@ -103,7 +103,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
|
||||
int primary_size = 0, primary = 0;
|
||||
int secondary_size = 0, secondary = 0;
|
||||
MT_Scalar primary_weight = 0.0, secondary_weight = 0.0;
|
||||
std::list<IK_QTask*>::iterator task;
|
||||
std::list<IK_QTask *>::iterator task;
|
||||
|
||||
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||
IK_QTask *qtask = *task;
|
||||
@ -128,20 +128,20 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
|
||||
m_secondary_enabled = (secondary > 0);
|
||||
|
||||
// rescale weights of tasks to sum up to 1
|
||||
MT_Scalar primary_rescale = 1.0/primary_weight;
|
||||
MT_Scalar primary_rescale = 1.0 / primary_weight;
|
||||
MT_Scalar secondary_rescale;
|
||||
if (MT_fuzzyZero(secondary_weight))
|
||||
secondary_rescale = 0.0;
|
||||
else
|
||||
secondary_rescale = 1.0/secondary_weight;
|
||||
secondary_rescale = 1.0 / secondary_weight;
|
||||
|
||||
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||
IK_QTask *qtask = *task;
|
||||
|
||||
if (qtask->Primary())
|
||||
qtask->SetWeight(qtask->Weight()*primary_rescale);
|
||||
qtask->SetWeight(qtask->Weight() * primary_rescale);
|
||||
else
|
||||
qtask->SetWeight(qtask->Weight()*secondary_rescale);
|
||||
qtask->SetWeight(qtask->Weight() * secondary_rescale);
|
||||
}
|
||||
|
||||
// set matrix sizes
|
||||
@ -154,7 +154,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
|
||||
|
||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
||||
for (i = 0; i < (*seg)->NumberOfDoF(); i++)
|
||||
m_jacobian.SetDoFWeight((*seg)->DoFId()+i, (*seg)->Weight(i));
|
||||
m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -165,15 +165,15 @@ void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& g
|
||||
m_poletip = tip;
|
||||
m_goal = goal;
|
||||
m_polegoal = polegoal;
|
||||
m_poleangle = (getangle)? 0.0f: poleangle;
|
||||
m_poleangle = (getangle) ? 0.0f : poleangle;
|
||||
m_getpoleangle = getangle;
|
||||
}
|
||||
|
||||
static MT_Scalar safe_acos(MT_Scalar f)
|
||||
{
|
||||
// acos that does not return NaN with rounding errors
|
||||
if (f <= -1.0f) return MT_PI;
|
||||
else if (f >= 1.0f) return 0.0;
|
||||
if (f <= -1.0) return MT_PI;
|
||||
else if (f >= 1.0) return 0.0;
|
||||
else return acos(f);
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ static MT_Vector3 normalize(const MT_Vector3& v)
|
||||
// a sane normalize function that doesn't give (1, 0, 0) in case
|
||||
// of a zero length vector, like MT_Vector3.normalize
|
||||
MT_Scalar len = v.length();
|
||||
return MT_fuzzyZero(len)? MT_Vector3(0, 0, 0): v/len;
|
||||
return MT_fuzzyZero(len) ? MT_Vector3(0, 0, 0) : v / len;
|
||||
}
|
||||
|
||||
static float angle(const MT_Vector3& v1, const MT_Vector3& v2)
|
||||
@ -190,21 +190,21 @@ static float angle(const MT_Vector3& v1, const MT_Vector3& v2)
|
||||
return safe_acos(v1.dot(v2));
|
||||
}
|
||||
|
||||
void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks)
|
||||
void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask *>& tasks)
|
||||
{
|
||||
// this function will be called before and after solving. calling it before
|
||||
// solving gives predictable solutions by rotating towards the solution,
|
||||
// and calling it afterwards ensures the solution is exact.
|
||||
|
||||
if(!m_poleconstraint)
|
||||
if (!m_poleconstraint)
|
||||
return;
|
||||
|
||||
// disable pole vector constraint in case of multiple position tasks
|
||||
std::list<IK_QTask*>::iterator task;
|
||||
std::list<IK_QTask *>::iterator task;
|
||||
int positiontasks = 0;
|
||||
|
||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
||||
if((*task)->PositionTask())
|
||||
if ((*task)->PositionTask())
|
||||
positiontasks++;
|
||||
|
||||
if (positiontasks >= 2) {
|
||||
@ -223,12 +223,12 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
||||
// an up vector, with the direction going from the root to the end effector
|
||||
// and the up vector going from the root to the pole constraint position.
|
||||
MT_Vector3 dir = normalize(endpos - rootpos);
|
||||
MT_Vector3 rootx= rootbasis.getColumn(0);
|
||||
MT_Vector3 rootz= rootbasis.getColumn(2);
|
||||
MT_Vector3 up = rootx*cos(m_poleangle) + rootz*sin(m_poleangle);
|
||||
MT_Vector3 rootx = rootbasis.getColumn(0);
|
||||
MT_Vector3 rootz = rootbasis.getColumn(2);
|
||||
MT_Vector3 up = rootx * cos(m_poleangle) + rootz *sin(m_poleangle);
|
||||
|
||||
// in post, don't rotate towards the goal but only correct the pole up
|
||||
MT_Vector3 poledir = (m_getpoleangle)? dir: normalize(m_goal - rootpos);
|
||||
MT_Vector3 poledir = (m_getpoleangle) ? dir : normalize(m_goal - rootpos);
|
||||
MT_Vector3 poleup = normalize(m_polegoal - rootpos);
|
||||
|
||||
MT_Matrix3x3 mat, polemat;
|
||||
@ -241,11 +241,11 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
||||
polemat[1] = MT_cross(polemat[0], poledir);
|
||||
polemat[2] = -poledir;
|
||||
|
||||
if(m_getpoleangle) {
|
||||
if (m_getpoleangle) {
|
||||
// we compute the pole angle that to rotate towards the target
|
||||
m_poleangle = angle(mat[1], polemat[1]);
|
||||
|
||||
if(rootz.dot(mat[1]*cos(m_poleangle) + mat[0]*sin(m_poleangle)) > 0.0f)
|
||||
if (rootz.dot(mat[1] * cos(m_poleangle) + mat[0] * sin(m_poleangle)) > 0.0)
|
||||
m_poleangle = -m_poleangle;
|
||||
|
||||
// solve again, with the pole angle we just computed
|
||||
@ -257,15 +257,15 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
||||
// desired rotation based on the pole vector constraint. we use
|
||||
// transpose instead of inverse because we have orthogonal matrices
|
||||
// anyway, and in case of a singular matrix we don't get NaN's.
|
||||
MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed()*mat);
|
||||
m_rootmatrix = trans*m_rootmatrix;
|
||||
MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed() * mat);
|
||||
m_rootmatrix = trans * m_rootmatrix;
|
||||
}
|
||||
}
|
||||
|
||||
bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm)
|
||||
{
|
||||
// assing each segment a unique id for the jacobian
|
||||
std::vector<IK_QSegment*>::iterator seg;
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
IK_QSegment *qseg, *minseg = NULL;
|
||||
MT_Scalar minabsdelta = 1e10, absdelta;
|
||||
MT_Vector3 delta, mindelta;
|
||||
@ -318,11 +318,11 @@ bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm)
|
||||
}
|
||||
|
||||
bool IK_QJacobianSolver::Solve(
|
||||
IK_QSegment *root,
|
||||
std::list<IK_QTask*> tasks,
|
||||
const MT_Scalar,
|
||||
const int max_iterations
|
||||
)
|
||||
IK_QSegment *root,
|
||||
std::list<IK_QTask *> tasks,
|
||||
const MT_Scalar,
|
||||
const int max_iterations
|
||||
)
|
||||
{
|
||||
float scale = ComputeScale();
|
||||
bool solved = false;
|
||||
@ -339,7 +339,7 @@ bool IK_QJacobianSolver::Solve(
|
||||
// update transform
|
||||
root->UpdateTransform(m_rootmatrix);
|
||||
|
||||
std::list<IK_QTask*>::iterator task;
|
||||
std::list<IK_QTask *>::iterator task;
|
||||
|
||||
// compute jacobian
|
||||
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||
@ -367,7 +367,7 @@ bool IK_QJacobianSolver::Solve(
|
||||
} while (UpdateAngles(norm));
|
||||
|
||||
// unlock segments again after locking in clamping loop
|
||||
std::vector<IK_QSegment*>::iterator seg;
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
||||
(*seg)->UnLock();
|
||||
|
||||
@ -383,10 +383,10 @@ bool IK_QJacobianSolver::Solve(
|
||||
}
|
||||
}
|
||||
|
||||
if(m_poleconstraint)
|
||||
if (m_poleconstraint)
|
||||
root->PrependBasis(m_rootmatrix.getBasis());
|
||||
|
||||
Scale(1.0f/scale, tasks);
|
||||
Scale(1.0f / scale, tasks);
|
||||
|
||||
//analyze_add_run(max_iterations, analyze_time()-dt);
|
||||
|
||||
|
@ -77,7 +77,7 @@ private:
|
||||
void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks);
|
||||
|
||||
MT_Scalar ComputeScale();
|
||||
void Scale(float scale, std::list<IK_QTask*>& tasks);
|
||||
void Scale(MT_Scalar scale, std::list<IK_QTask*>& tasks);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -60,24 +60,25 @@ static MT_Matrix3x3 RotationMatrix(MT_Scalar angle, int axis)
|
||||
|
||||
static MT_Scalar EulerAngleFromMatrix(const MT_Matrix3x3& R, int axis)
|
||||
{
|
||||
MT_Scalar t = sqrt(R[0][0]*R[0][0] + R[0][1]*R[0][1]);
|
||||
MT_Scalar t = sqrt(R[0][0] * R[0][0] + R[0][1] * R[0][1]);
|
||||
|
||||
if (t > 16.0*MT_EPSILON) {
|
||||
if (axis == 0) return -atan2(R[1][2], R[2][2]);
|
||||
else if(axis == 1) return atan2(-R[0][2], t);
|
||||
else return -atan2(R[0][1], R[0][0]);
|
||||
} else {
|
||||
if (axis == 0) return -atan2(-R[2][1], R[1][1]);
|
||||
else if(axis == 1) return atan2(-R[0][2], t);
|
||||
else return 0.0f;
|
||||
}
|
||||
if (t > 16.0 * MT_EPSILON) {
|
||||
if (axis == 0) return -atan2(R[1][2], R[2][2]);
|
||||
else if (axis == 1) return atan2(-R[0][2], t);
|
||||
else return -atan2(R[0][1], R[0][0]);
|
||||
}
|
||||
else {
|
||||
if (axis == 0) return -atan2(-R[2][1], R[1][1]);
|
||||
else if (axis == 1) return atan2(-R[0][2], t);
|
||||
else return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static MT_Scalar safe_acos(MT_Scalar f)
|
||||
{
|
||||
if (f <= -1.0f)
|
||||
if (f <= -1.0)
|
||||
return MT_PI;
|
||||
else if (f >= 1.0f)
|
||||
else if (f >= 1.0)
|
||||
return 0.0;
|
||||
else
|
||||
return acos(f);
|
||||
@ -89,7 +90,7 @@ static MT_Scalar ComputeTwist(const MT_Matrix3x3& R)
|
||||
MT_Scalar qy = R[0][2] - R[2][0];
|
||||
MT_Scalar qw = R[0][0] + R[1][1] + R[2][2] + 1;
|
||||
|
||||
MT_Scalar tau = 2*atan2(qy, qw);
|
||||
MT_Scalar tau = 2.0 * atan2(qy, qw);
|
||||
|
||||
return tau;
|
||||
}
|
||||
@ -108,7 +109,7 @@ static void RemoveTwist(MT_Matrix3x3& R)
|
||||
MT_Matrix3x3 T = ComputeTwistMatrix(tau);
|
||||
|
||||
// remove twist
|
||||
R = R*T.transposed();
|
||||
R = R * T.transposed();
|
||||
}
|
||||
|
||||
static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R)
|
||||
@ -117,7 +118,7 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R)
|
||||
MT_Scalar tau = ComputeTwist(R);
|
||||
|
||||
// compute swing parameters
|
||||
MT_Scalar num = 2.0*(1.0 + R[1][1]);
|
||||
MT_Scalar num = 2.0 * (1.0 + R[1][1]);
|
||||
|
||||
// singularity at pi
|
||||
if (MT_abs(num) < MT_EPSILON)
|
||||
@ -126,9 +127,9 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R)
|
||||
// enforce limits at all then
|
||||
return MT_Vector3(0.0, tau, 1.0);
|
||||
|
||||
num = 1.0/sqrt(num);
|
||||
MT_Scalar ax = -R[2][1]*num;
|
||||
MT_Scalar az = R[0][1]*num;
|
||||
num = 1.0 / sqrt(num);
|
||||
MT_Scalar ax = -R[2][1] * num;
|
||||
MT_Scalar az = R[0][1] * num;
|
||||
|
||||
return MT_Vector3(ax, tau, az);
|
||||
}
|
||||
@ -136,8 +137,8 @@ static MT_Vector3 SphericalRangeParameters(const MT_Matrix3x3& R)
|
||||
static MT_Matrix3x3 ComputeSwingMatrix(MT_Scalar ax, MT_Scalar az)
|
||||
{
|
||||
// length of (ax, 0, az) = sin(theta/2)
|
||||
MT_Scalar sine2 = ax*ax + az*az;
|
||||
MT_Scalar cosine2 = sqrt((sine2 >= 1.0)? 0.0: 1.0-sine2);
|
||||
MT_Scalar sine2 = ax * ax + az * az;
|
||||
MT_Scalar cosine2 = sqrt((sine2 >= 1.0) ? 0.0 : 1.0 - sine2);
|
||||
|
||||
// compute swing matrix
|
||||
MT_Matrix3x3 S(MT_Quaternion(ax, 0.0, az, -cosine2));
|
||||
@ -151,11 +152,11 @@ static MT_Vector3 MatrixToAxisAngle(const MT_Matrix3x3& R)
|
||||
R[0][2] - R[2][0],
|
||||
R[1][0] - R[0][1]);
|
||||
|
||||
MT_Scalar c = safe_acos((R[0][0] + R[1][1] + R[2][2] - 1)/2);
|
||||
MT_Scalar c = safe_acos((R[0][0] + R[1][1] + R[2][2] - 1) / 2);
|
||||
MT_Scalar l = delta.length();
|
||||
|
||||
if (!MT_fuzzyZero(l))
|
||||
delta *= c/l;
|
||||
delta *= c / l;
|
||||
|
||||
return delta;
|
||||
}
|
||||
@ -192,10 +193,10 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala
|
||||
z = zlim;
|
||||
}
|
||||
else {
|
||||
MT_Scalar invx = 1.0/(xlim*xlim);
|
||||
MT_Scalar invz = 1.0/(zlim*zlim);
|
||||
MT_Scalar invx = 1.0 / (xlim * xlim);
|
||||
MT_Scalar invz = 1.0 / (zlim * zlim);
|
||||
|
||||
if ((x*x*invx + z*z*invz) <= 1.0)
|
||||
if ((x * x * invx + z * z * invz) <= 1.0)
|
||||
return false;
|
||||
|
||||
if (MT_fuzzyZero(x)) {
|
||||
@ -203,17 +204,17 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala
|
||||
z = zlim;
|
||||
}
|
||||
else {
|
||||
MT_Scalar rico = z/x;
|
||||
MT_Scalar rico = z / x;
|
||||
MT_Scalar old_x = x;
|
||||
x = sqrt(1.0/(invx + invz*rico*rico));
|
||||
x = sqrt(1.0 / (invx + invz * rico * rico));
|
||||
if (old_x < 0.0)
|
||||
x = -x;
|
||||
z = rico*x;
|
||||
z = rico * x;
|
||||
}
|
||||
}
|
||||
|
||||
ax = (ax < 0.0)? -x: x;
|
||||
az = (az < 0.0)? -z: z;
|
||||
ax = (ax < 0.0) ? -x : x;
|
||||
az = (az < 0.0) ? -z : z;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -221,8 +222,8 @@ static bool EllipseClamp(MT_Scalar& ax, MT_Scalar& az, MT_Scalar *amin, MT_Scala
|
||||
// IK_QSegment
|
||||
|
||||
IK_QSegment::IK_QSegment(int num_DoF, bool translational)
|
||||
: m_parent(NULL), m_child(NULL), m_sibling(NULL), m_composite(NULL),
|
||||
m_num_DoF(num_DoF), m_translational(translational)
|
||||
: m_parent(NULL), m_child(NULL), m_sibling(NULL), m_composite(NULL),
|
||||
m_num_DoF(num_DoF), m_translational(translational)
|
||||
{
|
||||
m_locked[0] = m_locked[1] = m_locked[2] = false;
|
||||
m_weight[0] = m_weight[1] = m_weight[2] = 1.0;
|
||||
@ -251,11 +252,11 @@ void IK_QSegment::Reset()
|
||||
}
|
||||
|
||||
void IK_QSegment::SetTransform(
|
||||
const MT_Vector3& start,
|
||||
const MT_Matrix3x3& rest_basis,
|
||||
const MT_Matrix3x3& basis,
|
||||
const MT_Scalar length
|
||||
)
|
||||
const MT_Vector3& start,
|
||||
const MT_Matrix3x3& rest_basis,
|
||||
const MT_Matrix3x3& basis,
|
||||
const MT_Scalar length
|
||||
)
|
||||
{
|
||||
m_max_extension = start.length() + length;
|
||||
|
||||
@ -271,7 +272,7 @@ void IK_QSegment::SetTransform(
|
||||
|
||||
MT_Matrix3x3 IK_QSegment::BasisChange() const
|
||||
{
|
||||
return m_orig_basis.transposed()*m_basis;
|
||||
return m_orig_basis.transposed() * m_basis;
|
||||
}
|
||||
|
||||
MT_Vector3 IK_QSegment::TranslationChange() const
|
||||
@ -329,7 +330,7 @@ void IK_QSegment::RemoveChild(IK_QSegment *child)
|
||||
void IK_QSegment::UpdateTransform(const MT_Transform& global)
|
||||
{
|
||||
// compute the global transform at the end of the segment
|
||||
m_global_start = global.getOrigin() + global.getBasis()*m_start;
|
||||
m_global_start = global.getOrigin() + global.getBasis() * m_start;
|
||||
|
||||
m_global_transform.setOrigin(m_global_start);
|
||||
m_global_transform.setBasis(global.getBasis() * m_rest_basis * m_basis);
|
||||
@ -345,7 +346,7 @@ void IK_QSegment::PrependBasis(const MT_Matrix3x3& mat)
|
||||
m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
|
||||
}
|
||||
|
||||
void IK_QSegment::Scale(float scale)
|
||||
void IK_QSegment::Scale(MT_Scalar scale)
|
||||
{
|
||||
m_start *= scale;
|
||||
m_translation *= scale;
|
||||
@ -358,7 +359,7 @@ void IK_QSegment::Scale(float scale)
|
||||
// IK_QSphericalSegment
|
||||
|
||||
IK_QSphericalSegment::IK_QSphericalSegment()
|
||||
: IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false)
|
||||
: IK_QSegment(3, false), m_limit_x(false), m_limit_y(false), m_limit_z(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -386,8 +387,8 @@ void IK_QSphericalSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax)
|
||||
lmin = MT_clamp(lmin, -MT_PI, MT_PI);
|
||||
lmax = MT_clamp(lmax, -MT_PI, MT_PI);
|
||||
|
||||
lmin = sin(lmin*0.5);
|
||||
lmax = sin(lmax*0.5);
|
||||
lmin = sin(lmin * 0.5);
|
||||
lmax = sin(lmax * 0.5);
|
||||
|
||||
if (axis == 0) {
|
||||
m_min[0] = -lmax;
|
||||
@ -414,8 +415,8 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3&
|
||||
|
||||
MT_Vector3 dq;
|
||||
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
||||
dq.y() = jacobian.AngleUpdate(m_DoF_id+1);
|
||||
dq.z() = jacobian.AngleUpdate(m_DoF_id+2);
|
||||
dq.y() = jacobian.AngleUpdate(m_DoF_id + 1);
|
||||
dq.z() = jacobian.AngleUpdate(m_DoF_id + 2);
|
||||
|
||||
// Directly update the rotation matrix, with Rodrigues' rotation formula,
|
||||
// to avoid singularities and allow smooth integration.
|
||||
@ -423,29 +424,29 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3&
|
||||
MT_Scalar theta = dq.length();
|
||||
|
||||
if (!MT_fuzzyZero(theta)) {
|
||||
MT_Vector3 w = dq*(1.0/theta);
|
||||
MT_Vector3 w = dq * (1.0 / theta);
|
||||
|
||||
MT_Scalar sine = sin(theta);
|
||||
MT_Scalar cosine = cos(theta);
|
||||
MT_Scalar cosineInv = 1-cosine;
|
||||
MT_Scalar cosineInv = 1 - cosine;
|
||||
|
||||
MT_Scalar xsine = w.x()*sine;
|
||||
MT_Scalar ysine = w.y()*sine;
|
||||
MT_Scalar zsine = w.z()*sine;
|
||||
MT_Scalar xsine = w.x() * sine;
|
||||
MT_Scalar ysine = w.y() * sine;
|
||||
MT_Scalar zsine = w.z() * sine;
|
||||
|
||||
MT_Scalar xxcosine = w.x()*w.x()*cosineInv;
|
||||
MT_Scalar xycosine = w.x()*w.y()*cosineInv;
|
||||
MT_Scalar xzcosine = w.x()*w.z()*cosineInv;
|
||||
MT_Scalar yycosine = w.y()*w.y()*cosineInv;
|
||||
MT_Scalar yzcosine = w.y()*w.z()*cosineInv;
|
||||
MT_Scalar zzcosine = w.z()*w.z()*cosineInv;
|
||||
MT_Scalar xxcosine = w.x() * w.x() * cosineInv;
|
||||
MT_Scalar xycosine = w.x() * w.y() * cosineInv;
|
||||
MT_Scalar xzcosine = w.x() * w.z() * cosineInv;
|
||||
MT_Scalar yycosine = w.y() * w.y() * cosineInv;
|
||||
MT_Scalar yzcosine = w.y() * w.z() * cosineInv;
|
||||
MT_Scalar zzcosine = w.z() * w.z() * cosineInv;
|
||||
|
||||
MT_Matrix3x3 M(
|
||||
cosine + xxcosine, -zsine + xycosine, ysine + xzcosine,
|
||||
zsine + xycosine, cosine + yycosine, -xsine + yzcosine,
|
||||
-ysine + xzcosine, xsine + yzcosine, cosine + zzcosine);
|
||||
cosine + xxcosine, -zsine + xycosine, ysine + xzcosine,
|
||||
zsine + xycosine, cosine + yycosine, -xsine + yzcosine,
|
||||
-ysine + xzcosine, xsine + yzcosine, cosine + zzcosine);
|
||||
|
||||
m_new_basis = m_basis*M;
|
||||
m_new_basis = m_basis * M;
|
||||
}
|
||||
else
|
||||
m_new_basis = m_basis;
|
||||
@ -505,13 +506,13 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3&
|
||||
|
||||
if (clamp[0] == false && clamp[1] == false && clamp[2] == false) {
|
||||
if (m_locked[0] || m_locked[1] || m_locked[2])
|
||||
m_new_basis = ComputeSwingMatrix(ax, az)*ComputeTwistMatrix(ay);
|
||||
m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_new_basis = ComputeSwingMatrix(ax, az)*ComputeTwistMatrix(ay);
|
||||
m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
|
||||
|
||||
delta = MatrixToAxisAngle(m_basis.transposed()*m_new_basis);
|
||||
delta = MatrixToAxisAngle(m_basis.transposed() * m_new_basis);
|
||||
|
||||
if (!(m_locked[0] || m_locked[2]) && (clamp[0] || clamp[2])) {
|
||||
m_locked_ax = ax;
|
||||
@ -528,12 +529,12 @@ void IK_QSphericalSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& del
|
||||
{
|
||||
if (dof == 1) {
|
||||
m_locked[1] = true;
|
||||
jacobian.Lock(m_DoF_id+1, delta[1]);
|
||||
jacobian.Lock(m_DoF_id + 1, delta[1]);
|
||||
}
|
||||
else {
|
||||
m_locked[0] = m_locked[2] = true;
|
||||
jacobian.Lock(m_DoF_id, delta[0]);
|
||||
jacobian.Lock(m_DoF_id+2, delta[2]);
|
||||
jacobian.Lock(m_DoF_id + 2, delta[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,14 +546,14 @@ void IK_QSphericalSegment::UpdateAngleApply()
|
||||
// IK_QNullSegment
|
||||
|
||||
IK_QNullSegment::IK_QNullSegment()
|
||||
: IK_QSegment(0, false)
|
||||
: IK_QSegment(0, false)
|
||||
{
|
||||
}
|
||||
|
||||
// IK_QRevoluteSegment
|
||||
|
||||
IK_QRevoluteSegment::IK_QRevoluteSegment(int axis)
|
||||
: IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false)
|
||||
: IK_QSegment(1, false), m_axis(axis), m_angle(0.0), m_limit(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -634,7 +635,7 @@ void IK_QRevoluteSegment::SetWeight(int axis, MT_Scalar weight)
|
||||
// IK_QSwingSegment
|
||||
|
||||
IK_QSwingSegment::IK_QSwingSegment()
|
||||
: IK_QSegment(2, false), m_limit_x(false), m_limit_z(false)
|
||||
: IK_QSegment(2, false), m_limit_x(false), m_limit_z(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -646,7 +647,7 @@ void IK_QSwingSegment::SetBasis(const MT_Matrix3x3& basis)
|
||||
|
||||
MT_Vector3 IK_QSwingSegment::Axis(int dof) const
|
||||
{
|
||||
return m_global_transform.getBasis().getColumn((dof==0)? 0: 2);
|
||||
return m_global_transform.getBasis().getColumn((dof == 0) ? 0 : 2);
|
||||
}
|
||||
|
||||
bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp)
|
||||
@ -657,7 +658,7 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del
|
||||
MT_Vector3 dq;
|
||||
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
||||
dq.y() = 0.0;
|
||||
dq.z() = jacobian.AngleUpdate(m_DoF_id+1);
|
||||
dq.z() = jacobian.AngleUpdate(m_DoF_id + 1);
|
||||
|
||||
// Directly update the rotation matrix, with Rodrigues' rotation formula,
|
||||
// to avoid singularities and allow smooth integration.
|
||||
@ -665,25 +666,25 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del
|
||||
MT_Scalar theta = dq.length();
|
||||
|
||||
if (!MT_fuzzyZero(theta)) {
|
||||
MT_Vector3 w = dq*(1.0/theta);
|
||||
MT_Vector3 w = dq * (1.0 / theta);
|
||||
|
||||
MT_Scalar sine = sin(theta);
|
||||
MT_Scalar cosine = cos(theta);
|
||||
MT_Scalar cosineInv = 1-cosine;
|
||||
MT_Scalar cosineInv = 1 - cosine;
|
||||
|
||||
MT_Scalar xsine = w.x()*sine;
|
||||
MT_Scalar zsine = w.z()*sine;
|
||||
MT_Scalar xsine = w.x() * sine;
|
||||
MT_Scalar zsine = w.z() * sine;
|
||||
|
||||
MT_Scalar xxcosine = w.x()*w.x()*cosineInv;
|
||||
MT_Scalar xzcosine = w.x()*w.z()*cosineInv;
|
||||
MT_Scalar zzcosine = w.z()*w.z()*cosineInv;
|
||||
MT_Scalar xxcosine = w.x() * w.x() * cosineInv;
|
||||
MT_Scalar xzcosine = w.x() * w.z() * cosineInv;
|
||||
MT_Scalar zzcosine = w.z() * w.z() * cosineInv;
|
||||
|
||||
MT_Matrix3x3 M(
|
||||
cosine + xxcosine, -zsine, xzcosine,
|
||||
zsine, cosine, -xsine,
|
||||
xzcosine, xsine, cosine + zzcosine);
|
||||
cosine + xxcosine, -zsine, xzcosine,
|
||||
zsine, cosine, -xsine,
|
||||
xzcosine, xsine, cosine + zzcosine);
|
||||
|
||||
m_new_basis = m_basis*M;
|
||||
m_new_basis = m_basis * M;
|
||||
|
||||
RemoveTwist(m_new_basis);
|
||||
}
|
||||
@ -731,7 +732,7 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del
|
||||
|
||||
m_new_basis = ComputeSwingMatrix(ax, az);
|
||||
|
||||
delta = MatrixToAxisAngle(m_basis.transposed()*m_new_basis);
|
||||
delta = MatrixToAxisAngle(m_basis.transposed() * m_new_basis);
|
||||
delta[1] = delta[2]; delta[2] = 0.0;
|
||||
|
||||
return true;
|
||||
@ -741,7 +742,7 @@ void IK_QSwingSegment::Lock(int, IK_QJacobian& jacobian, MT_Vector3& delta)
|
||||
{
|
||||
m_locked[0] = m_locked[1] = true;
|
||||
jacobian.Lock(m_DoF_id, delta[0]);
|
||||
jacobian.Lock(m_DoF_id+1, delta[1]);
|
||||
jacobian.Lock(m_DoF_id + 1, delta[1]);
|
||||
}
|
||||
|
||||
void IK_QSwingSegment::UpdateAngleApply()
|
||||
@ -758,11 +759,11 @@ void IK_QSwingSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax)
|
||||
lmin = MT_clamp(lmin, -MT_PI, MT_PI);
|
||||
lmax = MT_clamp(lmax, -MT_PI, MT_PI);
|
||||
|
||||
lmin = sin(lmin*0.5);
|
||||
lmax = sin(lmax*0.5);
|
||||
lmin = sin(lmin * 0.5);
|
||||
lmax = sin(lmax * 0.5);
|
||||
|
||||
// put center of ellispe in the middle between min and max
|
||||
MT_Scalar offset = 0.5*(lmin + lmax);
|
||||
MT_Scalar offset = 0.5 * (lmin + lmax);
|
||||
//lmax = lmax - offset;
|
||||
|
||||
if (axis == 0) {
|
||||
@ -794,8 +795,8 @@ void IK_QSwingSegment::SetWeight(int axis, MT_Scalar weight)
|
||||
// IK_QElbowSegment
|
||||
|
||||
IK_QElbowSegment::IK_QElbowSegment(int axis)
|
||||
: IK_QSegment(2, false), m_axis(axis), m_twist(0.0), m_angle(0.0),
|
||||
m_cos_twist(1.0), m_sin_twist(0.0), m_limit(false), m_limit_twist(false)
|
||||
: IK_QSegment(2, false), m_axis(axis), m_twist(0.0), m_angle(0.0),
|
||||
m_cos_twist(1.0), m_sin_twist(0.0), m_limit(false), m_limit_twist(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -807,7 +808,7 @@ void IK_QElbowSegment::SetBasis(const MT_Matrix3x3& basis)
|
||||
RemoveTwist(m_basis);
|
||||
m_angle = EulerAngleFromMatrix(basis, m_axis);
|
||||
|
||||
m_basis = RotationMatrix(m_angle, m_axis)*ComputeTwistMatrix(m_twist);
|
||||
m_basis = RotationMatrix(m_angle, m_axis) * ComputeTwistMatrix(m_twist);
|
||||
}
|
||||
|
||||
MT_Vector3 IK_QElbowSegment::Axis(int dof) const
|
||||
@ -850,7 +851,7 @@ bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& del
|
||||
}
|
||||
|
||||
if (!m_locked[1]) {
|
||||
m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id+1);
|
||||
m_new_twist = m_twist + jacobian.AngleUpdate(m_DoF_id + 1);
|
||||
|
||||
if (m_limit_twist) {
|
||||
if (m_new_twist > m_max_twist) {
|
||||
@ -877,7 +878,7 @@ void IK_QElbowSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta)
|
||||
}
|
||||
else {
|
||||
m_locked[1] = true;
|
||||
jacobian.Lock(m_DoF_id+1, delta[1]);
|
||||
jacobian.Lock(m_DoF_id + 1, delta[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -892,7 +893,7 @@ void IK_QElbowSegment::UpdateAngleApply()
|
||||
MT_Matrix3x3 A = RotationMatrix(m_angle, m_axis);
|
||||
MT_Matrix3x3 T = RotationMatrix(m_sin_twist, m_cos_twist, 1);
|
||||
|
||||
m_basis = A*T;
|
||||
m_basis = A * T;
|
||||
}
|
||||
|
||||
void IK_QElbowSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax)
|
||||
@ -927,7 +928,7 @@ void IK_QElbowSegment::SetWeight(int axis, MT_Scalar weight)
|
||||
// IK_QTranslateSegment
|
||||
|
||||
IK_QTranslateSegment::IK_QTranslateSegment(int axis1)
|
||||
: IK_QSegment(1, true)
|
||||
: IK_QSegment(1, true)
|
||||
{
|
||||
m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
|
||||
m_axis_enabled[axis1] = true;
|
||||
@ -938,7 +939,7 @@ IK_QTranslateSegment::IK_QTranslateSegment(int axis1)
|
||||
}
|
||||
|
||||
IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2)
|
||||
: IK_QSegment(2, true)
|
||||
: IK_QSegment(2, true)
|
||||
{
|
||||
m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = false;
|
||||
m_axis_enabled[axis1] = true;
|
||||
@ -951,7 +952,7 @@ IK_QTranslateSegment::IK_QTranslateSegment(int axis1, int axis2)
|
||||
}
|
||||
|
||||
IK_QTranslateSegment::IK_QTranslateSegment()
|
||||
: IK_QSegment(3, true)
|
||||
: IK_QSegment(3, true)
|
||||
{
|
||||
m_axis_enabled[0] = m_axis_enabled[1] = m_axis_enabled[2] = true;
|
||||
|
||||
@ -1013,7 +1014,7 @@ void IK_QTranslateSegment::UpdateAngleApply()
|
||||
void IK_QTranslateSegment::Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta)
|
||||
{
|
||||
m_locked[dof] = true;
|
||||
jacobian.Lock(m_DoF_id+dof, delta[dof]);
|
||||
jacobian.Lock(m_DoF_id + dof, delta[dof]);
|
||||
}
|
||||
|
||||
void IK_QTranslateSegment::SetWeight(int axis, MT_Scalar weight)
|
||||
@ -1030,12 +1031,12 @@ void IK_QTranslateSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax)
|
||||
if (lmax < lmin)
|
||||
return;
|
||||
|
||||
m_min[axis]= lmin;
|
||||
m_max[axis]= lmax;
|
||||
m_limit[axis]= true;
|
||||
m_min[axis] = lmin;
|
||||
m_max[axis] = lmax;
|
||||
m_limit[axis] = true;
|
||||
}
|
||||
|
||||
void IK_QTranslateSegment::Scale(float scale)
|
||||
void IK_QTranslateSegment::Scale(MT_Scalar scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -170,7 +170,7 @@ public:
|
||||
void Reset();
|
||||
|
||||
// scale
|
||||
virtual void Scale(float scale);
|
||||
virtual void Scale(MT_Scalar scale);
|
||||
|
||||
protected:
|
||||
|
||||
@ -338,7 +338,7 @@ public:
|
||||
void SetWeight(int axis, MT_Scalar weight);
|
||||
void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax);
|
||||
|
||||
void Scale(float scale);
|
||||
void Scale(MT_Scalar scale);
|
||||
|
||||
private:
|
||||
int m_axis[3];
|
||||
|
@ -36,11 +36,11 @@
|
||||
// IK_QTask
|
||||
|
||||
IK_QTask::IK_QTask(
|
||||
int size,
|
||||
bool primary,
|
||||
bool active,
|
||||
const IK_QSegment *segment
|
||||
) :
|
||||
int size,
|
||||
bool primary,
|
||||
bool active,
|
||||
const IK_QSegment *segment
|
||||
) :
|
||||
m_size(size), m_primary(primary), m_active(active), m_segment(segment),
|
||||
m_weight(1.0)
|
||||
{
|
||||
@ -49,10 +49,10 @@ IK_QTask::IK_QTask(
|
||||
// IK_QPositionTask
|
||||
|
||||
IK_QPositionTask::IK_QPositionTask(
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Vector3& goal
|
||||
) :
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Vector3& goal
|
||||
) :
|
||||
IK_QTask(3, primary, true, segment), m_goal(goal)
|
||||
{
|
||||
// computing clamping length
|
||||
@ -67,7 +67,7 @@ IK_QPositionTask::IK_QPositionTask(
|
||||
num++;
|
||||
}
|
||||
|
||||
m_clamp_length /= 2*num;
|
||||
m_clamp_length /= 2 * num;
|
||||
}
|
||||
|
||||
void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
@ -79,9 +79,9 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
MT_Scalar length = d_pos.length();
|
||||
|
||||
if (length > m_clamp_length)
|
||||
d_pos = (m_clamp_length/length)*d_pos;
|
||||
d_pos = (m_clamp_length / length) * d_pos;
|
||||
|
||||
jacobian.SetBetas(m_id, m_size, m_weight*d_pos);
|
||||
jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
|
||||
|
||||
// compute derivatives
|
||||
int i;
|
||||
@ -91,13 +91,13 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
MT_Vector3 p = seg->GlobalStart() - pos;
|
||||
|
||||
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
||||
MT_Vector3 axis = seg->Axis(i)*m_weight;
|
||||
MT_Vector3 axis = seg->Axis(i) * m_weight;
|
||||
|
||||
if (seg->Translational())
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId()+i, axis, 1e2);
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2);
|
||||
else {
|
||||
MT_Vector3 pa = p.cross(axis);
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId()+i, pa, 1e0);
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,10 +113,10 @@ MT_Scalar IK_QPositionTask::Distance() const
|
||||
// IK_QOrientationTask
|
||||
|
||||
IK_QOrientationTask::IK_QOrientationTask(
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Matrix3x3& goal
|
||||
) :
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Matrix3x3& goal
|
||||
) :
|
||||
IK_QTask(3, primary, true, segment), m_goal(goal), m_distance(0.0)
|
||||
{
|
||||
}
|
||||
@ -126,17 +126,17 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
// compute betas
|
||||
const MT_Matrix3x3& rot = m_segment->GlobalTransform().getBasis();
|
||||
|
||||
MT_Matrix3x3 d_rotm = m_goal*rot.transposed();
|
||||
MT_Matrix3x3 d_rotm = m_goal * rot.transposed();
|
||||
d_rotm.transpose();
|
||||
|
||||
MT_Vector3 d_rot;
|
||||
d_rot = -0.5*MT_Vector3(d_rotm[2][1] - d_rotm[1][2],
|
||||
d_rotm[0][2] - d_rotm[2][0],
|
||||
d_rotm[1][0] - d_rotm[0][1]);
|
||||
d_rot = -0.5 * MT_Vector3(d_rotm[2][1] - d_rotm[1][2],
|
||||
d_rotm[0][2] - d_rotm[2][0],
|
||||
d_rotm[1][0] - d_rotm[0][1]);
|
||||
|
||||
m_distance = d_rot.length();
|
||||
|
||||
jacobian.SetBetas(m_id, m_size, m_weight*d_rot);
|
||||
jacobian.SetBetas(m_id, m_size, m_weight * d_rot);
|
||||
|
||||
// compute derivatives
|
||||
int i;
|
||||
@ -146,10 +146,10 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
||||
|
||||
if (seg->Translational())
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId()+i, MT_Vector3(0, 0, 0), 1e2);
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, MT_Vector3(0, 0, 0), 1e2);
|
||||
else {
|
||||
MT_Vector3 axis = seg->Axis(i)*m_weight;
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId()+i, axis, 1e0);
|
||||
MT_Vector3 axis = seg->Axis(i) * m_weight;
|
||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,15 +158,15 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
// Note: implementation not finished!
|
||||
|
||||
IK_QCenterOfMassTask::IK_QCenterOfMassTask(
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Vector3& goal_center
|
||||
) :
|
||||
bool primary,
|
||||
const IK_QSegment *segment,
|
||||
const MT_Vector3& goal_center
|
||||
) :
|
||||
IK_QTask(3, primary, true, segment), m_goal_center(goal_center)
|
||||
{
|
||||
m_total_mass_inv = ComputeTotalMass(m_segment);
|
||||
if (!MT_fuzzyZero(m_total_mass_inv))
|
||||
m_total_mass_inv = 1.0/m_total_mass_inv;
|
||||
m_total_mass_inv = 1.0 / m_total_mass_inv;
|
||||
}
|
||||
|
||||
MT_Scalar IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
|
||||
@ -182,7 +182,7 @@ MT_Scalar IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
|
||||
|
||||
MT_Vector3 IK_QCenterOfMassTask::ComputeCenter(const IK_QSegment *segment)
|
||||
{
|
||||
MT_Vector3 center = /*seg->Mass()**/segment->GlobalStart();
|
||||
MT_Vector3 center = /*seg->Mass()**/ segment->GlobalStart();
|
||||
|
||||
const IK_QSegment *seg;
|
||||
for (seg = segment->Child(); seg; seg = seg->Sibling())
|
||||
@ -197,14 +197,14 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian& jacobian, MT_Vector3& c
|
||||
MT_Vector3 p = center - segment->GlobalStart();
|
||||
|
||||
for (i = 0; i < segment->NumberOfDoF(); i++) {
|
||||
MT_Vector3 axis = segment->Axis(i)*m_weight;
|
||||
axis *= /*segment->Mass()**/m_total_mass_inv;
|
||||
MT_Vector3 axis = segment->Axis(i) * m_weight;
|
||||
axis *= /*segment->Mass()**/ m_total_mass_inv;
|
||||
|
||||
if (segment->Translational())
|
||||
jacobian.SetDerivatives(m_id, segment->DoFId()+i, axis, 1e2);
|
||||
jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2);
|
||||
else {
|
||||
MT_Vector3 pa = axis.cross(p);
|
||||
jacobian.SetDerivatives(m_id, segment->DoFId()+i, pa, 1e0);
|
||||
jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian& jacobian, MT_Vector3& c
|
||||
|
||||
void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
{
|
||||
MT_Vector3 center = ComputeCenter(m_segment)*m_total_mass_inv;
|
||||
MT_Vector3 center = ComputeCenter(m_segment) * m_total_mass_inv;
|
||||
|
||||
// compute beta
|
||||
MT_Vector3 d_pos = m_goal_center - center;
|
||||
@ -224,10 +224,10 @@ void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian& jacobian)
|
||||
|
||||
#if 0
|
||||
if (m_distance > m_clamp_length)
|
||||
d_pos = (m_clamp_length/m_distance)*d_pos;
|
||||
d_pos = (m_clamp_length / m_distance) * d_pos;
|
||||
#endif
|
||||
|
||||
jacobian.SetBetas(m_id, m_size, m_weight*d_pos);
|
||||
jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
|
||||
|
||||
// compute derivatives
|
||||
JacobianSegment(jacobian, center, m_segment);
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
|
||||
virtual bool PositionTask() const { return false; }
|
||||
|
||||
virtual void Scale(float) {}
|
||||
virtual void Scale(MT_Scalar) {}
|
||||
|
||||
protected:
|
||||
int m_id;
|
||||
@ -103,7 +103,7 @@ public:
|
||||
MT_Scalar Distance() const;
|
||||
|
||||
bool PositionTask() const { return true; }
|
||||
void Scale(float scale) { m_goal *= scale; m_clamp_length *= scale; }
|
||||
void Scale(MT_Scalar scale) { m_goal *= scale; m_clamp_length *= scale; }
|
||||
|
||||
private:
|
||||
MT_Vector3 m_goal;
|
||||
@ -141,7 +141,7 @@ public:
|
||||
|
||||
MT_Scalar Distance() const;
|
||||
|
||||
void Scale(float scale) { m_goal_center *= scale; m_distance *= scale; }
|
||||
void Scale(MT_Scalar scale) { m_goal_center *= scale; m_distance *= scale; }
|
||||
|
||||
private:
|
||||
MT_Scalar ComputeTotalMass(const IK_QSegment *segment);
|
||||
|
@ -42,20 +42,21 @@ using namespace std;
|
||||
|
||||
class IK_QSolver {
|
||||
public:
|
||||
IK_QSolver() : root(NULL) {};
|
||||
IK_QSolver() : root(NULL) {
|
||||
};
|
||||
|
||||
IK_QJacobianSolver solver;
|
||||
IK_QSegment *root;
|
||||
std::list<IK_QTask*> tasks;
|
||||
std::list<IK_QTask *> tasks;
|
||||
};
|
||||
|
||||
// FIXME: locks still result in small "residual" changes to the locked axes...
|
||||
IK_QSegment *CreateSegment(int flag, bool translate)
|
||||
{
|
||||
int ndof = 0;
|
||||
ndof += (flag & IK_XDOF)? 1: 0;
|
||||
ndof += (flag & IK_YDOF)? 1: 0;
|
||||
ndof += (flag & IK_ZDOF)? 1: 0;
|
||||
ndof += (flag & IK_XDOF) ? 1 : 0;
|
||||
ndof += (flag & IK_YDOF) ? 1 : 0;
|
||||
ndof += (flag & IK_ZDOF) ? 1 : 0;
|
||||
|
||||
IK_QSegment *seg;
|
||||
|
||||
@ -78,7 +79,7 @@ IK_QSegment *CreateSegment(int flag, bool translate)
|
||||
|
||||
if (flag & IK_XDOF) {
|
||||
axis1 = 0;
|
||||
axis2 = (flag & IK_YDOF)? 1: 2;
|
||||
axis2 = (flag & IK_YDOF) ? 1 : 2;
|
||||
}
|
||||
else {
|
||||
axis1 = 1;
|
||||
@ -91,7 +92,7 @@ IK_QSegment *CreateSegment(int flag, bool translate)
|
||||
if (axis1 + axis2 == 2)
|
||||
seg = new IK_QSwingSegment();
|
||||
else
|
||||
seg = new IK_QElbowSegment((axis1 == 0)? 0: 2);
|
||||
seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -131,7 +132,7 @@ IK_Segment *IK_CreateSegment(int flag)
|
||||
|
||||
void IK_FreeSegment(IK_Segment *seg)
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
|
||||
if (qseg->Composite())
|
||||
delete qseg->Composite();
|
||||
@ -140,8 +141,8 @@ void IK_FreeSegment(IK_Segment *seg)
|
||||
|
||||
void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qparent = (IK_QSegment*)parent;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
IK_QSegment *qparent = (IK_QSegment *)parent;
|
||||
|
||||
if (qparent && qparent->Composite())
|
||||
qseg->SetParent(qparent->Composite());
|
||||
@ -151,7 +152,7 @@ void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
|
||||
|
||||
void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float basis[][3], float length)
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
|
||||
MT_Vector3 mstart(start);
|
||||
// convert from blender column major to moto row major
|
||||
@ -177,19 +178,19 @@ void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float bas
|
||||
|
||||
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
|
||||
if (axis >= IK_TRANS_X) {
|
||||
if(!qseg->Translational()) {
|
||||
if(qseg->Composite() && qseg->Composite()->Translational())
|
||||
if (!qseg->Translational()) {
|
||||
if (qseg->Composite() && qseg->Composite()->Translational())
|
||||
qseg = qseg->Composite();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if(axis == IK_TRANS_X) axis = IK_X;
|
||||
else if(axis == IK_TRANS_Y) axis = IK_Y;
|
||||
else axis = IK_Z;
|
||||
if (axis == IK_TRANS_X) axis = IK_X;
|
||||
else if (axis == IK_TRANS_Y) axis = IK_Y;
|
||||
else axis = IK_Z;
|
||||
}
|
||||
|
||||
qseg->SetLimit(axis, lmin, lmax);
|
||||
@ -197,25 +198,25 @@ void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
|
||||
|
||||
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
|
||||
{
|
||||
if (stiffness < 0.0)
|
||||
if (stiffness < 0.0f)
|
||||
return;
|
||||
|
||||
if (stiffness > 0.999)
|
||||
stiffness = 0.999;
|
||||
if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS))
|
||||
stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
|
||||
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
MT_Scalar weight = 1.0-stiffness;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
MT_Scalar weight = 1.0f - stiffness;
|
||||
|
||||
if (axis >= IK_TRANS_X) {
|
||||
if(!qseg->Translational()) {
|
||||
if(qseg->Composite() && qseg->Composite()->Translational())
|
||||
if (!qseg->Translational()) {
|
||||
if (qseg->Composite() && qseg->Composite()->Translational())
|
||||
qseg = qseg->Composite();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if(axis == IK_TRANS_X) axis = IK_X;
|
||||
else if(axis == IK_TRANS_Y) axis = IK_Y;
|
||||
if (axis == IK_TRANS_X) axis = IK_X;
|
||||
else if (axis == IK_TRANS_Y) axis = IK_Y;
|
||||
else axis = IK_Z;
|
||||
}
|
||||
|
||||
@ -224,7 +225,7 @@ void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
|
||||
|
||||
void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
|
||||
if (qseg->Translational() && qseg->Composite())
|
||||
qseg = qseg->Composite();
|
||||
@ -245,7 +246,7 @@ void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
|
||||
|
||||
void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
|
||||
{
|
||||
IK_QSegment *qseg = (IK_QSegment*)seg;
|
||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||
|
||||
if (!qseg->Translational() && qseg->Composite())
|
||||
qseg = qseg->Composite();
|
||||
@ -263,9 +264,9 @@ IK_Solver *IK_CreateSolver(IK_Segment *root)
|
||||
return NULL;
|
||||
|
||||
IK_QSolver *solver = new IK_QSolver();
|
||||
solver->root = (IK_QSegment*)root;
|
||||
solver->root = (IK_QSegment *)root;
|
||||
|
||||
return (IK_Solver*)solver;
|
||||
return (IK_Solver *)solver;
|
||||
}
|
||||
|
||||
void IK_FreeSolver(IK_Solver *solver)
|
||||
@ -273,9 +274,9 @@ void IK_FreeSolver(IK_Solver *solver)
|
||||
if (solver == NULL)
|
||||
return;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
std::list<IK_QTask*>& tasks = qsolver->tasks;
|
||||
std::list<IK_QTask*>::iterator task;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
std::list<IK_QTask *>& tasks = qsolver->tasks;
|
||||
std::list<IK_QTask *>::iterator task;
|
||||
|
||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
||||
delete (*task);
|
||||
@ -288,8 +289,8 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w
|
||||
if (solver == NULL || tip == NULL)
|
||||
return;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment*)tip;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||
|
||||
if (qtip->Composite())
|
||||
qtip = qtip->Composite();
|
||||
@ -306,8 +307,8 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[
|
||||
if (solver == NULL || tip == NULL)
|
||||
return;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment*)tip;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||
|
||||
if (qtip->Composite())
|
||||
qtip = qtip->Composite();
|
||||
@ -327,14 +328,14 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float
|
||||
if (solver == NULL || tip == NULL)
|
||||
return;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment*)tip;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||
|
||||
MT_Vector3 qgoal(goal);
|
||||
MT_Vector3 qpolegoal(polegoal);
|
||||
|
||||
qsolver->solver.SetPoleVectorConstraint(
|
||||
qtip, qgoal, qpolegoal, poleangle, getangle);
|
||||
qtip, qgoal, qpolegoal, poleangle, getangle);
|
||||
}
|
||||
|
||||
float IK_SolverGetPoleAngle(IK_Solver *solver)
|
||||
@ -342,7 +343,7 @@ float IK_SolverGetPoleAngle(IK_Solver *solver)
|
||||
if (solver == NULL)
|
||||
return 0.0f;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
|
||||
return qsolver->solver.GetPoleAngle();
|
||||
}
|
||||
@ -352,8 +353,8 @@ void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3]
|
||||
if (solver == NULL || root == NULL)
|
||||
return;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSegment *qroot = (IK_QSegment*)root;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
IK_QSegment *qroot = (IK_QSegment *)root;
|
||||
|
||||
// convert from blender column major to moto row major
|
||||
MT_Vector3 center(goal);
|
||||
@ -368,18 +369,18 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
|
||||
if (solver == NULL)
|
||||
return 0;
|
||||
|
||||
IK_QSolver *qsolver = (IK_QSolver*)solver;
|
||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||
|
||||
IK_QSegment *root = qsolver->root;
|
||||
IK_QJacobianSolver& jacobian = qsolver->solver;
|
||||
std::list<IK_QTask*>& tasks = qsolver->tasks;
|
||||
std::list<IK_QTask *>& tasks = qsolver->tasks;
|
||||
MT_Scalar tol = tolerance;
|
||||
|
||||
if(!jacobian.Setup(root, tasks))
|
||||
if (!jacobian.Setup(root, tasks))
|
||||
return 0;
|
||||
|
||||
bool result = jacobian.Solve(root, tasks, tol, max_iterations);
|
||||
|
||||
return ((result)? 1: 0);
|
||||
return ((result) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -37,11 +37,11 @@
|
||||
* Set the exponential map from a quaternion. The quaternion must be non-zero.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
setRotation(
|
||||
const MT_Quaternion &q
|
||||
) {
|
||||
const MT_Quaternion &q)
|
||||
{
|
||||
// ok first normalize the quaternion
|
||||
// then compute theta the axis-angle and the normalized axis v
|
||||
// scale v by theta and that's it hopefully!
|
||||
@ -53,7 +53,7 @@ setRotation(
|
||||
m_sinp = m_v.length();
|
||||
m_v /= m_sinp;
|
||||
|
||||
m_theta = atan2(double(m_sinp),double(cosp));
|
||||
m_theta = atan2(double(m_sinp), double(cosp));
|
||||
m_v *= m_theta;
|
||||
}
|
||||
|
||||
@ -62,10 +62,10 @@ setRotation(
|
||||
* representation
|
||||
*/
|
||||
|
||||
const MT_Quaternion&
|
||||
const MT_Quaternion&
|
||||
MT_ExpMap::
|
||||
getRotation(
|
||||
) const {
|
||||
getRotation() const
|
||||
{
|
||||
return m_q;
|
||||
}
|
||||
|
||||
@ -73,10 +73,10 @@ getRotation(
|
||||
* Convert the exponential map to a 3x3 matrix
|
||||
*/
|
||||
|
||||
MT_Matrix3x3
|
||||
MT_Matrix3x3
|
||||
MT_ExpMap::
|
||||
getMatrix(
|
||||
) const {
|
||||
getMatrix() const
|
||||
{
|
||||
return MT_Matrix3x3(m_q);
|
||||
}
|
||||
|
||||
@ -84,11 +84,11 @@ getMatrix(
|
||||
* Update & reparameterizate the exponential map
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
update(
|
||||
const MT_Vector3& dv
|
||||
){
|
||||
const MT_Vector3& dv)
|
||||
{
|
||||
m_v += dv;
|
||||
|
||||
angleUpdated();
|
||||
@ -100,14 +100,13 @@ update(
|
||||
* from the map) and return them as a 3x3 matrix
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
partialDerivatives(
|
||||
MT_Matrix3x3& dRdx,
|
||||
MT_Matrix3x3& dRdy,
|
||||
MT_Matrix3x3& dRdz
|
||||
) const {
|
||||
|
||||
MT_Matrix3x3& dRdx,
|
||||
MT_Matrix3x3& dRdy,
|
||||
MT_Matrix3x3& dRdz) const
|
||||
{
|
||||
MT_Quaternion dQdx[3];
|
||||
|
||||
compute_dQdVi(dQdx);
|
||||
@ -117,29 +116,28 @@ partialDerivatives(
|
||||
compute_dRdVi(dQdx[2], dRdz);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
compute_dRdVi(
|
||||
const MT_Quaternion &dQdvi,
|
||||
MT_Matrix3x3 & dRdvi
|
||||
) const {
|
||||
|
||||
MT_Scalar prod[9];
|
||||
const MT_Quaternion &dQdvi,
|
||||
MT_Matrix3x3 & dRdvi) const
|
||||
{
|
||||
MT_Scalar prod[9];
|
||||
|
||||
/* This efficient formulation is arrived at by writing out the
|
||||
* entire chain rule product dRdq * dqdv in terms of 'q' and
|
||||
* noticing that all the entries are formed from sums of just
|
||||
* nine products of 'q' and 'dqdv' */
|
||||
|
||||
prod[0] = -MT_Scalar(4)*m_q.x()*dQdvi.x();
|
||||
prod[1] = -MT_Scalar(4)*m_q.y()*dQdvi.y();
|
||||
prod[2] = -MT_Scalar(4)*m_q.z()*dQdvi.z();
|
||||
prod[3] = MT_Scalar(2)*(m_q.y()*dQdvi.x() + m_q.x()*dQdvi.y());
|
||||
prod[4] = MT_Scalar(2)*(m_q.w()*dQdvi.z() + m_q.z()*dQdvi.w());
|
||||
prod[5] = MT_Scalar(2)*(m_q.z()*dQdvi.x() + m_q.x()*dQdvi.z());
|
||||
prod[6] = MT_Scalar(2)*(m_q.w()*dQdvi.y() + m_q.y()*dQdvi.w());
|
||||
prod[7] = MT_Scalar(2)*(m_q.z()*dQdvi.y() + m_q.y()*dQdvi.z());
|
||||
prod[8] = MT_Scalar(2)*(m_q.w()*dQdvi.x() + m_q.x()*dQdvi.w());
|
||||
prod[0] = -MT_Scalar(4) * m_q.x() * dQdvi.x();
|
||||
prod[1] = -MT_Scalar(4) * m_q.y() * dQdvi.y();
|
||||
prod[2] = -MT_Scalar(4) * m_q.z() * dQdvi.z();
|
||||
prod[3] = MT_Scalar(2) * (m_q.y() * dQdvi.x() + m_q.x() * dQdvi.y());
|
||||
prod[4] = MT_Scalar(2) * (m_q.w() * dQdvi.z() + m_q.z() * dQdvi.w());
|
||||
prod[5] = MT_Scalar(2) * (m_q.z() * dQdvi.x() + m_q.x() * dQdvi.z());
|
||||
prod[6] = MT_Scalar(2) * (m_q.w() * dQdvi.y() + m_q.y() * dQdvi.w());
|
||||
prod[7] = MT_Scalar(2) * (m_q.z() * dQdvi.y() + m_q.y() * dQdvi.z());
|
||||
prod[8] = MT_Scalar(2) * (m_q.w() * dQdvi.x() + m_q.x() * dQdvi.w());
|
||||
|
||||
/* first row, followed by second and third */
|
||||
dRdvi[0][0] = prod[1] + prod[2];
|
||||
@ -157,61 +155,60 @@ compute_dRdVi(
|
||||
|
||||
// compute partial derivatives dQ/dVi
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
compute_dQdVi(
|
||||
MT_Quaternion *dQdX
|
||||
) const {
|
||||
|
||||
MT_Quaternion *dQdX) const
|
||||
{
|
||||
/* This is an efficient implementation of the derivatives given
|
||||
* in Appendix A of the paper with common subexpressions factored out */
|
||||
|
||||
MT_Scalar sinc, termCoeff;
|
||||
|
||||
if (m_theta < MT_EXPMAP_MINANGLE) {
|
||||
sinc = 0.5 - m_theta*m_theta/48.0;
|
||||
termCoeff = (m_theta*m_theta/40.0 - 1.0)/24.0;
|
||||
sinc = 0.5 - m_theta * m_theta / 48.0;
|
||||
termCoeff = (m_theta * m_theta / 40.0 - 1.0) / 24.0;
|
||||
}
|
||||
else {
|
||||
MT_Scalar cosp = m_q.w();
|
||||
MT_Scalar ang = 1.0/m_theta;
|
||||
MT_Scalar ang = 1.0 / m_theta;
|
||||
|
||||
sinc = m_sinp*ang;
|
||||
termCoeff = ang*ang*(0.5*cosp - sinc);
|
||||
sinc = m_sinp * ang;
|
||||
termCoeff = ang * ang * (0.5 * cosp - sinc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
MT_Quaternion& dQdx = dQdX[i];
|
||||
int i2 = (i+1)%3;
|
||||
int i3 = (i+2)%3;
|
||||
int i2 = (i + 1) % 3;
|
||||
int i3 = (i + 2) % 3;
|
||||
|
||||
MT_Scalar term = m_v[i]*termCoeff;
|
||||
MT_Scalar term = m_v[i] * termCoeff;
|
||||
|
||||
dQdx[i] = term*m_v[i] + sinc;
|
||||
dQdx[i2] = term*m_v[i2];
|
||||
dQdx[i3] = term*m_v[i3];
|
||||
dQdx.w() = -0.5*m_v[i]*sinc;
|
||||
dQdx[i] = term * m_v[i] + sinc;
|
||||
dQdx[i2] = term * m_v[i2];
|
||||
dQdx[i3] = term * m_v[i3];
|
||||
dQdx.w() = -0.5 * m_v[i] * sinc;
|
||||
}
|
||||
}
|
||||
|
||||
// reParametize away from singularity, updating
|
||||
// m_v and m_theta
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
reParametrize(
|
||||
){
|
||||
reParametrize()
|
||||
{
|
||||
if (m_theta > MT_PI) {
|
||||
MT_Scalar scl = m_theta;
|
||||
if (m_theta > MT_2_PI){ /* first get theta into range 0..2PI */
|
||||
if (m_theta > MT_2_PI) { /* first get theta into range 0..2PI */
|
||||
m_theta = MT_Scalar(fmod(m_theta, MT_2_PI));
|
||||
scl = m_theta/scl;
|
||||
scl = m_theta / scl;
|
||||
m_v *= scl;
|
||||
}
|
||||
if (m_theta > MT_PI){
|
||||
if (m_theta > MT_PI) {
|
||||
scl = m_theta;
|
||||
m_theta = MT_2_PI - m_theta;
|
||||
scl = MT_Scalar(1.0) - MT_2_PI/scl;
|
||||
scl = MT_Scalar(1.0) - MT_2_PI / scl;
|
||||
m_v *= scl;
|
||||
}
|
||||
}
|
||||
@ -219,10 +216,10 @@ reParametrize(
|
||||
|
||||
// compute cached variables
|
||||
|
||||
void
|
||||
void
|
||||
MT_ExpMap::
|
||||
angleUpdated(
|
||||
){
|
||||
angleUpdated()
|
||||
{
|
||||
m_theta = m_v.length();
|
||||
|
||||
reParametrize();
|
||||
@ -233,20 +230,21 @@ angleUpdated(
|
||||
m_sinp = MT_Scalar(0.0);
|
||||
|
||||
/* Taylor Series for sinc */
|
||||
MT_Vector3 temp = m_v * MT_Scalar(MT_Scalar(.5) - m_theta*m_theta/MT_Scalar(48.0));
|
||||
MT_Vector3 temp = m_v * MT_Scalar(MT_Scalar(.5) - m_theta * m_theta / MT_Scalar(48.0));
|
||||
m_q.x() = temp.x();
|
||||
m_q.y() = temp.y();
|
||||
m_q.z() = temp.z();
|
||||
m_q.w() = MT_Scalar(1.0);
|
||||
} else {
|
||||
m_sinp = MT_Scalar(sin(.5*m_theta));
|
||||
}
|
||||
else {
|
||||
m_sinp = MT_Scalar(sin(.5 * m_theta));
|
||||
|
||||
/* Taylor Series for sinc */
|
||||
MT_Vector3 temp = m_v * (m_sinp/m_theta);
|
||||
MT_Vector3 temp = m_v * (m_sinp / m_theta);
|
||||
m_q.x() = temp.x();
|
||||
m_q.y() = temp.y();
|
||||
m_q.z() = temp.z();
|
||||
m_q.w() = MT_Scalar(cos(.5*m_theta));
|
||||
m_q.w() = MT_Scalar(cos(0.5 * m_theta));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,7 @@ int Armature::addConstraint(const std::string& segment_name, ConstraintCallback
|
||||
return iConstraint;
|
||||
}
|
||||
}
|
||||
if (m_finalized) {
|
||||
if (m_finalized) {
|
||||
if (_freeParam && _param)
|
||||
free(_param);
|
||||
return -1;
|
||||
|
@ -106,7 +106,7 @@ int _EatSpace( std::istream& is,int* countp=NULL) {
|
||||
|
||||
|
||||
// Eats whites, returns, tabs and the delim character
|
||||
// Checks wether delim char. is encountered.
|
||||
// Checks whether delim char. is encountered.
|
||||
void Eat( std::istream& is, int delim )
|
||||
{
|
||||
int ch;
|
||||
@ -119,7 +119,7 @@ void Eat( std::istream& is, int delim )
|
||||
}
|
||||
|
||||
// Eats whites, returns, tabs and the delim character
|
||||
// Checks wether delim char. is encountered.
|
||||
// Checks whether delim char. is encountered.
|
||||
// EatEnd does not eat all space-like char's at the end.
|
||||
void EatEnd( std::istream& is, int delim )
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ protected :
|
||||
|
||||
/**
|
||||
* Protected constructors
|
||||
* This class is not for direct instanciation. Sub classes
|
||||
* This class is not for direct instantiation. Sub classes
|
||||
* should only be allocated on the heap.
|
||||
*/
|
||||
|
||||
|
@ -37,6 +37,15 @@
|
||||
#endif
|
||||
|
||||
|
||||
// this is needed for inlining behavior
|
||||
#if defined _WIN32
|
||||
# define DO_INLINE __inline
|
||||
#elif defined (__sun) || defined (__sun__)
|
||||
# define DO_INLINE
|
||||
#else
|
||||
# define DO_INLINE static inline
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered.
|
||||
@ -814,14 +823,14 @@ int get_range_expanded_pixel_coord(float normalized_value, int max_value) {
|
||||
return (int)((normalized_value * (float)(max_value)) + 0.5f);
|
||||
}
|
||||
|
||||
__inline float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) {
|
||||
DO_INLINE float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) {
|
||||
if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
|
||||
return 0.0f;
|
||||
}
|
||||
return buf[(pos_y * buf_x) + pos_x];
|
||||
}
|
||||
|
||||
__inline float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) {
|
||||
DO_INLINE float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) {
|
||||
int a;
|
||||
int b;
|
||||
int a_plus_1;
|
||||
@ -847,7 +856,7 @@ __inline float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, fl
|
||||
|
||||
}
|
||||
|
||||
__inline void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) {
|
||||
DO_INLINE void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) {
|
||||
if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
|
||||
return;
|
||||
}
|
||||
|
@ -270,7 +270,6 @@ def dump_messages_rna(messages, check_ctxt):
|
||||
walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
|
||||
|
||||
|
||||
|
||||
def dump_messages_pytext(messages, check_ctxt):
|
||||
""" dumps text inlined in the python user interface: eg.
|
||||
|
||||
@ -291,7 +290,7 @@ def dump_messages_pytext(messages, check_ctxt):
|
||||
|
||||
# Break recursive nodes look up on some kind of nodes.
|
||||
# E.g. we don’t want to get strings inside subscripts (blah["foo"])!
|
||||
stopper_nodes = {ast.Subscript,}
|
||||
stopper_nodes = {ast.Subscript, }
|
||||
|
||||
for func_id, func in bpy.types.UILayout.bl_rna.functions.items():
|
||||
# check it has a 'text' argument
|
||||
|
@ -94,7 +94,6 @@ def main():
|
||||
help="Restrict processed languages to those.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
if args.pot:
|
||||
global FILE_NAME_POT
|
||||
FILE_NAME_POT = args.pot
|
||||
@ -145,24 +144,24 @@ def main():
|
||||
ret = t
|
||||
|
||||
if args.stats and glob_stats["nbr"] != 0.0:
|
||||
nbr_contexts = len(glob_stats["contexts"]-{""})
|
||||
nbr_contexts = len(glob_stats["contexts"] - {""})
|
||||
if nbr_contexts != 1:
|
||||
if nbr_contexts == 0:
|
||||
nbr_contexts = "No"
|
||||
_ctx_txt = "s are"
|
||||
else:
|
||||
_ctx_txt = " is"
|
||||
print("\nAverage stats for all {:.0f} processed files:\n" \
|
||||
" {:>6.1%} done!\n" \
|
||||
" {:>6.1%} of messages are tooltips.\n" \
|
||||
" {:>6.1%} of tooltips are translated.\n" \
|
||||
" {:>6.1%} of translated messages are tooltips.\n" \
|
||||
" {:>6.1%} of messages are commented.\n" \
|
||||
" The org msgids are currently made of {} signs.\n" \
|
||||
" All processed translations are currently made of {} signs.\n" \
|
||||
" {} specific context{} present:\n {}\n" \
|
||||
"".format(glob_stats["nbr"], glob_stats["lvl"]/glob_stats["nbr"],
|
||||
glob_stats["lvl_ttips"]/glob_stats["nbr"],
|
||||
print("\nAverage stats for all {:.0f} processed files:\n"
|
||||
" {:>6.1%} done!\n"
|
||||
" {:>6.1%} of messages are tooltips.\n"
|
||||
" {:>6.1%} of tooltips are translated.\n"
|
||||
" {:>6.1%} of translated messages are tooltips.\n"
|
||||
" {:>6.1%} of messages are commented.\n"
|
||||
" The org msgids are currently made of {} signs.\n"
|
||||
" All processed translations are currently made of {} signs.\n"
|
||||
" {} specific context{} present:\n {}\n"
|
||||
"".format(glob_stats["nbr"], glob_stats["lvl"] / glob_stats["nbr"],
|
||||
glob_stats["lvl_ttips"] / glob_stats["nbr"],
|
||||
glob_stats["lvl_trans_ttips"]/glob_stats["nbr"],
|
||||
glob_stats["lvl_ttips_in_trans"]/glob_stats["nbr"],
|
||||
glob_stats["lvl_comm"]/glob_stats["nbr"], glob_stats["nbr_signs"],
|
||||
|
@ -65,7 +65,6 @@ def main():
|
||||
help="Restrict processed languages to those.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
ret = 0
|
||||
|
||||
if args.langs:
|
||||
|
@ -56,12 +56,11 @@ def main():
|
||||
help="Restrict processed languages to those.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
ret = 0
|
||||
|
||||
threshold = float(settings.IMPORT_MIN_LEVEL)/100.0
|
||||
threshold = float(settings.IMPORT_MIN_LEVEL) / 100.0
|
||||
if args.threshold is not None:
|
||||
threshold = float(args.threshold)/100.0
|
||||
threshold = float(args.threshold) / 100.0
|
||||
|
||||
for lang in os.listdir(BRANCHES_DIR):
|
||||
if args.langs and lang not in args.langs:
|
||||
@ -74,7 +73,7 @@ def main():
|
||||
trans_msgs = stats["trans_msg"]
|
||||
lvl = 0.0
|
||||
if tot_msgs:
|
||||
lvl = float(trans_msgs)/float(tot_msgs)
|
||||
lvl = float(trans_msgs) / float(tot_msgs)
|
||||
if lvl > threshold:
|
||||
if state["is_broken"] and args.strict:
|
||||
print("{:<10}: {:>6.1%} done, but BROKEN, skipped." \
|
||||
|
@ -21,7 +21,7 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
# Merge one or more .po files into the first dest one.
|
||||
# If a msgkey is present in more than one merged po, the one in the first file wins, unless
|
||||
# If a msgkey is present in more than one merged po, the one in the first file wins, unless
|
||||
# it’s marked as fuzzy and one later is not.
|
||||
# The fuzzy flag is removed if necessary.
|
||||
# All other comments are never modified.
|
||||
@ -59,7 +59,6 @@ def main():
|
||||
help="The po's to merge into the dst.po one.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
ret = 0
|
||||
done_msgkeys = set()
|
||||
done_fuzzy_msgkeys = set()
|
||||
@ -78,7 +77,7 @@ def main():
|
||||
# If we don’t want to replace existing valid translations, pre-populate
|
||||
# done_msgkeys and done_fuzzy_msgkeys.
|
||||
if not args.replace:
|
||||
done_msgkeys = dst_states["trans_msg"].copy()
|
||||
done_msgkeys = dst_states["trans_msg"].copy()
|
||||
done_fuzzy_msgkeys = dst_states["fuzzy_msg"].copy()
|
||||
for po in args.src:
|
||||
messages, states, stats = utils.parse_messages(po)
|
||||
|
@ -86,6 +86,7 @@ FRIBIDI_FLAGS_DEFAULT = FRIBIDI_FLAG_SHAPE_MIRRORING | \
|
||||
FRIBIDI_FLAGS_ARABIC = FRIBIDI_FLAG_SHAPE_ARAB_PRES | \
|
||||
FRIBIDI_FLAG_SHAPE_ARAB_LIGA
|
||||
|
||||
|
||||
##### Kernel processing funcs. #####
|
||||
def protect_format_seq(msg):
|
||||
"""
|
||||
@ -185,6 +186,7 @@ def log2vis(msgs):
|
||||
|
||||
yield fbc_str.value
|
||||
|
||||
|
||||
##### Command line stuff. #####
|
||||
def main():
|
||||
import argparse
|
||||
@ -208,7 +210,6 @@ def main():
|
||||
help="The po's to pre-process messages.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
msgs, state, u1 = utils.parse_messages(args.src)
|
||||
if state["is_broken"]:
|
||||
print("Source po is BROKEN, aborting.")
|
||||
|
@ -55,7 +55,7 @@ DOMAIN = "blender"
|
||||
|
||||
# Our own "gettext" stuff.
|
||||
# File type (ext) to parse.
|
||||
PYGETTEXT_ALLOWED_EXTS = {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
|
||||
PYGETTEXT_ALLOWED_EXTS = {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
|
||||
|
||||
# Where to search contexts definitions, relative to SOURCE_DIR (defined below).
|
||||
PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont",
|
||||
@ -97,7 +97,7 @@ _msg_re = r"(?P<msg_raw>" + _str_whole_re.format(_="_msg") + r")"
|
||||
PYGETTEXT_KEYWORDS = (() +
|
||||
tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it)
|
||||
for it in ("IFACE_", "TIP_", "N_")) +
|
||||
tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*"+ _msg_re + r"\s*\)").format(it)
|
||||
tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it)
|
||||
for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_"))
|
||||
)
|
||||
|
||||
|
@ -376,7 +376,7 @@ dict_uimsgs = {
|
||||
"chebychev",
|
||||
"kutta",
|
||||
"lennard",
|
||||
"minkowsky",
|
||||
"minkowski",
|
||||
"minnaert",
|
||||
"musgrave",
|
||||
"nayar",
|
||||
@ -414,7 +414,7 @@ dict_uimsgs = {
|
||||
"gpu", "gpus",
|
||||
"hc",
|
||||
"hdr",
|
||||
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
|
||||
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
|
||||
"hsv", "hsva",
|
||||
"id",
|
||||
"itu",
|
||||
|
@ -38,6 +38,7 @@ except:
|
||||
|
||||
PY3 = settings.PYTHON3_EXEC
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="" \
|
||||
@ -59,7 +60,6 @@ def main():
|
||||
help="Restrict processed languages to those.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
ret = 0
|
||||
|
||||
# Generate a temp messages file.
|
||||
|
@ -47,7 +47,7 @@ def process_po(po, lang, mo=None):
|
||||
mo_dir = os.path.join(TRUNK_MO_DIR, lang, "LC_MESSAGES")
|
||||
# Create dirs if not existing!
|
||||
if not os.path.isdir(mo_dir):
|
||||
os.makedirs(mo_dir, exist_ok = True)
|
||||
os.makedirs(mo_dir, exist_ok=True)
|
||||
|
||||
# show stats
|
||||
cmd = (GETTEXT_MSGFMT_EXECUTABLE,
|
||||
|
@ -36,8 +36,8 @@ except:
|
||||
|
||||
|
||||
GETTEXT_MSGMERGE_EXECUTABLE = settings.GETTEXT_MSGMERGE_EXECUTABLE
|
||||
BRANCHES_DIR = settings.BRANCHES_DIR
|
||||
TRUNK_PO_DIR = settings.TRUNK_PO_DIR
|
||||
BRANCHES_DIR = settings.BRANCHES_DIR
|
||||
TRUNK_PO_DIR = settings.TRUNK_PO_DIR
|
||||
FILE_NAME_POT = settings.FILE_NAME_POT
|
||||
|
||||
|
||||
|
@ -74,12 +74,13 @@ pygettexts = tuple(re.compile(r).search
|
||||
_clean_str = re.compile(settings.str_clean_re).finditer
|
||||
clean_str = lambda s: "".join(m.group("clean") for m in _clean_str(s))
|
||||
|
||||
|
||||
def check_file(path, rel_path, messages):
|
||||
with open(path, encoding="utf-8") as f:
|
||||
f = f.read()
|
||||
for srch in pygettexts:
|
||||
m = srch(f)
|
||||
line = pos =0
|
||||
line = pos = 0
|
||||
while m:
|
||||
d = m.groupdict()
|
||||
# Context.
|
||||
@ -149,6 +150,8 @@ from spell_check_utils import (dict_uimsgs,
|
||||
)
|
||||
|
||||
_spell_checked = set()
|
||||
|
||||
|
||||
def spell_check(txt, cache):
|
||||
ret = []
|
||||
|
||||
@ -194,6 +197,8 @@ def gen_empty_pot():
|
||||
|
||||
escape_re = tuple(re.compile(r[0]) for r in settings.ESCAPE_RE)
|
||||
escape = lambda s, n: escape_re[n].sub(settings.ESCAPE_RE[n][1], s)
|
||||
|
||||
|
||||
def merge_messages(msgs, states, messages, do_checks, spell_cache):
|
||||
num_added = num_present = 0
|
||||
for (context, msgid), srcs in messages.items():
|
||||
|
@ -65,7 +65,6 @@ def main():
|
||||
help="Restrict processed languages to those.")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
ret = 0
|
||||
failed = set()
|
||||
|
||||
|
@ -40,6 +40,7 @@ def stripeol(s):
|
||||
def is_tooltip(msgid):
|
||||
return len(msgid) > 30
|
||||
|
||||
|
||||
def parse_messages(fname):
|
||||
"""
|
||||
Returns a tupple (messages, states, stats).
|
||||
@ -82,7 +83,6 @@ def parse_messages(fname):
|
||||
fuzzy_messages = set()
|
||||
commented_messages = set()
|
||||
|
||||
|
||||
def clean_vars():
|
||||
nonlocal reading_msgid, reading_msgstr, reading_msgctxt, \
|
||||
reading_comment, is_fuzzy, is_translated, is_commented, \
|
||||
@ -143,7 +143,6 @@ def parse_messages(fname):
|
||||
|
||||
clean_vars()
|
||||
|
||||
|
||||
with open(fname, 'r', encoding="utf-8") as f:
|
||||
for line_nr, line in enumerate(f):
|
||||
line = stripeol(line)
|
||||
@ -156,7 +155,7 @@ def parse_messages(fname):
|
||||
reading_ctxt = True
|
||||
if line.startswith(COMMENT_PREFIX):
|
||||
is_commented = True
|
||||
line = line[9+len(COMMENT_PREFIX):-1]
|
||||
line = line[9 + len(COMMENT_PREFIX):-1]
|
||||
else:
|
||||
line = line[9:-1]
|
||||
msgctxt_lines.append(line)
|
||||
@ -167,7 +166,7 @@ def parse_messages(fname):
|
||||
reading_msgid = True
|
||||
if line.startswith(COMMENT_PREFIX):
|
||||
is_commented = True
|
||||
line = line[7+len(COMMENT_PREFIX):-1]
|
||||
line = line[7 + len(COMMENT_PREFIX):-1]
|
||||
else:
|
||||
line = line[7:-1]
|
||||
msgid_lines.append(line)
|
||||
@ -180,7 +179,7 @@ def parse_messages(fname):
|
||||
reading_msgid = False
|
||||
reading_msgstr = True
|
||||
if line.startswith(COMMENT_PREFIX):
|
||||
line = line[8+len(COMMENT_PREFIX):-1]
|
||||
line = line[8 + len(COMMENT_PREFIX):-1]
|
||||
if not is_commented:
|
||||
is_broken = True
|
||||
else:
|
||||
@ -194,13 +193,13 @@ def parse_messages(fname):
|
||||
elif line.startswith("#"):
|
||||
if reading_msgid:
|
||||
if is_commented:
|
||||
msgid_lines.append(line[1+len(COMMENT_PREFIX):-1])
|
||||
msgid_lines.append(line[1 + len(COMMENT_PREFIX):-1])
|
||||
else:
|
||||
msgid_lines.append(line)
|
||||
is_broken = True
|
||||
elif reading_msgstr:
|
||||
if is_commented:
|
||||
msgstr_lines.append(line[1+len(COMMENT_PREFIX):-1])
|
||||
msgstr_lines.append(line[1 + len(COMMENT_PREFIX):-1])
|
||||
else:
|
||||
msgstr_lines.append(line)
|
||||
is_broken = True
|
||||
@ -338,13 +337,13 @@ def print_stats(stats, glob_stats=None, prefix=""):
|
||||
lvl = lvl_ttips = lvl_trans_ttips = lvl_ttips_in_trans = lvl_comm = 0.0
|
||||
|
||||
if tot_msgs > 0:
|
||||
lvl = float(trans_msgs)/float(tot_msgs)
|
||||
lvl_ttips = float(tot_ttips)/float(tot_msgs)
|
||||
lvl_comm = float(comm_msgs)/float(tot_msgs+comm_msgs)
|
||||
lvl = float(trans_msgs) / float(tot_msgs)
|
||||
lvl_ttips = float(tot_ttips) / float(tot_msgs)
|
||||
lvl_comm = float(comm_msgs) / float(tot_msgs+comm_msgs)
|
||||
if tot_ttips > 0:
|
||||
lvl_trans_ttips = float(trans_ttips)/float(tot_ttips)
|
||||
lvl_trans_ttips = float(trans_ttips) / float(tot_ttips)
|
||||
if trans_msgs > 0:
|
||||
lvl_ttips_in_trans = float(trans_ttips)/float(trans_msgs)
|
||||
lvl_ttips_in_trans = float(trans_ttips) / float(trans_msgs)
|
||||
|
||||
if glob_stats:
|
||||
glob_stats["nbr"] += 1.0
|
||||
@ -368,9 +367,8 @@ def print_stats(stats, glob_stats=None, prefix=""):
|
||||
"{:>6.1%} of translated messages are tooltips ({} over {}).\n"
|
||||
"".format(lvl_ttips_in_trans, trans_ttips, trans_msgs),
|
||||
"{:>6.1%} of messages are commented ({} over {}).\n"
|
||||
"".format(lvl_comm, comm_msgs, comm_msgs+tot_msgs),
|
||||
"".format(lvl_comm, comm_msgs, comm_msgs + tot_msgs),
|
||||
"This translation is currently made of {} signs.\n"
|
||||
"".format(nbr_trans_signs))
|
||||
print(prefix.join(lines))
|
||||
return 0
|
||||
|
||||
|
@ -34,13 +34,14 @@ __all__ = (
|
||||
"register_class",
|
||||
"register_module",
|
||||
"resource_path",
|
||||
"script_path_user",
|
||||
"script_path_pref",
|
||||
"script_paths",
|
||||
"smpte_from_frame",
|
||||
"smpte_from_seconds",
|
||||
"unregister_class",
|
||||
"unregister_module",
|
||||
"user_resource",
|
||||
"user_script_path",
|
||||
)
|
||||
|
||||
from _bpy import register_class, unregister_class, blend_paths, resource_path
|
||||
@ -252,15 +253,16 @@ _scripts = _os.path.join(_os.path.dirname(__file__),
|
||||
_scripts = (_os.path.normpath(_scripts), )
|
||||
|
||||
|
||||
def user_script_path():
|
||||
# returns the env var and falls back to userprefs
|
||||
def script_path_user():
|
||||
"""returns the env var and falls back to home dir or None"""
|
||||
path = _user_resource('SCRIPTS')
|
||||
return _os.path.normpath(path) if path else None
|
||||
|
||||
if path:
|
||||
path = _os.path.normpath(path)
|
||||
return path
|
||||
else:
|
||||
return None
|
||||
|
||||
def script_path_pref():
|
||||
"""returns the user preference or None"""
|
||||
path = _bpy.context.user_preferences.filepaths.script_directory
|
||||
return _os.path.normpath(path) if path else None
|
||||
|
||||
|
||||
def script_paths(subdir=None, user_pref=True, check_all=False):
|
||||
@ -278,10 +280,6 @@ def script_paths(subdir=None, user_pref=True, check_all=False):
|
||||
:rtype: list
|
||||
"""
|
||||
scripts = list(_scripts)
|
||||
prefs = _bpy.context.user_preferences
|
||||
|
||||
# add user scripts dir
|
||||
user_script = user_script_path()
|
||||
|
||||
if check_all:
|
||||
# all possible paths
|
||||
@ -291,7 +289,7 @@ def script_paths(subdir=None, user_pref=True, check_all=False):
|
||||
# only paths blender uses
|
||||
base_paths = _bpy_script_paths()
|
||||
|
||||
for path in base_paths + (user_script, ):
|
||||
for path in base_paths + (script_path_user(), script_path_pref()):
|
||||
if path:
|
||||
path = _os.path.normpath(path)
|
||||
if path not in scripts and _os.path.isdir(path):
|
||||
|
@ -308,7 +308,8 @@ def banner(context):
|
||||
'OUTPUT')
|
||||
add_scrollback("Convenience Imports: from mathutils import *; "
|
||||
"from math import *", 'OUTPUT')
|
||||
add_scrollback("Convenience Variables: C = bpy.context, D = bpy.data", 'OUTPUT')
|
||||
add_scrollback("Convenience Variables: C = bpy.context, D = bpy.data",
|
||||
'OUTPUT')
|
||||
add_scrollback("", 'OUTPUT')
|
||||
sc.prompt = PROMPT
|
||||
|
||||
|
@ -87,7 +87,8 @@ def write_sysinfo(op):
|
||||
output.write("\nDirectories:\n")
|
||||
output.write(lilies)
|
||||
output.write("scripts: %r\n" % (bpy.utils.script_paths()))
|
||||
output.write("user scripts: %r\n" % (bpy.utils.user_script_path()))
|
||||
output.write("user scripts: %r\n" % (bpy.utils.script_path_user()))
|
||||
output.write("pref scripts: %r\n" % (bpy.utils.script_path_pref()))
|
||||
output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES')))
|
||||
output.write("config: %r\n" % (bpy.utils.user_resource('CONFIG')))
|
||||
output.write("scripts : %r\n" % (bpy.utils.user_resource('SCRIPTS')))
|
||||
|
@ -101,7 +101,6 @@ def operator_value_is_undo(value):
|
||||
return (isinstance(id_data, bpy.types.ID) and
|
||||
(not isinstance(id_data, (bpy.types.WindowManager,
|
||||
bpy.types.Screen,
|
||||
bpy.types.Scene,
|
||||
bpy.types.Brush,
|
||||
))))
|
||||
|
||||
|
@ -38,6 +38,7 @@ _modules = (
|
||||
"properties_data_modifier",
|
||||
"properties_data_speaker",
|
||||
"properties_game",
|
||||
"properties_mask_common",
|
||||
"properties_material",
|
||||
"properties_object_constraint",
|
||||
"properties_object",
|
||||
|
@ -323,6 +323,7 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from
|
||||
|
||||
def draw(self, context):
|
||||
ob = context.object
|
||||
|
||||
self.draw_settings(context, ob.pose.animation_visualization, bones=True)
|
||||
|
||||
|
||||
|
@ -148,7 +148,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
||||
col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
|
||||
col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="").all = False
|
||||
col.menu("MESH_MT_vertex_group_specials", icon='DOWNARROW_HLT', text="")
|
||||
if group:
|
||||
col.separator()
|
||||
|
@ -105,14 +105,13 @@ class DATA_PT_cone(DataButtonsPanel, Panel):
|
||||
speaker = context.speaker
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
|
||||
col = split.column()
|
||||
col.label("Angle:")
|
||||
col.prop(speaker, "cone_angle_outer", text="Outer")
|
||||
col.prop(speaker, "cone_angle_inner", text="Inner")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.label("Volume:")
|
||||
col.prop(speaker, "cone_volume_outer", text="Outer")
|
||||
|
||||
|
@ -337,7 +337,6 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
|
||||
|
||||
if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}:
|
||||
col = split.column()
|
||||
|
||||
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
col.prop(gs, "dome_angle", slider=True)
|
||||
|
||||
@ -347,14 +346,13 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
|
||||
|
||||
elif dome_type == 'PANORAM_SPH':
|
||||
col = split.column()
|
||||
|
||||
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
|
||||
col = split.column()
|
||||
col.prop(gs, "dome_tessellation", text="Tessellation")
|
||||
|
||||
else: # cube map
|
||||
col = split.column()
|
||||
|
||||
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
|
||||
col = split.column()
|
||||
@ -396,6 +394,7 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
row = layout.row()
|
||||
row.prop(gs, "use_frame_rate")
|
||||
row.prop(gs, "restrict_animation_updates")
|
||||
@ -415,10 +414,10 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
row.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False)
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False)
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.prop(gs, "show_debug_properties", text="Debug Properties")
|
||||
flow.prop(gs, "show_framerate_profile", text="Framerate and Profile")
|
||||
@ -582,14 +581,14 @@ class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
|
||||
world = context.world
|
||||
|
||||
layout.active = world.mist_settings.use_mist
|
||||
row = layout.row()
|
||||
row.prop(world.mist_settings, "falloff")
|
||||
|
||||
layout.prop(world.mist_settings, "falloff")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(world.mist_settings, "start")
|
||||
row.prop(world.mist_settings, "depth")
|
||||
row = layout.row()
|
||||
row.prop(world.mist_settings, "intensity", text="Minimum Intensity")
|
||||
|
||||
layout.prop(world.mist_settings, "intensity", text="Minimum Intensity")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
|
||||
|
317
release/scripts/startup/bl_ui/properties_mask_common.py
Normal file
317
release/scripts/startup/bl_ui/properties_mask_common.py
Normal file
@ -0,0 +1,317 @@
|
||||
# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
|
||||
# panels get subclassed (not registered directly)
|
||||
# menus are referenced `as is`
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
|
||||
|
||||
class MASK_PT_mask:
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'UI'
|
||||
bl_label = "Mask Settings"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space_data = context.space_data
|
||||
return space_data.mask and space_data.mode == 'MASK'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(mask, "frame_start")
|
||||
col.prop(mask, "frame_end")
|
||||
|
||||
|
||||
class MASK_PT_layers:
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'UI'
|
||||
bl_label = "Mask Layers"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space_data = context.space_data
|
||||
return space_data.mask and space_data.mode == 'MASK'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
active_layer = mask.layers.active
|
||||
|
||||
rows = 5 if active_layer else 2
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(mask, "layers",
|
||||
mask, "active_layer_index", rows=rows)
|
||||
|
||||
sub = row.column(align=True)
|
||||
|
||||
sub.operator("mask.layer_new", icon='ZOOMIN', text="")
|
||||
sub.operator("mask.layer_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
if active_layer:
|
||||
sub.separator()
|
||||
|
||||
props = sub.operator("mask.layer_move", icon='TRIA_UP', text="")
|
||||
props.direction = 'UP'
|
||||
|
||||
props = sub.operator("mask.layer_move", icon='TRIA_DOWN', text="")
|
||||
props.direction = 'DOWN'
|
||||
|
||||
layout.prop(active_layer, "name")
|
||||
|
||||
# blending
|
||||
row = layout.row(align=True)
|
||||
row.prop(active_layer, "alpha")
|
||||
row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
|
||||
|
||||
layout.prop(active_layer, "blend")
|
||||
layout.prop(active_layer, "falloff")
|
||||
|
||||
|
||||
class MASK_PT_spline():
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'UI'
|
||||
bl_label = "Active Spline"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
|
||||
if mask and sc.mode == 'MASK':
|
||||
return mask.layers.active and mask.layers.active.splines.active
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
spline = mask.layers.active.splines.active
|
||||
|
||||
col = layout.column()
|
||||
col.prop(spline, "weight_interpolation")
|
||||
|
||||
row = col.row()
|
||||
row.prop(spline, "use_cyclic")
|
||||
row.prop(spline, "use_fill")
|
||||
|
||||
|
||||
class MASK_PT_point():
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'UI'
|
||||
bl_label = "Active Point"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
|
||||
if mask and sc.mode == 'MASK':
|
||||
mask_layer_active = mask.layers.active
|
||||
return (mask_layer_active and
|
||||
mask_layer_active.splines.active_point)
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sc = context.space_data
|
||||
mask = sc.mask
|
||||
point = mask.layers.active.splines.active_point
|
||||
parent = point.parent
|
||||
|
||||
col = layout.column()
|
||||
col.prop(point, "handle_type")
|
||||
|
||||
col = layout.column()
|
||||
# Currently only parenting yo movie clip is allowed, so do not
|
||||
# ver-oplicate things for now and use single template_ID
|
||||
#col.template_any_ID(parent, "id", "id_type", text="")
|
||||
|
||||
col.label("Parent:")
|
||||
col.prop(parent, "id", text="")
|
||||
|
||||
if parent.id_type == 'MOVIECLIP' and parent.id:
|
||||
clip = parent.id
|
||||
tracking = clip.tracking
|
||||
|
||||
col.prop_search(parent, "parent", tracking,
|
||||
"objects", icon='OBJECT_DATA', text="Object:")
|
||||
|
||||
if parent.parent in tracking.objects:
|
||||
object = tracking.objects[parent.parent]
|
||||
col.prop_search(parent, "sub_parent", object,
|
||||
"tracks", icon='ANIM_DATA', text="Track:")
|
||||
else:
|
||||
col.prop_search(parent, "sub_parent", tracking,
|
||||
"tracks", icon='ANIM_DATA', text="Track:")
|
||||
|
||||
|
||||
class MASK_PT_display():
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'UI'
|
||||
bl_label = "Mask Display"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space_data = context.space_data
|
||||
return space_data.mask and space_data.mode == 'MASK'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
space_data = context.space_data
|
||||
|
||||
layout.prop(space_data, "mask_draw_type", text="")
|
||||
layout.prop(space_data, "show_mask_smooth")
|
||||
|
||||
|
||||
class MASK_PT_tools():
|
||||
# subclasses must define...
|
||||
#~ bl_space_type = 'CLIP_EDITOR'
|
||||
#~ bl_region_type = 'TOOLS'
|
||||
bl_label = "Mask Tools"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space_data = context.space_data
|
||||
return space_data.mask and space_data.mode == 'MASK'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Transform:")
|
||||
col.operator("transform.translate")
|
||||
col.operator("transform.rotate")
|
||||
col.operator("transform.resize", text="Scale")
|
||||
props = col.operator("transform.transform", text="Shrink/Fatten")
|
||||
props.mode = 'MASK_SHRINKFATTEN'
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Spline:")
|
||||
col.operator("mask.delete")
|
||||
col.operator("mask.cyclic_toggle")
|
||||
col.operator("mask.switch_direction")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Parenting:")
|
||||
col.operator("mask.parent_set")
|
||||
col.operator("mask.parent_clear")
|
||||
|
||||
|
||||
class MASK_MT_mask(Menu):
|
||||
bl_label = "Mask"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("mask.delete")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("mask.cyclic_toggle")
|
||||
layout.operator("mask.switch_direction")
|
||||
layout.operator("mask.normals_make_consistent")
|
||||
layout.operator("mask.feather_weight_clear") # TODO, better place?
|
||||
|
||||
layout.separator()
|
||||
layout.operator("mask.parent_clear")
|
||||
layout.operator("mask.parent_set")
|
||||
|
||||
layout.separator()
|
||||
layout.menu("MASK_MT_visibility")
|
||||
layout.menu("MASK_MT_transform")
|
||||
layout.menu("MASK_MT_animation")
|
||||
|
||||
|
||||
class MASK_MT_visibility(Menu):
|
||||
bl_label = "Show/Hide"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("mask.hide_view_clear", text="Show Hidden")
|
||||
layout.operator("mask.hide_view_set", text="Hide Selected")
|
||||
|
||||
props = layout.operator("mask.hide_view_set", text="Hide Unselected")
|
||||
props.unselected = True
|
||||
|
||||
|
||||
class MASK_MT_transform(Menu):
|
||||
bl_label = "Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("transform.translate")
|
||||
layout.operator("transform.rotate")
|
||||
layout.operator("transform.resize")
|
||||
props = layout.operator("transform.transform", text="Shrink/Fatten")
|
||||
props.mode = 'MASK_SHRINKFATTEN'
|
||||
|
||||
|
||||
class MASK_MT_animation(Menu):
|
||||
bl_label = "Animation"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("mask.shape_key_clear")
|
||||
layout.operator("mask.shape_key_insert")
|
||||
layout.operator("mask.shape_key_feather_reset")
|
||||
layout.operator("mask.shape_key_rekey")
|
||||
|
||||
|
||||
class MASK_MT_select(Menu):
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
sc = context.space_data
|
||||
|
||||
layout.operator("mask.select_border")
|
||||
layout.operator("mask.select_circle")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mask.select_all").action = 'TOGGLE'
|
||||
layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
@ -350,7 +350,6 @@ class MATERIAL_PT_shading(MaterialButtonsPanel, Panel):
|
||||
|
||||
class MATERIAL_PT_transp(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Transparency"
|
||||
# bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
@classmethod
|
||||
|
@ -259,7 +259,6 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
|
||||
layout.prop(ob, "use_dupli_vertices_rotation", text="Rotation")
|
||||
|
||||
elif ob.dupli_type == 'FACES':
|
||||
|
||||
row = layout.row()
|
||||
row.prop(ob, "use_dupli_faces_scale", text="Scale")
|
||||
row.prop(ob, "dupli_faces_scale", text="Inherit Scale")
|
||||
|
@ -186,11 +186,8 @@ def effector_weights_ui(self, context, weights):
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(weights, "gravity", slider=True)
|
||||
|
||||
col = split.column()
|
||||
col.prop(weights, "all", slider=True)
|
||||
split.prop(weights, "gravity", slider=True)
|
||||
split.prop(weights, "all", slider=True)
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user