Compare commits
405 Commits
blender2.7
...
pbr-viewpo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f87036e8a7 | ||
![]() |
f8a1255464 | ||
![]() |
0497b012a3 | ||
![]() |
669c2801c0 | ||
![]() |
d26de5c907 | ||
![]() |
01872d7f5d | ||
![]() |
1640ea89e5 | ||
![]() |
dd23e52817 | ||
![]() |
d74f6b2204 | ||
224d70c978 | |||
![]() |
4948b6e226 | ||
4ea6917468 | |||
c6abbb40ad | |||
![]() |
feff6b4df3 | ||
![]() |
12c0394a4f | ||
a92d20a0a4 | |||
![]() |
06b5508073 | ||
![]() |
6f81e808e3 | ||
![]() |
d0989e538e | ||
![]() |
418b24551e | ||
![]() |
225edf4e66 | ||
![]() |
33d99bdfe6 | ||
9941bc3041 | |||
625f1a1c30 | |||
05117d71a3 | |||
54a0ff3ab5 | |||
e9268abf4a | |||
117af2356a | |||
46a069822a | |||
827ad4125c | |||
70ff63e63f | |||
0c6939f5f5 | |||
8327795f8d | |||
![]() |
6a0292cc19 | ||
![]() |
4811b2d356 | ||
e7fddc0772 | |||
42677fa937 | |||
ca369e6f0c | |||
61ca73ea10 | |||
36d2365ac3 | |||
9cdf4afb76 | |||
f7414b7412 | |||
![]() |
d1a35b7a08 | ||
![]() |
fa39ec9e46 | ||
![]() |
196654ad08 | ||
![]() |
69713aa2da | ||
![]() |
b557ceb2c1 | ||
![]() |
9a9a663f40 | ||
![]() |
f929045c2c | ||
3999910b19 | |||
1deab69e0a | |||
741965615d | |||
a4fe823416 | |||
a8dc3f4596 | |||
878938f203 | |||
3996fbc564 | |||
cf5750a85e | |||
![]() |
5e428b3b3f | ||
fcff984338 | |||
9632ca0a13 | |||
2df27995f9 | |||
48db35468f | |||
29b47924dd | |||
4f4c7808e4 | |||
![]() |
325b21c1d5 | ||
4736f19000 | |||
3f0c0ed87d | |||
![]() |
9904d73d9a | ||
![]() |
ae8e845470 | ||
![]() |
ee54a6f130 | ||
![]() |
608e2402ef | ||
![]() |
4a10eb38a3 | ||
![]() |
e1e97bbb98 | ||
![]() |
11653f85ff | ||
34dc660a76 | |||
dd350c0b37 | |||
6855ba4034 | |||
f23db59e48 | |||
![]() |
58f0af965c | ||
![]() |
3cecf39069 | ||
![]() |
05cf74622f | ||
945f8e3f93 | |||
![]() |
dfa5b32c8c | ||
![]() |
ecbedce81e | ||
14d0549295 | |||
![]() |
916e631fc9 | ||
![]() |
3579350481 | ||
6f220c1c55 | |||
71656ac222 | |||
![]() |
d5b75256e0 | ||
![]() |
c565f7b5fd | ||
![]() |
165bdfb672 | ||
![]() |
b5c539f9fa | ||
![]() |
84ed9d9829 | ||
![]() |
69b1b95356 | ||
![]() |
e79f302f16 | ||
![]() |
f6e7e46fac | ||
683656681c | |||
06d4aca879 | |||
c330f37135 | |||
53d82c3e8d | |||
2fe7e70e92 | |||
0c43567a5a | |||
587a16352a | |||
6371f8ff8a | |||
ecbad54df9 | |||
22f59b81d7 | |||
78abbdf264 | |||
5fc9bed8b3 | |||
7a60f889d3 | |||
e636529e33 | |||
99db1b8d95 | |||
a2471d2b37 | |||
187d8f473a | |||
7a552612c3 | |||
25e4dc45e5 | |||
b071ac315c | |||
2a76da9ec2 | |||
a398cdedfa | |||
b613d25354 | |||
5c23b863f8 | |||
![]() |
6e358a1d06 | ||
![]() |
53d1dbbe5c | ||
4639664b3c | |||
107b585a41 | |||
9d40c3dc32 | |||
1865bcd3cf | |||
1f6d704008 | |||
0fbe35c674 | |||
70a16298ea | |||
![]() |
fc77787f6f | ||
![]() |
49beb714c5 | ||
![]() |
4539c2b173 | ||
![]() |
82d069c232 | ||
![]() |
490a938c8b | ||
![]() |
1997b0f03c | ||
1b4b4dfd0c | |||
fe654a93c7 | |||
e01b1eac84 | |||
![]() |
553b4faac8 | ||
ffc46668c4 | |||
![]() |
ea89b4a918 | ||
![]() |
6b88f3118f | ||
198e3a35c8 | |||
86e439e311 | |||
edcce96d97 | |||
360cb87007 | |||
e86bd78745 | |||
1731e94d0c | |||
e874f3cdc5 | |||
c462500618 | |||
![]() |
5e8c4ae75b | ||
3a4c1db14b | |||
79b8242fd1 | |||
![]() |
ae44e24fed | ||
55aadccbde | |||
72473a61b0 | |||
c50ccc8476 | |||
ba30b852f3 | |||
b8e3d81f31 | |||
875d63ccb5 | |||
5753a1462f | |||
d1b21d1278 | |||
82648a8f91 | |||
![]() |
42ed1f0e3c | ||
47bba7e15f | |||
![]() |
35bd833e02 | ||
bbf32980b0 | |||
![]() |
9bac74c27b | ||
![]() |
4c7ff8fb1e | ||
83d5a919e2 | |||
0ca2118851 | |||
ad32b774cb | |||
![]() |
88aa42a6f7 | ||
![]() |
fc485302cc | ||
8cff9c20ff | |||
628ef78e8a | |||
a731c75442 | |||
9bea012b8c | |||
5c6baf1ee9 | |||
addc666999 | |||
36bbdf142c | |||
7fc2e333bb | |||
![]() |
1dfb89d229 | ||
![]() |
4a1feaa555 | ||
1d469f3780 | |||
0e7c3dfe75 | |||
825150605e | |||
9047717b3f | |||
0f759da370 | |||
![]() |
284398e517 | ||
![]() |
04bc828fb6 | ||
![]() |
6ebf5c18c3 | ||
d3365c5c72 | |||
![]() |
42ad5952ff | ||
34bd89a9f6 | |||
e21853abb9 | |||
1b1275f0db | |||
c3034afa58 | |||
834cb93f40 | |||
d96b8e168f | |||
76c99f361f | |||
5eddb80513 | |||
39f7a81176 | |||
0d54d32dd6 | |||
2fb5a959e9 | |||
110d68ca1d | |||
df7be04ca6 | |||
54b00657ca | |||
1b5b899228 | |||
ddb1d5648d | |||
b6bd299359 | |||
18d49a8283 | |||
031c5bad87 | |||
![]() |
a84794b399 | ||
3c29aad787 | |||
498583844f | |||
9d3813e602 | |||
42bbfe7f0a | |||
060bf1bd28 | |||
da36b447c7 | |||
1fc1fd8372 | |||
069569f820 | |||
be2bc7e0f6 | |||
eb717ee979 | |||
1e6b3ef1a1 | |||
7e02d335c0 | |||
d8f036efd6 | |||
6b34eed217 | |||
b92d76000d | |||
b8f27b2514 | |||
8619e09107 | |||
23d7ae1843 | |||
f1ad3483af | |||
91f04b82a5 | |||
90c4ad7387 | |||
db5ad6a79e | |||
e36af2c257 | |||
dfbc51f764 | |||
4565f3d0c8 | |||
7664d947b3 | |||
4aadf7331e | |||
f537d96286 | |||
adbbcefe57 | |||
8fd4a8ab5d | |||
e7a32365cf | |||
5320a0ad9b | |||
e4e1b0c7d3 | |||
f3d65ad23c | |||
b7f3fb0ef9 | |||
a77e77599d | |||
9893153799 | |||
39259fc8ab | |||
c73e4e99a5 | |||
4214b3c44a | |||
6c65e5a00c | |||
8e99eec026 | |||
11ffbfb36a | |||
6fea42d677 | |||
f27516839f | |||
0ea8430549 | |||
e7f9614f07 | |||
6b21d22c60 | |||
a55c5dbcc4 | |||
3eae585791 | |||
9843921288 | |||
4571fdde0e | |||
58697444bb | |||
32757d488f | |||
396dd82428 | |||
797f1896fa | |||
42d816a3d9 | |||
3d9cc4d3f1 | |||
b3cb7e2652 | |||
0d1f0116fe | |||
eccf5a6f81 | |||
251349c3c2 | |||
b1532493c2 | |||
9186b9ae48 | |||
cfbd605567 | |||
![]() |
20fa91bd47 | ||
71a57a37b2 | |||
f45fbf4b83 | |||
b90b02a480 | |||
5ae6a3b6b6 | |||
0f927d6eca | |||
cbce7fef16 | |||
c2dc77983d | |||
3b0a5dd158 | |||
97ee7f8609 | |||
48c58bd913 | |||
![]() |
ddfae3d2e1 | ||
![]() |
4cae0cb418 | ||
![]() |
22c83011a9 | ||
2cfff95ba3 | |||
eedcc4a6a0 | |||
5864269b2c | |||
46e1d85e61 | |||
c96d4ec644 | |||
a151806698 | |||
10d57f991b | |||
4b99958ca1 | |||
1e5735ab99 | |||
5750549f6a | |||
ed6f86a510 | |||
24d29f2e50 | |||
![]() |
d2ec40b8f5 | ||
![]() |
31d65359e8 | ||
![]() |
554952d114 | ||
![]() |
d85b6b86cf | ||
![]() |
db461850d7 | ||
![]() |
d28c4d4a7c | ||
![]() |
96f6372a07 | ||
![]() |
9c8fbd9813 | ||
![]() |
fbf7e5acfb | ||
11af9e9a5b | |||
![]() |
d7d0166386 | ||
![]() |
6ebbef4724 | ||
![]() |
bcf5e1c7f5 | ||
![]() |
4841e60261 | ||
faec430914 | |||
![]() |
7e4d937718 | ||
f85745b17b | |||
![]() |
579d16714f | ||
![]() |
d949b28199 | ||
![]() |
e54385f059 | ||
![]() |
b372028836 | ||
![]() |
105a1d84c4 | ||
![]() |
80f03704e7 | ||
![]() |
655cfca452 | ||
b4a721af69 | |||
5aa19be912 | |||
735727e2b8 | |||
ac30a04b27 | |||
181d095f50 | |||
ceb452bc9d | |||
c3863650cc | |||
1f723603c8 | |||
3632c4997f | |||
773efb506a | |||
ba279efbdb | |||
9465d3decf | |||
ecb695ccc8 | |||
![]() |
7c777fe038 | ||
![]() |
81737e6cca | ||
cd0ec340c4 | |||
15c8d095e5 | |||
7c57822afa | |||
c92b6f1de6 | |||
d30b942f07 | |||
df2e543d44 | |||
fbed29a246 | |||
987bb50a74 | |||
d474ed9b88 | |||
664f5b8c06 | |||
d8d49befa0 | |||
d47173c8ca | |||
cf6cb3dcaf | |||
bcd12bf64d | |||
29a792a75b | |||
cc468c1974 | |||
82ec9c87a7 | |||
5a783144e2 | |||
![]() |
515be07dd4 | ||
![]() |
7750dea70e | ||
![]() |
f50bf4f110 | ||
![]() |
c1580b9cd4 | ||
![]() |
c112a54d2a | ||
![]() |
1cd2d7b744 | ||
![]() |
798357ca57 | ||
![]() |
b818de11df | ||
![]() |
ef01bfd53d | ||
![]() |
bb9d7491e8 | ||
![]() |
37300f3307 | ||
![]() |
ed3a8ae7b3 | ||
![]() |
9a0e6c1883 | ||
![]() |
b6d97ce425 | ||
![]() |
1eb5ff3bbd | ||
![]() |
240e995062 | ||
![]() |
7e0cb40b48 | ||
![]() |
9974ada602 | ||
![]() |
b3c3275dad | ||
![]() |
8de5664a60 | ||
![]() |
52cb2981c4 | ||
![]() |
4b08c4d0ae | ||
![]() |
bec580b0f9 | ||
![]() |
e217b66505 | ||
![]() |
6d33b1031a | ||
![]() |
051c9c39d4 | ||
![]() |
20afa77324 | ||
![]() |
371c289af8 | ||
![]() |
59295b9126 | ||
![]() |
f0f398c0dd | ||
![]() |
a3a0220d57 | ||
![]() |
df63042d8f | ||
![]() |
3155b440bf | ||
![]() |
01a258f829 | ||
![]() |
a30e73bf67 | ||
![]() |
c326d403d8 | ||
![]() |
44aeca9023 | ||
![]() |
c89ced47bb | ||
![]() |
83aeba94c7 | ||
![]() |
4aebb28e60 | ||
![]() |
863923d3d0 | ||
![]() |
83a54dc2a8 |
@@ -25,7 +25,7 @@
|
||||
ARGS=$( \
|
||||
getopt \
|
||||
-o s:i:t:h \
|
||||
--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,use-cxx11,\
|
||||
--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,\
|
||||
with-all,with-opencollada,\
|
||||
ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\
|
||||
force-all,force-python,force-numpy,force-boost,\
|
||||
@@ -104,11 +104,6 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
|
||||
--no-confirm
|
||||
Disable any interaction with user (suitable for automated run).
|
||||
|
||||
--use-cxx11
|
||||
Build all libraries in cpp11 'mode' (will be mandatory soon in blender2.8 branch).
|
||||
NOTE: If your compiler is gcc-6.0 or above, you probably *want* to enable this option (since it's default
|
||||
standard starting from this version).
|
||||
|
||||
--with-all
|
||||
By default, a number of optional and not-so-often needed libraries are not installed.
|
||||
This option will try to install them, at the cost of potential conflicts (depending on
|
||||
@@ -287,7 +282,7 @@ SUDO="sudo"
|
||||
|
||||
NO_BUILD=false
|
||||
NO_CONFIRM=false
|
||||
USE_CXX11=false
|
||||
USE_CXX11=true # Mandatory in blender2.8
|
||||
|
||||
PYTHON_VERSION="3.5.1"
|
||||
PYTHON_VERSION_MIN="3.5"
|
||||
@@ -499,9 +494,6 @@ while true; do
|
||||
--no-confirm)
|
||||
NO_CONFIRM=true; shift; continue
|
||||
;;
|
||||
--use-cxx11)
|
||||
USE_CXX11=true; shift; continue
|
||||
;;
|
||||
--with-all)
|
||||
WITH_ALL=true; shift; continue
|
||||
;;
|
||||
@@ -778,7 +770,7 @@ FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" )
|
||||
|
||||
CXXFLAGS_BACK=$CXXFLAGS
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
WARNING "You are trying to use c++11, this *should* go smoothely with any very recent distribution
|
||||
WARNING "C++11 is now mandatory for blender2.8, this *should* go smoothly with any very recent distribution.
|
||||
However, if you are experiencing linking errors (also when building Blender itself), please try the following:
|
||||
* Re-run this script with `--build-all --force-all` options.
|
||||
* Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above.
|
||||
|
@@ -25,7 +25,6 @@ set(SRC
|
||||
blender_camera.cpp
|
||||
blender_mesh.cpp
|
||||
blender_object.cpp
|
||||
blender_particles.cpp
|
||||
blender_curves.cpp
|
||||
blender_logging.cpp
|
||||
blender_python.cpp
|
||||
|
@@ -1080,49 +1080,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
|
||||
del bpy.types.Scene.cycles_curves
|
||||
|
||||
|
||||
class CyclesCurveSettings(bpy.types.PropertyGroup):
|
||||
@classmethod
|
||||
def register(cls):
|
||||
bpy.types.ParticleSettings.cycles = PointerProperty(
|
||||
name="Cycles Hair Settings",
|
||||
description="Cycles hair settings",
|
||||
type=cls,
|
||||
)
|
||||
cls.radius_scale = FloatProperty(
|
||||
name="Radius Scaling",
|
||||
description="Multiplier of width properties",
|
||||
min=0.0, max=1000.0,
|
||||
default=0.01,
|
||||
)
|
||||
cls.root_width = FloatProperty(
|
||||
name="Root Size",
|
||||
description="Strand's width at root",
|
||||
min=0.0, max=1000.0,
|
||||
default=1.0,
|
||||
)
|
||||
cls.tip_width = FloatProperty(
|
||||
name="Tip Multiplier",
|
||||
description="Strand's width at tip",
|
||||
min=0.0, max=1000.0,
|
||||
default=0.0,
|
||||
)
|
||||
cls.shape = FloatProperty(
|
||||
name="Strand Shape",
|
||||
description="Strand shape parameter",
|
||||
min=-1.0, max=1.0,
|
||||
default=0.0,
|
||||
)
|
||||
cls.use_closetip = BoolProperty(
|
||||
name="Close tip",
|
||||
description="Set tip radius to zero",
|
||||
default=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
del bpy.types.ParticleSettings.cycles
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(CyclesRenderSettings)
|
||||
bpy.utils.register_class(CyclesCameraSettings)
|
||||
@@ -1133,7 +1090,6 @@ def register():
|
||||
bpy.utils.register_class(CyclesMeshSettings)
|
||||
bpy.utils.register_class(CyclesObjectSettings)
|
||||
bpy.utils.register_class(CyclesCurveRenderSettings)
|
||||
bpy.utils.register_class(CyclesCurveSettings)
|
||||
|
||||
|
||||
def unregister():
|
||||
@@ -1146,4 +1102,3 @@ def unregister():
|
||||
bpy.utils.unregister_class(CyclesObjectSettings)
|
||||
bpy.utils.unregister_class(CyclesVisibilitySettings)
|
||||
bpy.utils.unregister_class(CyclesCurveRenderSettings)
|
||||
bpy.utils.unregister_class(CyclesCurveSettings)
|
||||
|
@@ -1349,37 +1349,6 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
|
||||
layout.template_color_ramp(mapping, "color_ramp", expand=True)
|
||||
|
||||
|
||||
class CyclesParticle_PT_textures(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Textures"
|
||||
bl_context = "particle"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
psys = context.particle_system
|
||||
return psys and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
row = layout.row()
|
||||
row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
|
||||
col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
|
||||
col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
if not part.active_texture:
|
||||
layout.template_ID(part, "active_texture", new="texture.new")
|
||||
else:
|
||||
slot = part.texture_slots[part.active_texture_index]
|
||||
layout.template_ID(slot, "texture", new="texture.new")
|
||||
|
||||
|
||||
class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Cycles Hair Rendering"
|
||||
bl_context = "particle"
|
||||
@@ -1528,37 +1497,6 @@ class CyclesRender_PT_debug(CyclesButtonsPanel, Panel):
|
||||
col.prop(cscene, "debug_use_opencl_debug", text="Debug")
|
||||
|
||||
|
||||
class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Cycles Hair Settings"
|
||||
bl_context = "particle"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
ccscene = scene.cycles_curves
|
||||
psys = context.particle_system
|
||||
use_curves = ccscene.use_curves and psys
|
||||
return CyclesButtonsPanel.poll(context) and use_curves and psys.settings.type == 'HAIR'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_settings
|
||||
cpsys = psys.cycles
|
||||
|
||||
row = layout.row()
|
||||
row.prop(cpsys, "shape", text="Shape")
|
||||
|
||||
layout.label(text="Thickness:")
|
||||
row = layout.row()
|
||||
row.prop(cpsys, "root_width", text="Root")
|
||||
row.prop(cpsys, "tip_width", text="Tip")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(cpsys, "radius_scale", text="Scaling")
|
||||
row.prop(cpsys, "use_closetip", text="Close tip")
|
||||
|
||||
|
||||
class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Simplify"
|
||||
bl_context = "scene"
|
||||
@@ -1581,12 +1519,10 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.label(text="Viewport:")
|
||||
col.prop(rd, "simplify_subdivision", text="Subdivision")
|
||||
col.prop(rd, "simplify_child_particles", text="Child Particles")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Render:")
|
||||
col.prop(rd, "simplify_subdivision_render", text="Subdivision")
|
||||
col.prop(rd, "simplify_child_particles_render", text="Child Particles")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(cscene, "use_camera_cull")
|
||||
|
@@ -37,9 +37,6 @@ void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, floa
|
||||
void interp_weights(float t, float data[4]);
|
||||
float shaperadius(float shape, float root, float tip, float time);
|
||||
void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData);
|
||||
bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num);
|
||||
bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num);
|
||||
bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background);
|
||||
void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData);
|
||||
void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
|
||||
float3 RotCam, bool is_ortho);
|
||||
@@ -119,220 +116,6 @@ void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyl
|
||||
curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
|
||||
}
|
||||
|
||||
bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background)
|
||||
{
|
||||
int curvenum = 0;
|
||||
int keyno = 0;
|
||||
|
||||
if(!(mesh && b_mesh && b_ob && CData))
|
||||
return false;
|
||||
|
||||
Transform tfm = get_transform(b_ob->matrix_world());
|
||||
Transform itfm = transform_quick_inverse(tfm);
|
||||
|
||||
BL::Object::modifiers_iterator b_mod;
|
||||
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
||||
if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
|
||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||
|
||||
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
|
||||
int shader = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
|
||||
int draw_step = background ? b_part.render_step() : b_part.draw_step();
|
||||
int totparts = b_psys.particles.length();
|
||||
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
|
||||
int totcurves = totchild;
|
||||
|
||||
if(b_part.child_type() == 0 || totchild == 0)
|
||||
totcurves += totparts;
|
||||
|
||||
if(totcurves == 0)
|
||||
continue;
|
||||
|
||||
int ren_step = (1 << draw_step) + 1;
|
||||
if(b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
|
||||
ren_step += b_part.kink_extra_steps();
|
||||
|
||||
PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
|
||||
|
||||
CData->psys_firstcurve.push_back_slow(curvenum);
|
||||
CData->psys_curvenum.push_back_slow(totcurves);
|
||||
CData->psys_shader.push_back_slow(shader);
|
||||
|
||||
float radius = get_float(cpsys, "radius_scale") * 0.5f;
|
||||
|
||||
CData->psys_rootradius.push_back_slow(radius * get_float(cpsys, "root_width"));
|
||||
CData->psys_tipradius.push_back_slow(radius * get_float(cpsys, "tip_width"));
|
||||
CData->psys_shape.push_back_slow(get_float(cpsys, "shape"));
|
||||
CData->psys_closetip.push_back_slow(get_boolean(cpsys, "use_closetip"));
|
||||
|
||||
int pa_no = 0;
|
||||
if(!(b_part.child_type() == 0) && totchild != 0)
|
||||
pa_no = totparts;
|
||||
|
||||
int num_add = (totparts+totchild - pa_no);
|
||||
CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
|
||||
CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
|
||||
CData->curve_length.reserve(CData->curve_length.size() + num_add);
|
||||
CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add*ren_step);
|
||||
CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add*ren_step);
|
||||
|
||||
for(; pa_no < totparts+totchild; pa_no++) {
|
||||
int keynum = 0;
|
||||
CData->curve_firstkey.push_back_slow(keyno);
|
||||
|
||||
float curve_length = 0.0f;
|
||||
float3 pcKey;
|
||||
for(int step_no = 0; step_no < ren_step; step_no++) {
|
||||
float nco[3];
|
||||
b_psys.co_hair(*b_ob, pa_no, step_no, nco);
|
||||
float3 cKey = make_float3(nco[0], nco[1], nco[2]);
|
||||
cKey = transform_point(&itfm, cKey);
|
||||
if(step_no > 0) {
|
||||
float step_length = len(cKey - pcKey);
|
||||
if(step_length == 0.0f)
|
||||
continue;
|
||||
curve_length += step_length;
|
||||
}
|
||||
CData->curvekey_co.push_back_slow(cKey);
|
||||
CData->curvekey_time.push_back_slow(curve_length);
|
||||
pcKey = cKey;
|
||||
keynum++;
|
||||
}
|
||||
keyno += keynum;
|
||||
|
||||
CData->curve_keynum.push_back_slow(keynum);
|
||||
CData->curve_length.push_back_slow(curve_length);
|
||||
curvenum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num)
|
||||
{
|
||||
if(!(mesh && b_mesh && b_ob && CData))
|
||||
return false;
|
||||
|
||||
CData->curve_uv.clear();
|
||||
|
||||
BL::Object::modifiers_iterator b_mod;
|
||||
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
||||
if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
|
||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||
|
||||
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
|
||||
int totparts = b_psys.particles.length();
|
||||
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
|
||||
int totcurves = totchild;
|
||||
|
||||
if(b_part.child_type() == 0 || totchild == 0)
|
||||
totcurves += totparts;
|
||||
|
||||
if(totcurves == 0)
|
||||
continue;
|
||||
|
||||
int pa_no = 0;
|
||||
if(!(b_part.child_type() == 0) && totchild != 0)
|
||||
pa_no = totparts;
|
||||
|
||||
int num_add = (totparts+totchild - pa_no);
|
||||
CData->curve_uv.reserve(CData->curve_uv.size() + num_add);
|
||||
|
||||
BL::ParticleSystem::particles_iterator b_pa;
|
||||
b_psys.particles.begin(b_pa);
|
||||
for(; pa_no < totparts+totchild; pa_no++) {
|
||||
/* Add UVs */
|
||||
BL::Mesh::tessface_uv_textures_iterator l;
|
||||
b_mesh->tessface_uv_textures.begin(l);
|
||||
|
||||
float3 uv = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if(b_mesh->tessface_uv_textures.length())
|
||||
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
|
||||
CData->curve_uv.push_back_slow(uv);
|
||||
|
||||
if(pa_no < totparts && b_pa != b_psys.particles.end())
|
||||
++b_pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num)
|
||||
{
|
||||
if(!(mesh && b_mesh && b_ob && CData))
|
||||
return false;
|
||||
|
||||
CData->curve_vcol.clear();
|
||||
|
||||
BL::Object::modifiers_iterator b_mod;
|
||||
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
||||
if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
|
||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
|
||||
|
||||
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
|
||||
int totparts = b_psys.particles.length();
|
||||
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
|
||||
int totcurves = totchild;
|
||||
|
||||
if(b_part.child_type() == 0 || totchild == 0)
|
||||
totcurves += totparts;
|
||||
|
||||
if(totcurves == 0)
|
||||
continue;
|
||||
|
||||
int pa_no = 0;
|
||||
if(!(b_part.child_type() == 0) && totchild != 0)
|
||||
pa_no = totparts;
|
||||
|
||||
int num_add = (totparts+totchild - pa_no);
|
||||
CData->curve_vcol.reserve(CData->curve_vcol.size() + num_add);
|
||||
|
||||
BL::ParticleSystem::particles_iterator b_pa;
|
||||
b_psys.particles.begin(b_pa);
|
||||
for(; pa_no < totparts+totchild; pa_no++) {
|
||||
/* Add vertex colors */
|
||||
BL::Mesh::tessface_vertex_colors_iterator l;
|
||||
b_mesh->tessface_vertex_colors.begin(l);
|
||||
|
||||
float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if(b_mesh->tessface_vertex_colors.length())
|
||||
b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
|
||||
CData->curve_vcol.push_back_slow(vcol);
|
||||
|
||||
if(pa_no < totparts && b_pa != b_psys.particles.end())
|
||||
++b_pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_resolution(BL::Object *b_ob, BL::Scene *scene, bool render)
|
||||
{
|
||||
BL::Object::modifiers_iterator b_mod;
|
||||
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
|
||||
if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && ((b_mod->show_viewport()) || (b_mod->show_render()))) {
|
||||
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
|
||||
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
|
||||
b_psys.set_resolution(*scene, *b_ob, (render)? 2: 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
|
||||
float3 RotCam, bool is_ortho)
|
||||
{
|
||||
@@ -837,20 +620,6 @@ void BlenderSync::sync_curve_settings()
|
||||
}
|
||||
|
||||
if(curve_system_manager->modified_mesh(prev_curve_system_manager)) {
|
||||
BL::BlendData::objects_iterator b_ob;
|
||||
|
||||
for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
|
||||
if(object_is_mesh(*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((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR)) {
|
||||
BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
|
||||
mesh_map.set_recalc(key);
|
||||
object_map.set_recalc(*b_ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(curve_system_manager->modified(prev_curve_system_manager))
|
||||
@@ -875,7 +644,7 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
/* obtain general settings */
|
||||
bool use_curves = scene->curve_system_manager->use_curves;
|
||||
|
||||
if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
|
||||
if(!use_curves) {
|
||||
if(!motion)
|
||||
mesh->compute_bounds();
|
||||
return;
|
||||
@@ -892,11 +661,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
|
||||
ParticleCurveData CData;
|
||||
|
||||
if(!preview)
|
||||
set_resolution(&b_ob, &b_scene, true);
|
||||
|
||||
ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
|
||||
|
||||
/* add hair geometry to mesh */
|
||||
if(primitive == CURVE_TRIANGLES) {
|
||||
if(triangle_method == CURVE_CAMERA_TRIANGLES) {
|
||||
@@ -964,8 +728,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
|
||||
continue;
|
||||
|
||||
ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num);
|
||||
|
||||
if(primitive == CURVE_TRIANGLES) {
|
||||
Attribute *attr_vcol = mesh->attributes.add(
|
||||
ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
|
||||
@@ -1005,8 +767,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
|
||||
Attribute *attr_uv;
|
||||
|
||||
ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num);
|
||||
|
||||
if(primitive == CURVE_TRIANGLES) {
|
||||
if(active_render)
|
||||
attr_uv = mesh->attributes.add(std, name);
|
||||
@@ -1037,9 +797,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
}
|
||||
}
|
||||
|
||||
if(!preview)
|
||||
set_resolution(&b_ob, &b_scene, false);
|
||||
|
||||
mesh->compute_bounds();
|
||||
}
|
||||
|
||||
|
@@ -465,29 +465,9 @@ static bool object_render_hide(BL::Object& b_ob,
|
||||
bool parent_hide,
|
||||
bool& hide_triangles)
|
||||
{
|
||||
/* check if we should render or hide particle emitter */
|
||||
BL::Object::particle_systems_iterator b_psys;
|
||||
|
||||
bool hair_present = false;
|
||||
bool show_emitter = false;
|
||||
bool hide_emitter = false;
|
||||
bool hide_as_dupli_parent = false;
|
||||
bool hide_as_dupli_child_original = false;
|
||||
|
||||
for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
|
||||
if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
|
||||
(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
|
||||
hair_present = true;
|
||||
|
||||
if(b_psys->settings().use_render_emitter())
|
||||
show_emitter = true;
|
||||
else
|
||||
hide_emitter = true;
|
||||
}
|
||||
|
||||
if(show_emitter)
|
||||
hide_emitter = false;
|
||||
|
||||
/* duplicators hidden by default, except dupliframes which duplicate self */
|
||||
if(b_ob.is_duplicator())
|
||||
if(top_level || b_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
|
||||
@@ -507,17 +487,9 @@ static bool object_render_hide(BL::Object& b_ob,
|
||||
parent = parent.parent();
|
||||
}
|
||||
|
||||
hide_triangles = hide_emitter;
|
||||
hide_triangles = false;
|
||||
|
||||
if(show_emitter) {
|
||||
return false;
|
||||
}
|
||||
else if(hair_present) {
|
||||
return hide_as_dupli_child_original;
|
||||
}
|
||||
else {
|
||||
return (hide_as_dupli_parent || hide_as_dupli_child_original);
|
||||
}
|
||||
return (hide_as_dupli_parent || hide_as_dupli_child_original);
|
||||
}
|
||||
|
||||
static bool object_render_hide_duplis(BL::Object& b_ob)
|
||||
@@ -540,7 +512,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
light_map.pre_sync();
|
||||
mesh_map.pre_sync();
|
||||
object_map.pre_sync();
|
||||
particle_system_map.pre_sync();
|
||||
motion_times.clear();
|
||||
}
|
||||
else {
|
||||
@@ -614,23 +585,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
|
||||
|
||||
/* sync object and mesh or light data */
|
||||
Object *object = sync_object(b_ob,
|
||||
persistent_id.data,
|
||||
*b_dup,
|
||||
tfm,
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
&use_portal);
|
||||
|
||||
/* sync possible particle data, note particle_id
|
||||
* starts counting at 1, first is dummy particle */
|
||||
if(!motion && object) {
|
||||
sync_dupli_particle(b_ob, *b_dup, object);
|
||||
}
|
||||
|
||||
sync_object(b_ob,
|
||||
persistent_id.data,
|
||||
*b_dup,
|
||||
tfm,
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
&use_portal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,8 +637,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
scene->mesh_manager->tag_update(scene);
|
||||
if(object_map.post_sync())
|
||||
scene->object_manager->tag_update(scene);
|
||||
if(particle_system_map.post_sync())
|
||||
scene->particle_system_manager->tag_update(scene);
|
||||
}
|
||||
|
||||
if(motion)
|
||||
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mesh.h"
|
||||
#include "object.h"
|
||||
#include "particles.h"
|
||||
|
||||
#include "blender_sync.h"
|
||||
#include "blender_util.h"
|
||||
|
||||
#include "util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Utilities */
|
||||
|
||||
bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
|
||||
BL::DupliObject& b_dup,
|
||||
Object *object)
|
||||
{
|
||||
/* test if this dupli was generated from a particle sytem */
|
||||
BL::ParticleSystem b_psys = b_dup.particle_system();
|
||||
if(!b_psys)
|
||||
return false;
|
||||
|
||||
object->hide_on_missing_motion = true;
|
||||
|
||||
/* test if we need particle data */
|
||||
if(!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
|
||||
return false;
|
||||
|
||||
/* don't handle child particles yet */
|
||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup.persistent_id();
|
||||
|
||||
if(persistent_id[0] >= b_psys.particles.length())
|
||||
return false;
|
||||
|
||||
/* find particle system */
|
||||
ParticleSystemKey key(b_ob, persistent_id);
|
||||
ParticleSystem *psys;
|
||||
|
||||
bool first_use = !particle_system_map.is_used(key);
|
||||
bool need_update = particle_system_map.sync(&psys, b_ob, b_dup.object(), key);
|
||||
|
||||
/* no update needed? */
|
||||
if(!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
|
||||
return true;
|
||||
|
||||
/* first time used in this sync loop? clear and tag update */
|
||||
if(first_use) {
|
||||
psys->particles.clear();
|
||||
psys->tag_update(scene);
|
||||
}
|
||||
|
||||
/* add particle */
|
||||
BL::Particle b_pa = b_psys.particles[persistent_id[0]];
|
||||
Particle pa;
|
||||
|
||||
pa.index = persistent_id[0];
|
||||
pa.age = b_scene.frame_current() - b_pa.birth_time();
|
||||
pa.lifetime = b_pa.lifetime();
|
||||
pa.location = get_float3(b_pa.location());
|
||||
pa.rotation = get_float4(b_pa.rotation());
|
||||
pa.size = b_pa.size();
|
||||
pa.velocity = get_float3(b_pa.velocity());
|
||||
pa.angular_velocity = get_float3(b_pa.angular_velocity());
|
||||
|
||||
psys->particles.push_back_slow(pa);
|
||||
|
||||
if(object->particle_index != psys->particles.size() - 1)
|
||||
scene->object_manager->tag_update(scene);
|
||||
object->particle_system = psys;
|
||||
object->particle_index = psys->particles.size() - 1;
|
||||
|
||||
/* return that this object has particle data */
|
||||
return true;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -56,7 +56,6 @@ BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
|
||||
object_map(&scene->objects),
|
||||
mesh_map(&scene->meshes),
|
||||
light_map(&scene->lights),
|
||||
particle_system_map(&scene->particle_systems),
|
||||
world_map(NULL),
|
||||
world_recalc(false),
|
||||
scene(scene),
|
||||
@@ -144,12 +143,6 @@ bool BlenderSync::sync_recalc()
|
||||
if(b_ob->is_updated_data() || b_ob->data().is_updated())
|
||||
light_map.set_recalc(*b_ob);
|
||||
}
|
||||
|
||||
if(b_ob->is_updated_data()) {
|
||||
BL::Object::particle_systems_iterator b_psys;
|
||||
for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
|
||||
particle_system_map.set_recalc(*b_ob);
|
||||
}
|
||||
}
|
||||
|
||||
BL::BlendData::meshes_iterator b_mesh;
|
||||
@@ -183,7 +176,6 @@ bool BlenderSync::sync_recalc()
|
||||
object_map.has_recalc() ||
|
||||
light_map.has_recalc() ||
|
||||
mesh_map.has_recalc() ||
|
||||
particle_system_map.has_recalc() ||
|
||||
BlendDataObjects_is_updated_get(&b_data.ptr) ||
|
||||
world_recalc;
|
||||
|
||||
|
@@ -139,11 +139,6 @@ private:
|
||||
int width, int height,
|
||||
float motion_time);
|
||||
|
||||
/* particles */
|
||||
bool sync_dupli_particle(BL::Object& b_ob,
|
||||
BL::DupliObject& b_dup,
|
||||
Object *object);
|
||||
|
||||
/* Images. */
|
||||
void sync_images();
|
||||
|
||||
@@ -162,7 +157,6 @@ private:
|
||||
id_map<ObjectKey, Object> object_map;
|
||||
id_map<void*, Mesh> mesh_map;
|
||||
id_map<ObjectKey, Light> light_map;
|
||||
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
|
||||
set<Mesh*> mesh_synced;
|
||||
set<Mesh*> mesh_motion_synced;
|
||||
std::set<float> motion_times;
|
||||
|
@@ -754,33 +754,6 @@ struct ObjectKey {
|
||||
}
|
||||
};
|
||||
|
||||
/* Particle System Key */
|
||||
|
||||
struct ParticleSystemKey {
|
||||
void *ob;
|
||||
int id[OBJECT_PERSISTENT_ID_SIZE];
|
||||
|
||||
ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE])
|
||||
: ob(ob_)
|
||||
{
|
||||
if(id_)
|
||||
memcpy(id, id_, sizeof(id));
|
||||
else
|
||||
memset(id, 0, sizeof(id));
|
||||
}
|
||||
|
||||
bool operator<(const ParticleSystemKey& k) const
|
||||
{
|
||||
/* first id is particle index, we don't compare that */
|
||||
if(ob < k.ob)
|
||||
return true;
|
||||
else if(ob == k.ob)
|
||||
return memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BLENDER_UTIL_H__ */
|
||||
|
2
intern/elbeem/extern/elbeem.h
vendored
2
intern/elbeem/extern/elbeem.h
vendored
@@ -111,7 +111,7 @@ typedef struct elbeemSimulationSettings {
|
||||
#define OB_FLUIDSIM_OBSTACLE 8
|
||||
#define OB_FLUIDSIM_INFLOW 16
|
||||
#define OB_FLUIDSIM_OUTFLOW 32
|
||||
#define OB_FLUIDSIM_PARTICLE 64
|
||||
#define OB_FLUIDSIM_PARTICLE 64 /* DEPRECATED */
|
||||
#define OB_FLUIDSIM_CONTROL 128
|
||||
|
||||
// defines for elbeemMesh->obstacleType below (low bits) high bits (>=64) are reserved for mFsSurfGenSetting flags which are defined in solver_class.h
|
||||
|
@@ -134,6 +134,8 @@ private:
|
||||
/** The OpenGL drawing context */
|
||||
NSOpenGLContext *m_openGLContext;
|
||||
|
||||
bool m_coreProfile;
|
||||
|
||||
//static CGLEWContext *s_cglewContext;
|
||||
|
||||
const bool m_debug;
|
||||
|
@@ -63,6 +63,23 @@ GHOST_ContextCGL::GHOST_ContextCGL(
|
||||
m_debug(contextFlags)
|
||||
{
|
||||
assert(openGLView != nil);
|
||||
|
||||
// for now be very strict about OpenGL version requested
|
||||
switch (contextMajorVersion) {
|
||||
case 2:
|
||||
assert(contextMinorVersion == 1);
|
||||
assert(contextProfileMask == 0);
|
||||
m_coreProfile = false;
|
||||
break;
|
||||
case 3:
|
||||
// Apple didn't implement 3.0 or 3.1
|
||||
assert(contextMinorVersion == 2);
|
||||
assert(contextProfileMask == GL_CONTEXT_CORE_PROFILE_BIT);
|
||||
m_coreProfile = true;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +187,7 @@ GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
|
||||
|
||||
static void makeAttribList(
|
||||
std::vector<NSOpenGLPixelFormatAttribute>& attribs,
|
||||
bool coreProfile,
|
||||
bool stereoVisual,
|
||||
int numOfAASamples,
|
||||
bool needAlpha,
|
||||
@@ -178,6 +196,9 @@ static void makeAttribList(
|
||||
{
|
||||
attribs.clear();
|
||||
|
||||
attribs.push_back(NSOpenGLPFAOpenGLProfile);
|
||||
attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
|
||||
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
||||
|
||||
@@ -190,8 +211,7 @@ static void makeAttribList(
|
||||
attribs.push_back(NSOpenGLPFANoRecovery);
|
||||
}
|
||||
|
||||
/* Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway */
|
||||
//attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
|
||||
attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); // for automatic GPU switching
|
||||
|
||||
attribs.push_back(NSOpenGLPFADepthSize);
|
||||
attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
|
||||
@@ -263,7 +283,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
// TODO: keep pixel format for subsequent windows/contexts instead of recreating each time
|
||||
|
||||
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
||||
makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
||||
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||
|
||||
@@ -274,7 +294,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
// (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
|
||||
|
||||
attribs.clear();
|
||||
makeAttribList(attribs, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
|
||||
makeAttribList(attribs, m_coreProfile, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||
}
|
||||
|
||||
@@ -316,7 +336,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
||||
[m_openGLContext release];
|
||||
|
||||
// create software GL context
|
||||
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
||||
makeAttribList(attribs, m_coreProfile, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
||||
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
||||
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
|
||||
[pixelFormat release];
|
||||
|
@@ -255,9 +255,6 @@ const bool GLXEW_ARB_create_context_robustness =
|
||||
if (m_contextMajorVersion != 0) {
|
||||
attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
|
||||
attribs[i++] = m_contextMajorVersion;
|
||||
}
|
||||
|
||||
if (m_contextMinorVersion != 0) {
|
||||
attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
|
||||
attribs[i++] = m_contextMinorVersion;
|
||||
}
|
||||
@@ -300,8 +297,8 @@ const bool GLXEW_ARB_create_context_robustness =
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Create legacy context */
|
||||
m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True);
|
||||
/* Don't create legacy context */
|
||||
fprintf(stderr, "Warning! GLX_ARB_create_context not available.\n");
|
||||
}
|
||||
|
||||
GHOST_TSuccess success;
|
||||
@@ -328,8 +325,14 @@ const bool GLXEW_ARB_create_context_robustness =
|
||||
|
||||
version = glGetString(GL_VERSION);
|
||||
|
||||
if (!version || version[0] < '2' || ((version[0] == '2') && (version[2] < '1'))) {
|
||||
fprintf(stderr, "Error! Blender requires OpenGL 2.1 to run. Try updating your drivers.\n");
|
||||
#if 0 // enable this when Blender switches to 3.3 core profile
|
||||
if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) {
|
||||
fprintf(stderr, "Error! Blender requires OpenGL 3.3 to run. Try updating your drivers.\n");
|
||||
#else
|
||||
// with Mesa, the closest thing to 3.3 compatibility profile is 3.0
|
||||
if (!version || version[0] < '3') {
|
||||
fprintf(stderr, "Error! Blender requires OpenGL 3.0 (soon 3.3) to run. Try updating your drivers.\n");
|
||||
#endif
|
||||
fflush(stderr);
|
||||
/* ugly, but we get crashes unless a whole bunch of systems are patched. */
|
||||
exit(0);
|
||||
|
@@ -962,7 +962,7 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
|
||||
strcmp(renderer, "GDI Generic") == 0) && version[0] == '1' && version[2] == '1')
|
||||
{
|
||||
MessageBox(m_hWnd, "Your system does not use 3D hardware acceleration.\n"
|
||||
"Blender requires a graphics driver with OpenGL 2.1 support.\n\n"
|
||||
"Blender requires a graphics driver with OpenGL 3.3 support.\n\n"
|
||||
"This may be caused by:\n"
|
||||
"* A missing or faulty graphics driver installation.\n"
|
||||
" Blender needs a graphics card driver to work correctly.\n"
|
||||
@@ -973,8 +973,8 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
|
||||
MB_OK | MB_ICONERROR);
|
||||
exit(0);
|
||||
}
|
||||
else if (version[0] < '2' || (version[0] == '2' && version[2] < '1')) {
|
||||
MessageBox(m_hWnd, "Blender requires a graphics driver with OpenGL 2.1 support.\n\n"
|
||||
else if (version[0] < '3' || (version[0] == '3' && version[2] < '3')) {
|
||||
MessageBox(m_hWnd, "Blender requires a graphics driver with OpenGL 3.3 support.\n\n"
|
||||
"The program will now close.",
|
||||
"Blender - Unsupported Graphics Driver!",
|
||||
MB_OK | MB_ICONERROR);
|
||||
|
@@ -46,14 +46,6 @@
|
||||
extern "C" WGLEWContext *wglewContext;
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_WGL_CONTEXT_FLAGS
|
||||
# ifdef WITH_GPU_DEBUG
|
||||
# define GHOST_OPENGL_WGL_CONTEXT_FLAGS WGL_CONTEXT_DEBUG_BIT_ARB
|
||||
# else
|
||||
# define GHOST_OPENGL_WGL_CONTEXT_FLAGS 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
|
||||
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
@@ -1086,82 +1086,23 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
||||
GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if !defined(WITH_GL_EGL)
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextCGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GL_CONTEXT_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
#else
|
||||
0, // no profile bit
|
||||
2, 1,
|
||||
#endif
|
||||
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextCGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
CGL_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_CGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context *context = new GHOST_ContextCGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
m_debug_context,
|
||||
GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_openGLView,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
|
@@ -610,97 +610,37 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
|
||||
GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if !defined(WITH_GL_EGL)
|
||||
|
||||
const int profile_mask =
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantAlphaBackground,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
3, 2,
|
||||
GHOST_OPENGL_WGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantAlphaBackground,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_WGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
#else
|
||||
# error // must specify either core or compat at build time
|
||||
#endif
|
||||
|
||||
GHOST_Context *context = new GHOST_ContextWGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantAlphaBackground,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
#if 1
|
||||
0, // profile bit
|
||||
2, 1, // GL version requested
|
||||
profile_mask,
|
||||
#if 0
|
||||
3, 3, // specific GL version requested
|
||||
// AMD gives us exactly this version
|
||||
// NVIDIA gives at least this version <-- desired behavior
|
||||
#else
|
||||
// switch to this for Blender 2.8 development
|
||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
3, 2,
|
||||
2, 1, // any GL version >= 2.1 (hopefully the latest)
|
||||
// we check later to ensure it's >= 3.3 on Windows
|
||||
// TODO(merwin): fix properly!
|
||||
// 2.1 ignores the profile bit & is incompatible with core profile
|
||||
// query version of initial dummy context, request that + profile + debug
|
||||
#endif
|
||||
(m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_hWnd,
|
||||
m_hDC,
|
||||
#if 1
|
||||
0, // profile bit
|
||||
2, 1, // GL version requested
|
||||
#else
|
||||
// switch to this for Blender 2.8 development
|
||||
EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
|
||||
3, 2,
|
||||
#endif
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
|
@@ -1306,33 +1306,24 @@ GHOST_WindowX11::
|
||||
GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if !defined(WITH_GL_EGL)
|
||||
|
||||
// During development:
|
||||
// try 3.3 compatibility profile
|
||||
// fall back to 3.0 if needed
|
||||
//
|
||||
// Final Blender 2.8:
|
||||
// try 3.3 core profile
|
||||
// no fallbacks
|
||||
|
||||
const int profile_mask =
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
3, 2,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
|
||||
2, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
#else
|
||||
# error // must specify either core or compat at build time
|
||||
#endif
|
||||
|
||||
GHOST_Context *context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
@@ -1340,58 +1331,34 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
profile_mask,
|
||||
3, 3,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3, 2,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#elif defined(WITH_GL_PROFILE_ES20)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
0, // profile bit
|
||||
2, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_ES_API);
|
||||
#elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
0, // profile bit
|
||||
0, 0,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
else {
|
||||
delete context;
|
||||
|
||||
// since that failed try 3.0 (mostly for Mesa, which doesn't implement compatibility profile)
|
||||
context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
0, // no profile bit
|
||||
3, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7.0</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
@@ -47,5 +49,7 @@
|
||||
<string>NSApplication</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@@ -1,17 +0,0 @@
|
||||
import bpy
|
||||
psys = bpy.context.particle_system
|
||||
cloth = bpy.context.particle_system.cloth
|
||||
settings = bpy.context.particle_system.cloth.settings
|
||||
collision = bpy.context.particle_system.cloth.collision_settings
|
||||
|
||||
settings.quality = 5
|
||||
settings.mass = 0.30000001192092896
|
||||
settings.bending_stiffness = 0.5
|
||||
psys.settings.bending_random = 0.0
|
||||
settings.bending_damping = 0.5
|
||||
settings.air_damping = 1.0
|
||||
settings.internal_friction = 0.0
|
||||
settings.density_target = 0.0
|
||||
settings.density_strength = 0.0
|
||||
settings.voxel_cell_size = 0.10000000149011612
|
||||
settings.pin_stiffness = 0.0
|
@@ -47,239 +47,6 @@ def object_ensure_material(obj, mat_name):
|
||||
return mat
|
||||
|
||||
|
||||
class QuickFur(Operator):
|
||||
bl_idname = "object.quick_fur"
|
||||
bl_label = "Quick Fur"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
density = EnumProperty(
|
||||
name="Fur Density",
|
||||
items=(('LIGHT', "Light", ""),
|
||||
('MEDIUM', "Medium", ""),
|
||||
('HEAVY', "Heavy", "")),
|
||||
default='MEDIUM',
|
||||
)
|
||||
view_percentage = IntProperty(
|
||||
name="View %",
|
||||
min=1, max=100,
|
||||
soft_min=1, soft_max=100,
|
||||
default=10,
|
||||
)
|
||||
length = FloatProperty(
|
||||
name="Length",
|
||||
min=0.001, max=100,
|
||||
soft_min=0.01, soft_max=10,
|
||||
default=0.1,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
fake_context = context.copy()
|
||||
mesh_objects = [obj for obj in context.selected_objects
|
||||
if obj.type == 'MESH' and obj.mode == 'OBJECT']
|
||||
|
||||
if not mesh_objects:
|
||||
self.report({'ERROR'}, "Select at least one mesh object")
|
||||
return {'CANCELLED'}
|
||||
|
||||
mat = bpy.data.materials.new("Fur Material")
|
||||
mat.strand.tip_size = 0.25
|
||||
mat.strand.blend_distance = 0.5
|
||||
|
||||
for obj in mesh_objects:
|
||||
fake_context["object"] = obj
|
||||
bpy.ops.object.particle_system_add(fake_context)
|
||||
|
||||
psys = obj.particle_systems[-1]
|
||||
psys.settings.type = 'HAIR'
|
||||
|
||||
if self.density == 'LIGHT':
|
||||
psys.settings.count = 100
|
||||
elif self.density == 'MEDIUM':
|
||||
psys.settings.count = 1000
|
||||
elif self.density == 'HEAVY':
|
||||
psys.settings.count = 10000
|
||||
|
||||
psys.settings.child_nbr = self.view_percentage
|
||||
psys.settings.hair_length = self.length
|
||||
psys.settings.use_strand_primitive = True
|
||||
psys.settings.use_hair_bspline = True
|
||||
psys.settings.child_type = 'INTERPOLATED'
|
||||
|
||||
obj.data.materials.append(mat)
|
||||
psys.settings.material = len(obj.data.materials)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class QuickExplode(Operator):
|
||||
bl_idname = "object.quick_explode"
|
||||
bl_label = "Quick Explode"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
style = EnumProperty(
|
||||
name="Explode Style",
|
||||
items=(('EXPLODE', "Explode", ""),
|
||||
('BLEND', "Blend", "")),
|
||||
default='EXPLODE',
|
||||
)
|
||||
amount = IntProperty(
|
||||
name="Amount of pieces",
|
||||
min=2, max=10000,
|
||||
soft_min=2, soft_max=10000,
|
||||
default=100,
|
||||
)
|
||||
frame_duration = IntProperty(
|
||||
name="Duration",
|
||||
min=1, max=300000,
|
||||
soft_min=1, soft_max=10000,
|
||||
default=50,
|
||||
)
|
||||
|
||||
frame_start = IntProperty(
|
||||
name="Start Frame",
|
||||
min=1, max=300000,
|
||||
soft_min=1, soft_max=10000,
|
||||
default=1,
|
||||
)
|
||||
frame_end = IntProperty(
|
||||
name="End Frame",
|
||||
min=1, max=300000,
|
||||
soft_min=1, soft_max=10000,
|
||||
default=10,
|
||||
)
|
||||
|
||||
velocity = FloatProperty(
|
||||
name="Outwards Velocity",
|
||||
min=0, max=300000,
|
||||
soft_min=0, soft_max=10,
|
||||
default=1,
|
||||
)
|
||||
|
||||
fade = BoolProperty(
|
||||
name="Fade",
|
||||
description="Fade the pieces over time",
|
||||
default=True,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
fake_context = context.copy()
|
||||
obj_act = context.active_object
|
||||
|
||||
if obj_act is None or obj_act.type != 'MESH':
|
||||
self.report({'ERROR'}, "Active object is not a mesh")
|
||||
return {'CANCELLED'}
|
||||
|
||||
mesh_objects = [obj for obj in context.selected_objects
|
||||
if obj.type == 'MESH' and obj != obj_act]
|
||||
mesh_objects.insert(0, obj_act)
|
||||
|
||||
if self.style == 'BLEND' and len(mesh_objects) != 2:
|
||||
self.report({'ERROR'}, "Select two mesh objects")
|
||||
self.style = 'EXPLODE'
|
||||
return {'CANCELLED'}
|
||||
elif not mesh_objects:
|
||||
self.report({'ERROR'}, "Select at least one mesh object")
|
||||
return {'CANCELLED'}
|
||||
|
||||
for obj in mesh_objects:
|
||||
if obj.particle_systems:
|
||||
self.report({'ERROR'},
|
||||
"Object %r already has a "
|
||||
"particle system" % obj.name)
|
||||
|
||||
return {'CANCELLED'}
|
||||
|
||||
if self.fade:
|
||||
tex = bpy.data.textures.new("Explode fade", 'BLEND')
|
||||
tex.use_color_ramp = True
|
||||
|
||||
if self.style == 'BLEND':
|
||||
tex.color_ramp.elements[0].position = 0.333
|
||||
tex.color_ramp.elements[1].position = 0.666
|
||||
|
||||
tex.color_ramp.elements[0].color[3] = 1.0
|
||||
tex.color_ramp.elements[1].color[3] = 0.0
|
||||
|
||||
if self.style == 'BLEND':
|
||||
from_obj = mesh_objects[1]
|
||||
to_obj = mesh_objects[0]
|
||||
|
||||
for obj in mesh_objects:
|
||||
fake_context["object"] = obj
|
||||
bpy.ops.object.particle_system_add(fake_context)
|
||||
|
||||
settings = obj.particle_systems[-1].settings
|
||||
settings.count = self.amount
|
||||
settings.frame_start = self.frame_start
|
||||
settings.frame_end = self.frame_end - self.frame_duration
|
||||
settings.lifetime = self.frame_duration
|
||||
settings.normal_factor = self.velocity
|
||||
settings.render_type = 'NONE'
|
||||
|
||||
explode = obj.modifiers.new(name='Explode', type='EXPLODE')
|
||||
explode.use_edge_cut = True
|
||||
|
||||
if self.fade:
|
||||
explode.show_dead = False
|
||||
uv = obj.data.uv_textures.new("Explode fade")
|
||||
explode.particle_uv = uv.name
|
||||
|
||||
mat = object_ensure_material(obj, "Explode Fade")
|
||||
|
||||
mat.use_transparency = True
|
||||
mat.use_transparent_shadows = True
|
||||
mat.alpha = 0.0
|
||||
mat.specular_alpha = 0.0
|
||||
|
||||
tex_slot = mat.texture_slots.add()
|
||||
|
||||
tex_slot.texture = tex
|
||||
tex_slot.texture_coords = 'UV'
|
||||
tex_slot.uv_layer = uv.name
|
||||
|
||||
tex_slot.use_map_alpha = True
|
||||
|
||||
if self.style == 'BLEND':
|
||||
if obj == to_obj:
|
||||
tex_slot.alpha_factor = -1.0
|
||||
elem = tex.color_ramp.elements[1]
|
||||
else:
|
||||
elem = tex.color_ramp.elements[0]
|
||||
# Keep already defined alpha!
|
||||
elem.color[:3] = mat.diffuse_color
|
||||
else:
|
||||
tex_slot.use_map_color_diffuse = False
|
||||
|
||||
if self.style == 'BLEND':
|
||||
settings.physics_type = 'KEYED'
|
||||
settings.use_emit_random = False
|
||||
settings.rotation_mode = 'NOR'
|
||||
|
||||
psys = obj.particle_systems[-1]
|
||||
|
||||
fake_context["particle_system"] = obj.particle_systems[-1]
|
||||
bpy.ops.particle.new_target(fake_context)
|
||||
bpy.ops.particle.new_target(fake_context)
|
||||
|
||||
if obj == from_obj:
|
||||
psys.targets[1].object = to_obj
|
||||
else:
|
||||
psys.targets[0].object = from_obj
|
||||
settings.normal_factor = -self.velocity
|
||||
explode.show_unborn = False
|
||||
explode.show_dead = True
|
||||
else:
|
||||
settings.factor_random = self.velocity
|
||||
settings.angular_velocity_factor = self.velocity / 10.0
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.frame_start = context.scene.frame_current
|
||||
self.frame_end = self.frame_start + self.frame_duration
|
||||
return self.execute(context)
|
||||
|
||||
|
||||
def obj_bb_minmax(obj, min_co, max_co):
|
||||
for i in range(0, 8):
|
||||
bb_vec = obj.matrix_world * Vector(obj.bound_box[i])
|
||||
|
@@ -384,36 +384,6 @@ class AddPresetFluid(AddPresetBase, Operator):
|
||||
preset_subdir = "fluid"
|
||||
|
||||
|
||||
class AddPresetHairDynamics(AddPresetBase, Operator):
|
||||
"""Add or remove a Hair Dynamics Preset"""
|
||||
bl_idname = "particle.hair_dynamics_preset_add"
|
||||
bl_label = "Add Hair Dynamics Preset"
|
||||
preset_menu = "PARTICLE_MT_hair_dynamics_presets"
|
||||
|
||||
preset_defines = [
|
||||
"psys = bpy.context.particle_system",
|
||||
"cloth = bpy.context.particle_system.cloth",
|
||||
"settings = bpy.context.particle_system.cloth.settings",
|
||||
"collision = bpy.context.particle_system.cloth.collision_settings",
|
||||
]
|
||||
|
||||
preset_subdir = "hair_dynamics"
|
||||
|
||||
preset_values = [
|
||||
"settings.quality",
|
||||
"settings.mass",
|
||||
"settings.bending_stiffness",
|
||||
"psys.settings.bending_random",
|
||||
"settings.bending_damping",
|
||||
"settings.air_damping",
|
||||
"settings.internal_friction",
|
||||
"settings.density_target",
|
||||
"settings.density_strength",
|
||||
"settings.voxel_cell_size",
|
||||
"settings.pin_stiffness",
|
||||
]
|
||||
|
||||
|
||||
class AddPresetSunSky(AddPresetBase, Operator):
|
||||
"""Add or remove a Sky & Atmosphere Preset"""
|
||||
bl_idname = "lamp.sunsky_preset_add"
|
||||
|
@@ -199,8 +199,6 @@ class VIEW3D_OT_select_or_deselect_all(Operator):
|
||||
bpy.ops.armature.select_all(action='DESELECT')
|
||||
elif active_object.mode == 'POSE':
|
||||
bpy.ops.pose.select_all(action='DESELECT')
|
||||
elif active_object.mode == 'PARTICLE_EDIT':
|
||||
bpy.ops.particle.select_all(action='DESELECT')
|
||||
else:
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
else:
|
||||
|
@@ -47,7 +47,6 @@ _modules = [
|
||||
"properties_object",
|
||||
"properties_paint_common",
|
||||
"properties_grease_pencil_common",
|
||||
"properties_particle",
|
||||
"properties_physics_cloth",
|
||||
"properties_physics_common",
|
||||
"properties_physics_dynamicpaint",
|
||||
|
@@ -388,6 +388,52 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
|
||||
|
||||
self.layout.template_curve_mapping(lamp, "falloff_curve", use_negative_slope=True)
|
||||
|
||||
class DATA_PT_viewport(DataButtonsPanel, Panel):
|
||||
bl_label = "Viewport Settings"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
lamp = context.lamp
|
||||
engine = context.scene.render.engine
|
||||
|
||||
return lamp and (engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(lamp, "use_specular")
|
||||
col.prop(lamp, "use_diffuse")
|
||||
|
||||
|
||||
if lamp.type in {'SPOT','SUN','AREA'}:
|
||||
|
||||
col = split.column()
|
||||
col.prop(lamp, "use_shadow", text="Use Shadow")
|
||||
|
||||
layout.label(text="Shadow Settings:")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = lamp.use_shadow
|
||||
col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True)
|
||||
col.prop(lamp, "shadow_buffer_size", text="Size")
|
||||
col.prop(lamp, "shadow_buffer_bias", text="Bias")
|
||||
col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.active = lamp.use_shadow
|
||||
row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
|
||||
row.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
|
||||
|
||||
if lamp.type == 'SUN':
|
||||
row = layout.row()
|
||||
row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
|
||||
|
||||
|
||||
class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
@@ -688,40 +688,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
|
||||
col = split.column()
|
||||
|
||||
def PARTICLE_INSTANCE(self, layout, ob, md):
|
||||
layout.prop(md, "object")
|
||||
layout.prop(md, "particle_system_index", text="Particle System")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.label(text="Create From:")
|
||||
col.prop(md, "use_normal")
|
||||
col.prop(md, "use_children")
|
||||
col.prop(md, "use_size")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Show Particles When:")
|
||||
col.prop(md, "show_alive")
|
||||
col.prop(md, "show_unborn")
|
||||
col.prop(md, "show_dead")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(md, "use_path", text="Create Along Paths")
|
||||
|
||||
split = layout.split()
|
||||
split.active = md.use_path
|
||||
col = split.column()
|
||||
col.row().prop(md, "axis", expand=True)
|
||||
col.prop(md, "use_preserve_shape")
|
||||
|
||||
col = split.column()
|
||||
col.prop(md, "position", slider=True)
|
||||
col.prop(md, "random_position", text="Random", slider=True)
|
||||
|
||||
def PARTICLE_SYSTEM(self, layout, ob, md):
|
||||
layout.label(text="Settings can be found inside the Particle context")
|
||||
|
||||
def SCREW(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
|
@@ -323,6 +323,69 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
|
||||
layout.prop(ob, "use_extra_recalc_data")
|
||||
|
||||
|
||||
class OBJECT_PT_probe_settings(ObjectButtonsPanel, Panel):
|
||||
bl_label = "Viewport Probe"
|
||||
bl_context = "object"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.object)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
layout.prop(ob, "probe_type", expand=True)
|
||||
|
||||
if ob.probe_type == 'OBJECT':
|
||||
layout.prop(ob, "probe_object")
|
||||
|
||||
elif ob.probe_type in {'CUBE', 'PLANE'}:
|
||||
split = layout.split()
|
||||
|
||||
layout.operator("object.probe_update", text="Update Probe", icon="FILE_REFRESH").type = 'ACTIVE_PROBE'
|
||||
|
||||
col = split.column()
|
||||
col.prop(ob, "probe_refresh_auto", text="Auto Refresh")
|
||||
col.prop(ob, "probe_compute_sh")
|
||||
col = split.column()
|
||||
col.prop(ob, "probe_refresh_double", text="Double Refresh")
|
||||
col.prop(ob, "probe_use_layers")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Quality:")
|
||||
col.prop(ob, "probe_size", text="Reflection")
|
||||
col.prop(ob, "probe_sh_quality", text="Diffuse")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Clipping:")
|
||||
|
||||
if ob.probe_type == 'PLANE':
|
||||
col.prop(ob, "probe_clip_bias", text="Bias")
|
||||
else :
|
||||
col.prop(ob, "probe_clip_start", text="Start")
|
||||
|
||||
col.prop(ob, "probe_clip_end", text="End")
|
||||
|
||||
if ob.probe_type == 'PLANE':
|
||||
row = layout.row()
|
||||
row.prop(ob, "probe_reflection_plane", text="Reflection Plane")
|
||||
layout.prop(ob, "probe_object", text="Default Cube Probe")
|
||||
|
||||
elif ob.probe_type == 'CUBE':
|
||||
row = layout.row()
|
||||
row.prop(ob, "probe_parallax_type", text="Parallax")
|
||||
|
||||
row = layout.row()
|
||||
row.active = (ob.probe_parallax_type in {"ELLIPSOID", "BOX"})
|
||||
row.prop(ob, "probe_parallax_volume", text="Parallax Volume")
|
||||
|
||||
|
||||
from bl_ui.properties_animviz import (
|
||||
MotionPathButtonsPanel,
|
||||
OnionSkinButtonsPanel,
|
||||
|
@@ -40,8 +40,6 @@ class UnifiedPaintPanel:
|
||||
return toolsettings.image_paint
|
||||
|
||||
return None
|
||||
elif context.particle_edit_object:
|
||||
return toolsettings.particle_edit
|
||||
|
||||
return None
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -21,13 +21,13 @@ import bpy
|
||||
from bpy.types import Menu, Panel
|
||||
|
||||
from bl_ui.properties_physics_common import (
|
||||
point_cache_ui,
|
||||
effector_weights_ui,
|
||||
)
|
||||
|
||||
|
||||
def cloth_panel_enabled(md):
|
||||
return md.point_cache.is_baked is False
|
||||
return True
|
||||
#return md.point_cache.is_baked is False
|
||||
|
||||
|
||||
class CLOTH_MT_presets(Menu):
|
||||
@@ -64,6 +64,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
|
||||
col = split.column()
|
||||
|
||||
split.label(text="Presets:")
|
||||
sub = split.row(align=True)
|
||||
sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
|
||||
@@ -130,16 +132,6 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
|
||||
sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
|
||||
|
||||
|
||||
class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cloth Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
def draw(self, context):
|
||||
md = context.cloth
|
||||
point_cache_ui(self, context, md.point_cache, cloth_panel_enabled(md), 'CLOTH')
|
||||
|
||||
|
||||
class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cloth Collision"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
@@ -98,113 +98,6 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
||||
'CONSTRAINT') # RB_TODO needs better icon
|
||||
|
||||
|
||||
# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc
|
||||
|
||||
def point_cache_ui(self, context, cache, enabled, cachetype):
|
||||
layout = self.layout
|
||||
|
||||
layout.context_pointer_set("point_cache", cache)
|
||||
|
||||
if not cachetype == 'RIGID_BODY':
|
||||
row = layout.row()
|
||||
row.template_list("UI_UL_list", "point_caches", cache, "point_caches",
|
||||
cache.point_caches, "active_index", rows=1)
|
||||
col = row.column(align=True)
|
||||
col.operator("ptcache.add", icon='ZOOMIN', text="")
|
||||
col.operator("ptcache.remove", icon='ZOOMOUT', text="")
|
||||
|
||||
row = layout.row()
|
||||
if cachetype in {'PSYS', 'HAIR', 'SMOKE'}:
|
||||
row.prop(cache, "use_external")
|
||||
|
||||
if cachetype == 'SMOKE':
|
||||
row.prop(cache, "use_library_path", "Use Lib Path")
|
||||
|
||||
if cache.use_external:
|
||||
split = layout.split(percentage=0.35)
|
||||
col = split.column()
|
||||
col.label(text="Index Number:")
|
||||
col.label(text="File Path:")
|
||||
|
||||
col = split.column()
|
||||
col.prop(cache, "index", text="")
|
||||
col.prop(cache, "filepath", text="")
|
||||
|
||||
cache_info = cache.info
|
||||
if cache_info:
|
||||
layout.label(text=cache_info)
|
||||
else:
|
||||
if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}:
|
||||
if not bpy.data.is_saved:
|
||||
layout.label(text="Cache is disabled until the file is saved")
|
||||
layout.enabled = False
|
||||
|
||||
if not cache.use_external or cachetype == 'SMOKE':
|
||||
row = layout.row(align=True)
|
||||
|
||||
if cachetype not in {'PSYS', 'DYNAMIC_PAINT'}:
|
||||
row.enabled = enabled
|
||||
row.prop(cache, "frame_start")
|
||||
row.prop(cache, "frame_end")
|
||||
if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
|
||||
row.prop(cache, "frame_step")
|
||||
|
||||
if cachetype != 'SMOKE':
|
||||
layout.label(text=cache.info)
|
||||
|
||||
can_bake = True
|
||||
|
||||
if cachetype not in {'SMOKE', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
|
||||
split = layout.split()
|
||||
split.enabled = enabled and bpy.data.is_saved
|
||||
|
||||
col = split.column()
|
||||
col.prop(cache, "use_disk_cache")
|
||||
|
||||
col = split.column()
|
||||
col.active = cache.use_disk_cache
|
||||
col.prop(cache, "use_library_path", "Use Lib Path")
|
||||
|
||||
row = layout.row()
|
||||
row.enabled = enabled and bpy.data.is_saved
|
||||
row.active = cache.use_disk_cache
|
||||
row.label(text="Compression:")
|
||||
row.prop(cache, "compression", expand=True)
|
||||
|
||||
layout.separator()
|
||||
|
||||
if cache.id_data.library and not cache.use_disk_cache:
|
||||
can_bake = False
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Linked object baking requires Disk Cache to be enabled", icon='INFO')
|
||||
else:
|
||||
layout.separator()
|
||||
|
||||
split = layout.split()
|
||||
split.active = can_bake
|
||||
|
||||
col = split.column()
|
||||
|
||||
if cache.is_baked is True:
|
||||
col.operator("ptcache.free_bake", text="Free Bake")
|
||||
else:
|
||||
col.operator("ptcache.bake", text="Bake").bake = True
|
||||
|
||||
sub = col.row()
|
||||
sub.enabled = (cache.is_frame_skip or cache.is_outdated) and enabled
|
||||
sub.operator("ptcache.bake", text="Calculate To Frame").bake = False
|
||||
|
||||
sub = col.column()
|
||||
sub.enabled = enabled
|
||||
sub.operator("ptcache.bake_from_cache", text="Current Cache to Bake")
|
||||
|
||||
col = split.column()
|
||||
col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True
|
||||
col.operator("ptcache.free_bake_all", text="Free All Bakes")
|
||||
col.operator("ptcache.bake_all", text="Update All To Frame").bake = False
|
||||
|
||||
|
||||
def effector_weights_ui(self, context, weights, weight_type):
|
||||
layout = self.layout
|
||||
|
||||
|
@@ -21,7 +21,6 @@ import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
from bl_ui.properties_physics_common import (
|
||||
point_cache_ui,
|
||||
effector_weights_ui,
|
||||
)
|
||||
|
||||
@@ -125,10 +124,8 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
|
||||
|
||||
col = split.column()
|
||||
if not use_shading_nodes:
|
||||
sub = col.column()
|
||||
sub.active = (brush.paint_source != 'PARTICLE_SYSTEM')
|
||||
sub.prop(brush, "use_material")
|
||||
if brush.use_material and brush.paint_source != 'PARTICLE_SYSTEM' and not use_shading_nodes:
|
||||
col.prop(brush, "use_material")
|
||||
if brush.use_material and not use_shading_nodes:
|
||||
col.prop(brush, "material", text="")
|
||||
col.prop(brush, "paint_alpha", text="Alpha Factor")
|
||||
else:
|
||||
@@ -393,29 +390,6 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
|
||||
row.prop(surface, "shrink_speed")
|
||||
|
||||
|
||||
class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dynamic Paint Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
md = context.dynamic_paint
|
||||
rd = context.scene.render
|
||||
return (md and
|
||||
md.ui_type == 'CANVAS' and
|
||||
md.canvas_settings and
|
||||
md.canvas_settings.canvas_surfaces.active and
|
||||
md.canvas_settings.canvas_surfaces.active.is_cache_user and
|
||||
(rd.engine in cls.COMPAT_ENGINES))
|
||||
|
||||
def draw(self, context):
|
||||
surface = context.dynamic_paint.canvas_settings.canvas_surfaces.active
|
||||
cache = surface.point_cache
|
||||
|
||||
point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
|
||||
|
||||
|
||||
class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dynamic Paint Source"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
@@ -436,16 +410,6 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.prop(brush, "paint_source")
|
||||
|
||||
if brush.paint_source == 'PARTICLE_SYSTEM':
|
||||
col.prop_search(brush, "particle_system", ob, "particle_systems", text="")
|
||||
if brush.particle_system:
|
||||
col.label(text="Particle effect:")
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_particle_radius
|
||||
sub.prop(brush, "solid_radius", text="Solid Radius")
|
||||
col.prop(brush, "use_particle_radius", text="Use Particle's Radius")
|
||||
col.prop(brush, "smooth_radius", text="Smooth radius")
|
||||
|
||||
if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
|
||||
col.prop(brush, "paint_distance", text="Paint Distance")
|
||||
split = layout.row().split(percentage=0.4)
|
||||
|
@@ -21,7 +21,6 @@ import bpy
|
||||
from bpy.types import Panel
|
||||
|
||||
from bl_ui.properties_physics_common import (
|
||||
point_cache_ui,
|
||||
effector_weights_ui,
|
||||
)
|
||||
|
||||
@@ -55,8 +54,6 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
|
||||
|
||||
split = layout.split()
|
||||
|
||||
split.enabled = not domain.point_cache.is_baked
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Resolution:")
|
||||
col.prop(domain, "resolution_max", text="Divisions")
|
||||
@@ -87,14 +84,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.label(text="Flow Source:")
|
||||
col.prop(flow, "smoke_flow_source", expand=False, text="")
|
||||
if flow.smoke_flow_source == 'PARTICLES':
|
||||
col.label(text="Particle System:")
|
||||
col.prop_search(flow, "particle_system", ob, "particle_systems", text="")
|
||||
col.prop(flow, "use_particle_size", text="Set Size")
|
||||
sub = col.column()
|
||||
sub.active = flow.use_particle_size
|
||||
sub.prop(flow, "particle_size")
|
||||
else:
|
||||
if flow.smoke_flow_source == 'MESH':
|
||||
col.prop(flow, "surface_distance")
|
||||
col.prop(flow, "volume_density")
|
||||
|
||||
@@ -179,7 +169,6 @@ class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel):
|
||||
domain = context.smoke.domain_settings
|
||||
|
||||
split = layout.split()
|
||||
split.enabled = not domain.point_cache.is_baked
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Reaction:")
|
||||
@@ -216,7 +205,6 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
|
||||
layout.active = domain.use_adaptive_domain
|
||||
|
||||
split = layout.split()
|
||||
split.enabled = (not domain.point_cache.is_baked)
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Resolution:")
|
||||
@@ -252,7 +240,6 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
|
||||
layout.active = md.use_high_resolution
|
||||
|
||||
split = layout.split()
|
||||
split.enabled = not md.point_cache.is_baked
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Resolution:")
|
||||
@@ -316,10 +303,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
|
||||
|
||||
layout.prop(domain, "cache_file_format")
|
||||
|
||||
if cache_file_format == 'POINTCACHE':
|
||||
layout.label(text="Compression:")
|
||||
layout.prop(domain, "point_cache_compress_type", expand=True)
|
||||
elif cache_file_format == 'OPENVDB':
|
||||
if cache_file_format == 'OPENVDB':
|
||||
if not bpy.app.build_options.openvdb:
|
||||
layout.label("Built without OpenVDB support")
|
||||
return
|
||||
@@ -330,9 +314,6 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
|
||||
row.label("Data Depth:")
|
||||
row.prop(domain, "data_depth", expand=True, text="Data Depth")
|
||||
|
||||
cache = domain.point_cache
|
||||
point_cache_ui(self, context, cache, (cache.is_baked is False), 'SMOKE')
|
||||
|
||||
|
||||
class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Smoke Field Weights"
|
||||
|
@@ -21,13 +21,13 @@ import bpy
|
||||
from bpy.types import Panel
|
||||
|
||||
from bl_ui.properties_physics_common import (
|
||||
point_cache_ui,
|
||||
effector_weights_ui,
|
||||
)
|
||||
|
||||
|
||||
def softbody_panel_enabled(md):
|
||||
return (md.point_cache.is_baked is False)
|
||||
return True
|
||||
#return (md.point_cache.is_baked is False)
|
||||
|
||||
|
||||
class PhysicButtonsPanel:
|
||||
@@ -71,16 +71,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
|
||||
layout.prop(softbody, "collision_group")
|
||||
|
||||
|
||||
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Soft Body Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
point_cache_ui(self, context, md.point_cache, softbody_panel_enabled(md), 'SOFTBODY')
|
||||
|
||||
|
||||
class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Soft Body Goal"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
@@ -27,7 +27,6 @@ from bpy.types import (
|
||||
from rna_prop_ui import PropertyPanel
|
||||
|
||||
from bl_ui.properties_physics_common import (
|
||||
point_cache_ui,
|
||||
effector_weights_ui,
|
||||
)
|
||||
|
||||
@@ -371,24 +370,6 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel):
|
||||
col.prop(rbw, "solver_iterations", text="Solver Iterations")
|
||||
|
||||
|
||||
class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel):
|
||||
bl_label = "Rigid Body Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
rd = context.scene.render
|
||||
scene = context.scene
|
||||
return scene and scene.rigidbody_world and (rd.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
rbw = scene.rigidbody_world
|
||||
|
||||
point_cache_ui(self, context, rbw.point_cache, rbw.point_cache.is_baked is False and rbw.enabled, 'RIGID_BODY')
|
||||
|
||||
|
||||
class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel):
|
||||
bl_label = "Rigid Body Field Weights"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -427,12 +408,10 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.label(text="Viewport:")
|
||||
col.prop(rd, "simplify_subdivision", text="Subdivision")
|
||||
col.prop(rd, "simplify_child_particles", text="Child Particles")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Render:")
|
||||
col.prop(rd, "simplify_subdivision_render", text="Subdivision")
|
||||
col.prop(rd, "simplify_child_particles_render", text="Child Particles")
|
||||
col.prop(rd, "simplify_shadow_samples", text="Shadow Samples")
|
||||
col.prop(rd, "simplify_ao_sss", text="AO and SSS")
|
||||
col.prop(rd, "use_simplify_triangulate")
|
||||
|
@@ -26,7 +26,6 @@ from bpy.types import (
|
||||
Lamp,
|
||||
Material,
|
||||
Object,
|
||||
ParticleSettings,
|
||||
Texture,
|
||||
World,
|
||||
)
|
||||
@@ -101,9 +100,6 @@ def context_tex_datablock(context):
|
||||
if idblock:
|
||||
return idblock
|
||||
|
||||
if context.particle_system:
|
||||
idblock = context.particle_system.settings
|
||||
|
||||
return idblock
|
||||
|
||||
|
||||
@@ -142,8 +138,6 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
|
||||
context.lamp or
|
||||
context.texture or
|
||||
context.line_style or
|
||||
context.particle_system or
|
||||
isinstance(context.space_data.pin_id, ParticleSettings) or
|
||||
context.texture_user) and
|
||||
(engine in cls.COMPAT_ENGINES))
|
||||
|
||||
@@ -811,18 +805,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
if pd.point_source == 'PARTICLE_SYSTEM':
|
||||
col.label(text="Object:")
|
||||
col.prop(pd, "object", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.enabled = bool(pd.object)
|
||||
if pd.object:
|
||||
sub.label(text="System:")
|
||||
sub.prop_search(pd, "particle_system", pd.object, "particle_systems", text="")
|
||||
sub.label(text="Cache:")
|
||||
sub.prop(pd, "particle_cache_space", text="")
|
||||
else:
|
||||
if pd.point_source == 'OBJECT':
|
||||
col.label(text="Object:")
|
||||
col.prop(pd, "object", text="")
|
||||
col.label(text="Cache:")
|
||||
@@ -831,13 +814,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
|
||||
col.separator()
|
||||
|
||||
col.label(text="Color Source:")
|
||||
if pd.point_source == 'PARTICLE_SYSTEM':
|
||||
col.prop(pd, "particle_color_source", text="")
|
||||
if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}:
|
||||
col.prop(pd, "speed_scale")
|
||||
if pd.particle_color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}:
|
||||
layout.template_color_ramp(pd, "color_ramp", expand=True)
|
||||
else:
|
||||
if pd.point_source == 'OBJECT':
|
||||
col.prop(pd, "vertex_color_source", text="")
|
||||
if pd.vertex_color_source == 'VERTEX_COLOR':
|
||||
if pd.object and pd.object.data:
|
||||
@@ -854,8 +831,6 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
|
||||
col.prop(pd, "falloff", text="")
|
||||
if pd.falloff == 'SOFT':
|
||||
col.prop(pd, "falloff_soft")
|
||||
if pd.falloff == 'PARTICLE_VELOCITY':
|
||||
col.prop(pd, "falloff_speed_scale")
|
||||
|
||||
col.prop(pd, "use_falloff_curve")
|
||||
|
||||
@@ -1147,35 +1122,6 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
|
||||
col = split.column()
|
||||
factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up")
|
||||
factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down")
|
||||
elif isinstance(idblock, ParticleSettings):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="General:")
|
||||
factor_but(col, "use_map_time", "time_factor", "Time")
|
||||
factor_but(col, "use_map_life", "life_factor", "Lifetime")
|
||||
factor_but(col, "use_map_density", "density_factor", "Density")
|
||||
factor_but(col, "use_map_size", "size_factor", "Size")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics:")
|
||||
factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
|
||||
factor_but(col, "use_map_damp", "damp_factor", "Damp")
|
||||
factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
|
||||
factor_but(col, "use_map_field", "field_factor", "Force Fields")
|
||||
|
||||
layout.label(text="Hair:")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, "use_map_length", "length_factor", "Length")
|
||||
factor_but(col, "use_map_clump", "clump_factor", "Clump")
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude")
|
||||
factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency")
|
||||
factor_but(col, "use_map_rough", "rough_factor", "Rough")
|
||||
|
||||
elif isinstance(idblock, FreestyleLineStyle):
|
||||
split = layout.split()
|
||||
@@ -1187,18 +1133,17 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
|
||||
|
||||
layout.separator()
|
||||
|
||||
if not isinstance(idblock, ParticleSettings):
|
||||
split = layout.split()
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex, "blend_type", text="Blend")
|
||||
col.prop(tex, "use_rgb_to_intensity")
|
||||
# color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
|
||||
col.prop(tex, "color", text="")
|
||||
col = split.column()
|
||||
col.prop(tex, "blend_type", text="Blend")
|
||||
col.prop(tex, "use_rgb_to_intensity")
|
||||
# color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
|
||||
col.prop(tex, "color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex, "invert", text="Negative")
|
||||
col.prop(tex, "use_stencil")
|
||||
col = split.column()
|
||||
col.prop(tex, "invert", text="Negative")
|
||||
col.prop(tex, "use_stencil")
|
||||
|
||||
if isinstance(idblock, Material) or isinstance(idblock, World):
|
||||
col.prop(tex, "default_value", text="DVar", slider=True)
|
||||
|
@@ -243,6 +243,30 @@ class WORLD_PT_mist(WorldButtonsPanel, Panel):
|
||||
layout.prop(world.mist_settings, "falloff")
|
||||
|
||||
|
||||
class WORLD_PT_probe_settings(WorldButtonsPanel, Panel):
|
||||
bl_label = "Viewport Probe"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(world, "probe_refresh_auto")
|
||||
col = split.column()
|
||||
col.prop(world, "probe_compute_sh")
|
||||
|
||||
layout.operator("world.probe_update", text="Update Probe", icon="FILE_REFRESH")
|
||||
|
||||
layout.label(text="Quality:")
|
||||
row = layout.row(align=True)
|
||||
row.prop(world, "probe_size", text="Reflection")
|
||||
row.prop(world, "probe_sh_quality", text="Diffuse")
|
||||
|
||||
|
||||
class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
_context_path = "world"
|
||||
|
@@ -92,8 +92,6 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
|
||||
row.prop(dopesheet, "show_lattices", text="")
|
||||
if bpy.data.armatures:
|
||||
row.prop(dopesheet, "show_armatures", text="")
|
||||
if bpy.data.particles:
|
||||
row.prop(dopesheet, "show_particles", text="")
|
||||
if bpy.data.speakers:
|
||||
row.prop(dopesheet, "show_speakers", text="")
|
||||
if bpy.data.linestyles:
|
||||
|
@@ -171,7 +171,6 @@ class TIME_MT_cache(Menu):
|
||||
col = layout.column()
|
||||
col.enabled = st.show_cache
|
||||
col.prop(st, "cache_softbody")
|
||||
col.prop(st, "cache_particles")
|
||||
col.prop(st, "cache_cloth")
|
||||
col.prop(st, "cache_smoke")
|
||||
col.prop(st, "cache_dynamicpaint")
|
||||
|
@@ -371,7 +371,6 @@ class USERPREF_PT_edit(Panel):
|
||||
col.prop(edit, "use_duplicate_texture", text="Texture")
|
||||
#col.prop(edit, "use_duplicate_fcurve", text="F-Curve")
|
||||
col.prop(edit, "use_duplicate_action", text="Action")
|
||||
col.prop(edit, "use_duplicate_particle", text="Particle")
|
||||
|
||||
|
||||
class USERPREF_PT_system(Panel):
|
||||
|
@@ -49,12 +49,9 @@ class VIEW3D_HT_header(Header):
|
||||
|
||||
if obj:
|
||||
mode = obj.mode
|
||||
# Particle edit
|
||||
if mode == 'PARTICLE_EDIT':
|
||||
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
|
||||
|
||||
# Occlude geometry
|
||||
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
|
||||
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'EDIT' and obj.type == 'MESH')) or
|
||||
(mode == 'WEIGHT_PAINT')):
|
||||
row.prop(view, "use_occlude_geometry", text="")
|
||||
|
||||
@@ -64,7 +61,7 @@ class VIEW3D_HT_header(Header):
|
||||
row.prop(toolsettings, "proportional_edit", icon_only=True)
|
||||
if toolsettings.proportional_edit != 'DISABLED':
|
||||
row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
|
||||
elif mode in {'EDIT', 'PARTICLE_EDIT'}:
|
||||
elif mode == 'EDIT':
|
||||
row = layout.row(align=True)
|
||||
row.prop(toolsettings, "proportional_edit", icon_only=True)
|
||||
if toolsettings.proportional_edit != 'DISABLED':
|
||||
@@ -703,35 +700,6 @@ class VIEW3D_MT_select_pose(Menu):
|
||||
layout.operator("object.select_pattern", text="Select Pattern...")
|
||||
|
||||
|
||||
class VIEW3D_MT_select_particle(Menu):
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("view3d.select_border")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_all").action = 'TOGGLE'
|
||||
layout.operator("particle.select_linked")
|
||||
layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_more")
|
||||
layout.operator("particle.select_less")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_random")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_roots", text="Roots")
|
||||
layout.operator("particle.select_tips", text="Tips")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_select_similar(Menu):
|
||||
bl_label = "Select Similar"
|
||||
|
||||
@@ -1922,87 +1890,8 @@ class VIEW3D_MT_hide_mask(Menu):
|
||||
props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
|
||||
|
||||
|
||||
# ********** Particle menu **********
|
||||
|
||||
|
||||
class VIEW3D_MT_particle(Menu):
|
||||
bl_label = "Particle"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
particle_edit = context.tool_settings.particle_edit
|
||||
|
||||
layout.operator("ed.undo")
|
||||
layout.operator("ed.redo")
|
||||
layout.operator("ed.undo_history")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.mirror")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.remove_doubles")
|
||||
layout.operator("particle.delete")
|
||||
|
||||
if particle_edit.select_mode == 'POINT':
|
||||
layout.operator("particle.subdivide")
|
||||
|
||||
layout.operator("particle.unify_length")
|
||||
layout.operator("particle.rekey")
|
||||
layout.operator("particle.weight_set")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("VIEW3D_MT_particle_showhide")
|
||||
|
||||
|
||||
class VIEW3D_MT_particle_specials(Menu):
|
||||
bl_label = "Specials"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
particle_edit = context.tool_settings.particle_edit
|
||||
|
||||
layout.operator("particle.rekey")
|
||||
layout.operator("particle.delete")
|
||||
layout.operator("particle.remove_doubles")
|
||||
layout.operator("particle.unify_length")
|
||||
|
||||
if particle_edit.select_mode == 'POINT':
|
||||
layout.operator("particle.subdivide")
|
||||
|
||||
layout.operator("particle.weight_set")
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.mirror")
|
||||
|
||||
if particle_edit.select_mode == 'POINT':
|
||||
layout.separator()
|
||||
layout.operator("particle.select_roots")
|
||||
layout.operator("particle.select_tips")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_random")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_more")
|
||||
layout.operator("particle.select_less")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("particle.select_all").action = 'TOGGLE'
|
||||
layout.operator("particle.select_linked")
|
||||
layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
|
||||
|
||||
|
||||
class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
|
||||
_operator_name = "particle"
|
||||
|
||||
# ********** Pose Menu **********
|
||||
|
||||
|
||||
@@ -3088,6 +2977,31 @@ class VIEW3D_MT_edit_gpencil_transform(Menu):
|
||||
# ********** Panel **********
|
||||
|
||||
|
||||
class VIEW3D_PT_viewport_debug(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Modern Viewport"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
view = context.space_data
|
||||
return (view)
|
||||
|
||||
def draw_header(self, context):
|
||||
view = context.space_data
|
||||
self.layout.prop(view, "use_modern_viewport", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
view = context.space_data
|
||||
|
||||
layout.active = view.use_modern_viewport
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Placeholder for debugging options")
|
||||
|
||||
|
||||
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
@@ -3201,7 +3115,7 @@ class VIEW3D_PT_view3d_display(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
view = context.space_data
|
||||
return (view)
|
||||
return (view) and not view.use_modern_viewport
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -3213,6 +3127,11 @@ class VIEW3D_PT_view3d_display(Panel):
|
||||
col.prop(view, "show_only_render")
|
||||
col.prop(view, "show_world")
|
||||
|
||||
if scene.render.use_shading_nodes:
|
||||
col = layout.column()
|
||||
col.active = view.show_world
|
||||
col.prop(view, "show_world_sh")
|
||||
|
||||
col = layout.column()
|
||||
display_all = not view.show_only_render
|
||||
col.active = display_all
|
||||
@@ -3299,6 +3218,11 @@ class VIEW3D_PT_view3d_shading(Panel):
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Shading"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
view = context.space_data
|
||||
return (view) and not view.use_modern_viewport
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@@ -3321,6 +3245,38 @@ class VIEW3D_PT_view3d_shading(Panel):
|
||||
if scene.render.use_shading_nodes or gs.material_mode != 'GLSL':
|
||||
col.prop(view, "show_textured_shadeless")
|
||||
|
||||
if scene.render.use_shading_nodes and view.viewport_shade == 'MATERIAL':
|
||||
pbr_settings = view.pbr_settings
|
||||
|
||||
col.prop(pbr_settings, "use_realistic_mat", text="Material Preview")
|
||||
if pbr_settings.use_realistic_mat:
|
||||
brdf_settings = pbr_settings.brdf;
|
||||
subcol = col.column(align=True)
|
||||
subcol.prop(brdf_settings, "samples")
|
||||
subcol.prop(brdf_settings, "lodbias")
|
||||
|
||||
col.prop(pbr_settings, "use_ssao", text="Material Ambient Occlusion")
|
||||
if pbr_settings.use_ssao:
|
||||
ssao_settings = pbr_settings.ssao;
|
||||
subcol = col.column(align=True)
|
||||
subcol.prop(ssao_settings, "factor")
|
||||
subcol.prop(scene.world.light_settings, "distance")
|
||||
subcol.prop(ssao_settings, "samples")
|
||||
subcol.prop(ssao_settings, "steps")
|
||||
|
||||
col.prop(pbr_settings, "use_ssr", text="Material Reflections")
|
||||
if pbr_settings.use_ssr:
|
||||
ssr_settings = pbr_settings.ssr;
|
||||
subcol = col.column(align=True)
|
||||
subcol.prop(ssr_settings, "attenuation")
|
||||
subcol.prop(ssr_settings, "steps")
|
||||
subcol.prop(ssr_settings, "thickness")
|
||||
|
||||
if pbr_settings.use_ssao or pbr_settings.use_ssr:
|
||||
col.prop(pbr_settings, "use_backface", text="Backface Buffer")
|
||||
|
||||
col.prop(pbr_settings, "use_layer_override")
|
||||
|
||||
col.prop(view, "show_backface_culling")
|
||||
|
||||
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
|
||||
@@ -3329,7 +3285,9 @@ class VIEW3D_PT_view3d_shading(Panel):
|
||||
|
||||
fx_settings = view.fx_settings
|
||||
|
||||
|
||||
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
|
||||
col.prop(fx_settings, "use_colormanagement", text="Color Management")
|
||||
sub = col.column()
|
||||
sub.active = view.region_3d.view_perspective == 'CAMERA'
|
||||
sub.prop(fx_settings, "use_dof")
|
||||
|
@@ -942,37 +942,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
if not context.particle_edit_object:
|
||||
col = layout.split().column()
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
|
||||
|
||||
# Particle Mode #
|
||||
if context.particle_edit_object:
|
||||
tool = settings.tool
|
||||
|
||||
layout.column().prop(settings, "tool", expand=True)
|
||||
|
||||
if tool != 'NONE':
|
||||
col = layout.column()
|
||||
col.prop(brush, "size", slider=True)
|
||||
if tool != 'ADD':
|
||||
col.prop(brush, "strength", slider=True)
|
||||
|
||||
if tool == 'ADD':
|
||||
col.prop(brush, "count")
|
||||
col = layout.column()
|
||||
col.prop(settings, "use_default_interpolate")
|
||||
col.prop(brush, "steps", slider=True)
|
||||
col.prop(settings, "default_key_count", slider=True)
|
||||
elif tool == 'LENGTH':
|
||||
layout.prop(brush, "length_mode", expand=True)
|
||||
elif tool == 'PUFF':
|
||||
layout.prop(brush, "puff_mode", expand=True)
|
||||
layout.prop(brush, "use_puff_volume")
|
||||
col = layout.split().column()
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
|
||||
|
||||
# Sculpt Mode #
|
||||
|
||||
elif context.sculpt_object and brush:
|
||||
if context.sculpt_object and brush:
|
||||
capabilities = brush.sculpt_capabilities
|
||||
|
||||
col = layout.column()
|
||||
@@ -1657,7 +1632,7 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
settings = cls.paint_settings(context)
|
||||
return (settings is not None) and (not isinstance(settings, bpy.types.ParticleEdit))
|
||||
return (settings is not None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1880,78 +1855,6 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
|
||||
props.value = i
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
|
||||
"""Default tools for particle mode"""
|
||||
bl_context = "particlemode"
|
||||
bl_label = "Options"
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pe = context.tool_settings.particle_edit
|
||||
ob = pe.object
|
||||
|
||||
layout.prop(pe, "type", text="")
|
||||
|
||||
ptcache = None
|
||||
|
||||
if pe.type == 'PARTICLES':
|
||||
if ob.particle_systems:
|
||||
if len(ob.particle_systems) > 1:
|
||||
layout.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
|
||||
ob.particle_systems, "active_index", rows=2, maxrows=3)
|
||||
|
||||
ptcache = ob.particle_systems.active.point_cache
|
||||
else:
|
||||
for md in ob.modifiers:
|
||||
if md.type == pe.type:
|
||||
ptcache = md.point_cache
|
||||
|
||||
if ptcache and len(ptcache.point_caches) > 1:
|
||||
layout.template_list("UI_UL_list", "particles_point_caches", ptcache, "point_caches",
|
||||
ptcache.point_caches, "active_index", rows=2, maxrows=3)
|
||||
|
||||
if not pe.is_editable:
|
||||
layout.label(text="Point cache must be baked")
|
||||
layout.label(text="in memory to enable editing!")
|
||||
|
||||
col = layout.column(align=True)
|
||||
if pe.is_hair:
|
||||
col.active = pe.is_editable
|
||||
col.prop(pe, "use_emitter_deflect", text="Deflect emitter")
|
||||
sub = col.row(align=True)
|
||||
sub.active = pe.use_emitter_deflect
|
||||
sub.prop(pe, "emitter_distance", text="Distance")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = pe.is_editable
|
||||
col.label(text="Keep:")
|
||||
col.prop(pe, "use_preserve_length", text="Lengths")
|
||||
col.prop(pe, "use_preserve_root", text="Root")
|
||||
if not pe.is_hair:
|
||||
col.label(text="Correct:")
|
||||
col.prop(pe, "use_auto_velocity", text="Velocity")
|
||||
col.prop(ob.data, "use_mirror_x")
|
||||
|
||||
col.prop(pe, "shape_object")
|
||||
col.operator("particle.shape_cut")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = pe.is_editable
|
||||
col.label(text="Draw:")
|
||||
col.prop(pe, "draw_step", text="Path Steps")
|
||||
if pe.is_hair:
|
||||
col.prop(pe, "show_particles", text="Children")
|
||||
else:
|
||||
if pe.type == 'PARTICLES':
|
||||
col.prop(pe, "show_particles", text="Particles")
|
||||
col.prop(pe, "use_fade_time")
|
||||
sub = col.row(align=True)
|
||||
sub.active = pe.use_fade_time
|
||||
sub.prop(pe, "fade_frames", slider=True)
|
||||
|
||||
|
||||
# Grease Pencil drawing tools
|
||||
class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
@@ -29,7 +29,6 @@ set(SRC_DNA_INC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_actuator_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_anim_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_armature_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_boid_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_brush_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_cachefile_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_camera_types.h
|
||||
@@ -68,7 +67,6 @@ set(SRC_DNA_INC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_outliner_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_property_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_rigidbody_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
|
||||
|
@@ -55,7 +55,6 @@ extern "C" {
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
}
|
||||
|
||||
@@ -502,22 +501,6 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
|
||||
return;
|
||||
}
|
||||
|
||||
ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
|
||||
|
||||
for (; psys; psys = psys->next) {
|
||||
if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (psys->part->type == PART_HAIR) {
|
||||
m_settings.export_child_hairs = true;
|
||||
m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
|
||||
}
|
||||
else if (psys->part->type == PART_EMITTER) {
|
||||
m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
|
||||
}
|
||||
}
|
||||
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
{
|
||||
|
@@ -37,7 +37,6 @@ extern "C" {
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
}
|
||||
|
||||
using Alembic::Abc::P3fArraySamplePtr;
|
||||
@@ -54,13 +53,15 @@ AbcHairWriter::AbcHairWriter(Scene *scene,
|
||||
AbcTransformWriter *parent,
|
||||
uint32_t time_sampling,
|
||||
ExportSettings &settings,
|
||||
ParticleSystem *psys)
|
||||
void *UNUSED(psys))
|
||||
: AbcObjectWriter(scene, ob, time_sampling, settings, parent)
|
||||
{
|
||||
m_psys = psys;
|
||||
m_psys = NULL; // = psys;
|
||||
|
||||
#if 0
|
||||
OCurves curves(parent->alembicXform(), psys->name, m_time_sampling);
|
||||
m_schema = curves.getSchema();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AbcHairWriter::do_write()
|
||||
@@ -68,7 +69,7 @@ void AbcHairWriter::do_write()
|
||||
if (!m_psys) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ParticleSystemModifierData *psmd = psys_get_modifier(m_object, m_psys);
|
||||
|
||||
if (!psmd->dm_final) {
|
||||
@@ -116,15 +117,17 @@ void AbcHairWriter::do_write()
|
||||
|
||||
m_sample.setSelfBounds(bounds());
|
||||
m_schema.set(m_sample);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
|
||||
ParticleSettings *part,
|
||||
void *part,
|
||||
std::vector<Imath::V3f> &verts,
|
||||
std::vector<Imath::V3f> &norm_values,
|
||||
std::vector<Imath::V2f> &uv_values,
|
||||
std::vector<int32_t> &hvertices)
|
||||
{
|
||||
#if 0
|
||||
/* Get untransformed vertices, there's a xform under the hair. */
|
||||
float inv_mat[4][4];
|
||||
invert_m4_m4_safe(inv_mat, m_object->obmat);
|
||||
@@ -225,15 +228,17 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
|
||||
++path;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
|
||||
ParticleSettings *part,
|
||||
void *part,
|
||||
std::vector<Imath::V3f> &verts,
|
||||
std::vector<Imath::V3f> &norm_values,
|
||||
std::vector<Imath::V2f> &uv_values,
|
||||
std::vector<int32_t> &hvertices)
|
||||
{
|
||||
#if 0
|
||||
/* Get untransformed vertices, there's a xform under the hair. */
|
||||
float inv_mat[4][4];
|
||||
invert_m4_m4_safe(inv_mat, m_object->obmat);
|
||||
@@ -287,4 +292,5 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
|
||||
++path;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -26,13 +26,11 @@
|
||||
#include "abc_object.h"
|
||||
|
||||
struct DerivedMesh;
|
||||
struct ParticleSettings;
|
||||
struct ParticleSystem;
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
class AbcHairWriter : public AbcObjectWriter {
|
||||
ParticleSystem *m_psys;
|
||||
/*ParticleSystem*/ void *m_psys;
|
||||
|
||||
Alembic::AbcGeom::OCurvesSchema m_schema;
|
||||
Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
|
||||
@@ -43,20 +41,20 @@ public:
|
||||
AbcTransformWriter *parent,
|
||||
uint32_t time_sampling,
|
||||
ExportSettings &settings,
|
||||
ParticleSystem *psys);
|
||||
/*ParticleSystem*/void *psys);
|
||||
|
||||
private:
|
||||
virtual void do_write();
|
||||
|
||||
void write_hair_sample(DerivedMesh *dm,
|
||||
ParticleSettings *part,
|
||||
/*ParticleSettings*/ void *part,
|
||||
std::vector<Imath::V3f> &verts,
|
||||
std::vector<Imath::V3f> &norm_values,
|
||||
std::vector<Imath::V2f> &uv_values,
|
||||
std::vector<int32_t> &hvertices);
|
||||
|
||||
void write_hair_child_sample(DerivedMesh *dm,
|
||||
ParticleSettings *part,
|
||||
/*ParticleSettings*/ void *part,
|
||||
std::vector<Imath::V3f> &verts,
|
||||
std::vector<Imath::V3f> &norm_values,
|
||||
std::vector<Imath::V2f> &uv_values,
|
||||
|
@@ -262,7 +262,7 @@ static ModifierData *get_subsurf_modifier(Scene *scene, Object *ob)
|
||||
}
|
||||
|
||||
/* mesh is not a subsurf. break */
|
||||
if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) {
|
||||
if ((md->type != eModifierType_Displace) /*&& (md->type != eModifierType_ParticleSystem)*/) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,6 @@ extern "C" {
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
@@ -62,13 +61,15 @@ AbcPointsWriter::AbcPointsWriter(Scene *scene,
|
||||
AbcTransformWriter *parent,
|
||||
uint32_t time_sampling,
|
||||
ExportSettings &settings,
|
||||
ParticleSystem *psys)
|
||||
void *UNUSED(psys))
|
||||
: AbcObjectWriter(scene, ob, time_sampling, settings, parent)
|
||||
{
|
||||
m_psys = psys;
|
||||
m_psys = NULL; // = psys;
|
||||
|
||||
#if 0
|
||||
OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
|
||||
m_schema = points.getSchema();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AbcPointsWriter::do_write()
|
||||
@@ -76,7 +77,7 @@ void AbcPointsWriter::do_write()
|
||||
if (!m_psys) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::vector<Imath::V3f> points;
|
||||
std::vector<Imath::V3f> velocities;
|
||||
std::vector<float> widths;
|
||||
@@ -133,6 +134,7 @@ void AbcPointsWriter::do_write()
|
||||
m_sample.setSelfBounds(bounds());
|
||||
|
||||
m_schema.set(m_sample);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
@@ -28,14 +28,12 @@
|
||||
#include "abc_object.h"
|
||||
#include "abc_customdata.h"
|
||||
|
||||
class ParticleSystem;
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
class AbcPointsWriter : public AbcObjectWriter {
|
||||
Alembic::AbcGeom::OPointsSchema m_schema;
|
||||
Alembic::AbcGeom::OPointsSchema::Sample m_sample;
|
||||
ParticleSystem *m_psys;
|
||||
/*ParticleSystem*/ void *m_psys;
|
||||
|
||||
public:
|
||||
AbcPointsWriter(Scene *scene,
|
||||
@@ -43,7 +41,7 @@ public:
|
||||
AbcTransformWriter *parent,
|
||||
uint32_t time_sampling,
|
||||
ExportSettings &settings,
|
||||
ParticleSystem *psys);
|
||||
/*ParticleSystem*/ void *psys);
|
||||
|
||||
void do_write();
|
||||
};
|
||||
|
@@ -34,6 +34,9 @@
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
/* enable this only if needed (unused circa 2016) */
|
||||
#define BLF_BLUR_ENABLE 0
|
||||
|
||||
struct rctf;
|
||||
struct ColorManagedDisplay;
|
||||
struct ResultBLF;
|
||||
@@ -144,7 +147,10 @@ void BLF_rotation(int fontid, float angle);
|
||||
void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax);
|
||||
void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax);
|
||||
void BLF_wordwrap(int fontid, int wrap_width);
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
void BLF_blur(int fontid, int size);
|
||||
#endif
|
||||
|
||||
void BLF_enable(int fontid, int option);
|
||||
void BLF_disable(int fontid, int option);
|
||||
|
@@ -56,7 +56,9 @@
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
#include "GPU_basic_shader.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_immediate.h"
|
||||
#endif
|
||||
|
||||
#include "blf_internal_types.h"
|
||||
@@ -453,6 +455,7 @@ void BLF_size(int fontid, int size, int dpi)
|
||||
}
|
||||
}
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
void BLF_blur(int fontid, int size)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
@@ -461,6 +464,7 @@ void BLF_blur(int fontid, int size)
|
||||
font->blur = size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
|
||||
{
|
||||
@@ -490,7 +494,7 @@ void BLF_rotation_default(float angle)
|
||||
}
|
||||
}
|
||||
|
||||
static void blf_draw_gl__start(FontBLF *font, GLint *mode)
|
||||
static void blf_draw_gl__start(FontBLF *font)
|
||||
{
|
||||
/*
|
||||
* The pixmap alignment hack is handle
|
||||
@@ -500,52 +504,48 @@ static void blf_draw_gl__start(FontBLF *font, GLint *mode)
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
|
||||
#endif
|
||||
|
||||
/* Save the current matrix mode. */
|
||||
glGetIntegerv(GL_MATRIX_MODE, mode);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
gpuMatrixBegin3D_legacy();
|
||||
|
||||
if (font->flags & BLF_MATRIX)
|
||||
glMultMatrixf(font->m);
|
||||
gpuMultMatrix3D((float (*)[4])font->m);
|
||||
|
||||
glTranslate3fv(font->pos);
|
||||
gpuTranslate3fv(font->pos);
|
||||
|
||||
if (font->flags & BLF_ASPECT)
|
||||
glScalef(font->aspect[0], font->aspect[1], font->aspect[2]);
|
||||
gpuScale3fv(font->aspect);
|
||||
|
||||
if (font->flags & BLF_ROTATION) /* radians -> degrees */
|
||||
glRotatef(font->angle * (float)(180.0 / M_PI), 0.0f, 0.0f, 1.0f);
|
||||
gpuRotateAxis(RAD2DEG(font->angle), 'Z');
|
||||
|
||||
if (font->shadow || font->blur)
|
||||
glGetFloatv(GL_CURRENT_COLOR, font->orig_col);
|
||||
float temp_color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, temp_color); /* TODO(merwin): new BLF_color function? */
|
||||
rgba_float_to_uchar(font->color, temp_color);
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
VertexFormat *format = immVertexFormat();
|
||||
unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
|
||||
unsigned texCoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT);
|
||||
unsigned color = add_attrib(format, "color", GL_UNSIGNED_BYTE, 4, NORMALIZE_INT_TO_FLOAT);
|
||||
|
||||
BLI_assert(pos == BLF_POS_ID);
|
||||
BLI_assert(texCoord == BLF_COORD_ID);
|
||||
BLI_assert(color == BLF_COLOR_ID);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_TEXT);
|
||||
#endif
|
||||
|
||||
/* always bind the texture for the first glyph */
|
||||
font->tex_bind_state = -1;
|
||||
}
|
||||
|
||||
static void blf_draw_gl__end(GLint mode)
|
||||
static void blf_draw_gl__end(void)
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
if (mode != GL_MODELVIEW)
|
||||
glMatrixMode(mode);
|
||||
gpuMatrixEnd();
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
|
||||
immUnbindProgram();
|
||||
#endif
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
@@ -554,23 +554,26 @@ void BLF_draw_ex(
|
||||
struct ResultBLF *r_info)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
GLint mode;
|
||||
|
||||
BLF_RESULT_CHECK_INIT(r_info);
|
||||
|
||||
if (font && font->glyph_cache) {
|
||||
blf_draw_gl__start(font, &mode);
|
||||
blf_draw_gl__start(font);
|
||||
if (font->flags & BLF_WORD_WRAP) {
|
||||
blf_font_draw__wrap(font, str, len, r_info);
|
||||
}
|
||||
else {
|
||||
blf_font_draw(font, str, len, r_info);
|
||||
}
|
||||
blf_draw_gl__end(mode);
|
||||
blf_draw_gl__end();
|
||||
}
|
||||
}
|
||||
void BLF_draw(int fontid, const char *str, size_t len)
|
||||
{
|
||||
if (len == 0 || str[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
BLF_draw_ex(fontid, str, len, NULL);
|
||||
}
|
||||
|
||||
@@ -579,12 +582,11 @@ void BLF_draw_ascii_ex(
|
||||
struct ResultBLF *r_info)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
GLint mode;
|
||||
|
||||
BLF_RESULT_CHECK_INIT(r_info);
|
||||
|
||||
if (font && font->glyph_cache) {
|
||||
blf_draw_gl__start(font, &mode);
|
||||
blf_draw_gl__start(font);
|
||||
if (font->flags & BLF_WORD_WRAP) {
|
||||
/* use non-ascii draw function for word-wrap */
|
||||
blf_font_draw__wrap(font, str, len, r_info);
|
||||
@@ -592,24 +594,31 @@ void BLF_draw_ascii_ex(
|
||||
else {
|
||||
blf_font_draw_ascii(font, str, len, r_info);
|
||||
}
|
||||
blf_draw_gl__end(mode);
|
||||
blf_draw_gl__end();
|
||||
}
|
||||
}
|
||||
void BLF_draw_ascii(int fontid, const char *str, size_t len)
|
||||
{
|
||||
if (len == 0 || str[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
BLF_draw_ascii_ex(fontid, str, len, NULL);
|
||||
}
|
||||
|
||||
int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
|
||||
{
|
||||
if (len == 0 || str[0] == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FontBLF *font = blf_get(fontid);
|
||||
GLint mode;
|
||||
int columns = 0;
|
||||
|
||||
if (font && font->glyph_cache) {
|
||||
blf_draw_gl__start(font, &mode);
|
||||
blf_draw_gl__start(font);
|
||||
columns = blf_font_draw_mono(font, str, len, cwidth);
|
||||
blf_draw_gl__end(mode);
|
||||
blf_draw_gl__end();
|
||||
}
|
||||
|
||||
return columns;
|
||||
@@ -855,7 +864,7 @@ void BLF_shadow(int fontid, int level, const float rgba[4])
|
||||
|
||||
if (font) {
|
||||
font->shadow = level;
|
||||
copy_v4_v4(font->shadow_col, rgba);
|
||||
rgba_float_to_uchar(font->shadow_color, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -58,6 +58,8 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BLF_api.h"
|
||||
|
||||
#include "GPU_immediate.h"
|
||||
|
||||
#include "blf_internal_types.h"
|
||||
#include "blf_internal.h"
|
||||
|
||||
@@ -172,6 +174,23 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
|
||||
} \
|
||||
} (void)0
|
||||
|
||||
static unsigned verts_needed(const FontBLF *font, const char *str, size_t len)
|
||||
{
|
||||
unsigned length = (unsigned)((len == INT_MAX) ? strlen(str) : len);
|
||||
unsigned quad_ct = 1;
|
||||
|
||||
if (font->flags & BLF_SHADOW) {
|
||||
if (font->shadow == 0)
|
||||
quad_ct += 1;
|
||||
if (font->shadow <= 4)
|
||||
quad_ct += 9; /* 3x3 kernel */
|
||||
else
|
||||
quad_ct += 25; /* 5x5 kernel */
|
||||
}
|
||||
|
||||
return length * quad_ct * 4;
|
||||
}
|
||||
|
||||
static void blf_font_draw_ex(
|
||||
FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info,
|
||||
int pen_y)
|
||||
@@ -187,6 +206,9 @@ static void blf_font_draw_ex(
|
||||
|
||||
blf_font_ensure_ascii_table(font);
|
||||
|
||||
immBeginAtMost(GL_QUADS, verts_needed(font, str, len));
|
||||
/* at most because some glyphs might be clipped & not drawn */
|
||||
|
||||
while ((i < len) && str[i]) {
|
||||
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
|
||||
|
||||
@@ -204,6 +226,8 @@ static void blf_font_draw_ex(
|
||||
g_prev = g;
|
||||
}
|
||||
|
||||
immEnd();
|
||||
|
||||
if (r_info) {
|
||||
r_info->lines = 1;
|
||||
r_info->width = pen_x;
|
||||
@@ -229,6 +253,8 @@ static void blf_font_draw_ascii_ex(
|
||||
|
||||
blf_font_ensure_ascii_table(font);
|
||||
|
||||
immBeginAtMost(GL_QUADS, verts_needed(font, str, len));
|
||||
|
||||
while ((c = *(str++)) && len--) {
|
||||
BLI_assert(c < 128);
|
||||
if ((g = glyph_ascii_table[c]) == NULL)
|
||||
@@ -243,6 +269,8 @@ static void blf_font_draw_ascii_ex(
|
||||
g_prev = g;
|
||||
}
|
||||
|
||||
immEnd();
|
||||
|
||||
if (r_info) {
|
||||
r_info->lines = 1;
|
||||
r_info->width = pen_x;
|
||||
@@ -265,6 +293,8 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
|
||||
|
||||
blf_font_ensure_ascii_table(font);
|
||||
|
||||
immBeginAtMost(GL_QUADS, verts_needed(font, str, len));
|
||||
|
||||
while ((i < len) && str[i]) {
|
||||
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
|
||||
|
||||
@@ -284,6 +314,8 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
|
||||
pen_x += cwidth * col;
|
||||
}
|
||||
|
||||
immEnd();
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@@ -922,7 +954,9 @@ static void blf_font_fill(FontBLF *font)
|
||||
font->size = 0;
|
||||
BLI_listbase_clear(&font->cache);
|
||||
font->glyph_cache = NULL;
|
||||
#if BLF_BLUR_ENABLE
|
||||
font->blur = 0;
|
||||
#endif
|
||||
font->max_tex_size = -1;
|
||||
|
||||
font->buf_info.fbuf = NULL;
|
||||
|
@@ -56,7 +56,7 @@
|
||||
#include "BLF_api.h"
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
#include "GPU_basic_shader.h"
|
||||
#include "GPU_immediate.h"
|
||||
#endif
|
||||
|
||||
#include "blf_internal_types.h"
|
||||
@@ -182,17 +182,6 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
/* needed since basic shader doesn't support alpha-only textures,
|
||||
* while we could add support this is only used in a few places
|
||||
* (an alternative could be to have a simple shader for BLF). */
|
||||
if (GLEW_ARB_texture_swizzle && GPU_basic_shader_use_glsl_get()) {
|
||||
GLint swizzle_mask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA};
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
|
||||
@@ -326,73 +315,73 @@ void blf_glyph_free(GlyphBLF *g)
|
||||
MEM_freeN(g);
|
||||
}
|
||||
|
||||
static void blf_texture_draw(float uv[2][2], float dx, float y1, float dx1, float y2)
|
||||
static void blf_texture_draw(const unsigned char color[4], float uv[2][2], float dx, float y1, float dx1, float y2)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(uv[0][0], uv[0][1]);
|
||||
glVertex2f(dx, y1);
|
||||
|
||||
glTexCoord2f(uv[0][0], uv[1][1]);
|
||||
glVertex2f(dx, y2);
|
||||
|
||||
glTexCoord2f(uv[1][0], uv[1][1]);
|
||||
glVertex2f(dx1, y2);
|
||||
|
||||
glTexCoord2f(uv[1][0], uv[0][1]);
|
||||
glVertex2f(dx1, y1);
|
||||
glEnd();
|
||||
immAttrib2f(BLF_COORD_ID, uv[0][0], uv[0][1]);
|
||||
immSkipAttrib(BLF_COLOR_ID); /* skip color of most vertices */
|
||||
immVertex2f(BLF_POS_ID, dx, y1);
|
||||
|
||||
immAttrib2f(BLF_COORD_ID, uv[0][0], uv[1][1]);
|
||||
immSkipAttrib(BLF_COLOR_ID);
|
||||
immVertex2f(BLF_POS_ID, dx, y2);
|
||||
|
||||
immAttrib2f(BLF_COORD_ID, uv[1][0], uv[1][1]);
|
||||
immSkipAttrib(BLF_COLOR_ID);
|
||||
immVertex2f(BLF_POS_ID, dx1, y2);
|
||||
|
||||
immAttrib2f(BLF_COORD_ID, uv[1][0], uv[0][1]);
|
||||
immAttrib4ubv(BLF_COLOR_ID, color); /* set color of provoking vertex */
|
||||
immVertex2f(BLF_POS_ID, dx1, y1);
|
||||
}
|
||||
|
||||
static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
|
||||
static void blf_texture5_draw(const unsigned char color_in[4], float uv[2][2], float x1, float y1, float x2, float y2)
|
||||
{
|
||||
const float soft[25] = {1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f,
|
||||
1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
|
||||
2 / 60.0f, 5 / 60.0f, 8 / 60.0f, 5 / 60.0f, 2 / 60.0f,
|
||||
1 / 60.0f, 3 / 60.0f, 5 / 60.0f, 3 / 60.0f, 1 / 60.0f,
|
||||
1 / 60.0f, 1 / 60.0f, 2 / 60.0f, 1 / 60.0f, 1 / 60.0f};
|
||||
|
||||
|
||||
const float *fp = soft;
|
||||
float color[4];
|
||||
unsigned char color[4];
|
||||
float dx, dy;
|
||||
|
||||
color[0] = shadow_col[0];
|
||||
color[1] = shadow_col[1];
|
||||
color[2] = shadow_col[2];
|
||||
|
||||
color[0] = color_in[0];
|
||||
color[1] = color_in[1];
|
||||
color[2] = color_in[2];
|
||||
|
||||
const float alpha_in = (1 / 255.0f) * color_in[3];
|
||||
|
||||
for (dx = -2; dx < 3; dx++) {
|
||||
for (dy = -2; dy < 3; dy++, fp++) {
|
||||
color[3] = *(fp) * shadow_col[3];
|
||||
glColor4fv(color);
|
||||
blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
|
||||
color[3] = FTOCHAR(*fp * alpha_in);
|
||||
blf_texture_draw(color, uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
|
||||
}
|
||||
}
|
||||
|
||||
glColor4fv(color);
|
||||
}
|
||||
|
||||
static void blf_texture3_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
|
||||
static void blf_texture3_draw(const unsigned char color_in[4], float uv[2][2], float x1, float y1, float x2, float y2)
|
||||
{
|
||||
const float soft[9] = {1 / 16.0f, 2 / 16.0f, 1 / 16.0f,
|
||||
2 / 16.0f, 4 / 16.0f, 2 / 16.0f,
|
||||
1 / 16.0f, 2 / 16.0f, 1 / 16.0f};
|
||||
|
||||
const float *fp = soft;
|
||||
float color[4];
|
||||
unsigned char color[4];
|
||||
float dx, dy;
|
||||
|
||||
color[0] = shadow_col[0];
|
||||
color[1] = shadow_col[1];
|
||||
color[2] = shadow_col[2];
|
||||
color[0] = color_in[0];
|
||||
color[1] = color_in[1];
|
||||
color[2] = color_in[2];
|
||||
|
||||
const float alpha_in = (1 / 255.0f) * color_in[3];
|
||||
|
||||
for (dx = -1; dx < 2; dx++) {
|
||||
for (dy = -1; dy < 2; dy++, fp++) {
|
||||
color[3] = *(fp) * shadow_col[3];
|
||||
glColor4fv(color);
|
||||
blf_texture_draw(uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
|
||||
color[3] = FTOCHAR(*fp * alpha_in);
|
||||
blf_texture_draw(color, uv, x1 + dx, y1 + dy, x2 + dx, y2 + dy);
|
||||
}
|
||||
}
|
||||
|
||||
glColor4fv(color);
|
||||
}
|
||||
|
||||
static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
|
||||
@@ -486,39 +475,37 @@ void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
|
||||
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = g->tex));
|
||||
}
|
||||
|
||||
/* TODO: blur & shadow in shader, single quad per glyph */
|
||||
|
||||
if (font->flags & BLF_SHADOW) {
|
||||
rctf rect_ofs;
|
||||
blf_glyph_calc_rect(&rect_ofs, g,
|
||||
x + (float)font->shadow_x,
|
||||
y + (float)font->shadow_y);
|
||||
|
||||
switch (font->shadow) {
|
||||
case 3:
|
||||
blf_texture3_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
break;
|
||||
case 5:
|
||||
blf_texture5_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
break;
|
||||
default:
|
||||
glColor4fv(font->shadow_col);
|
||||
blf_texture_draw(g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
break;
|
||||
if (font->shadow == 0) {
|
||||
blf_texture_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
else if (font->shadow <= 4) {
|
||||
blf_texture3_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
else {
|
||||
blf_texture5_draw(font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
|
||||
}
|
||||
|
||||
glColor4fv(font->orig_col);
|
||||
}
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
switch (font->blur) {
|
||||
case 3:
|
||||
blf_texture3_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
blf_texture3_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
break;
|
||||
case 5:
|
||||
blf_texture5_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
blf_texture5_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
break;
|
||||
default:
|
||||
blf_texture_draw(g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
break;
|
||||
blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
}
|
||||
|
||||
return;
|
||||
#else
|
||||
blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
|
||||
#endif
|
||||
}
|
||||
|
@@ -37,6 +37,11 @@ struct GlyphBLF;
|
||||
struct GlyphCacheBLF;
|
||||
struct rctf;
|
||||
|
||||
/* vertex attribute IDs (fixed IDs so we don't have to pass them around) */
|
||||
#define BLF_POS_ID 0
|
||||
#define BLF_COORD_ID 1
|
||||
#define BLF_COLOR_ID 2
|
||||
|
||||
unsigned int blf_next_p2(unsigned int x);
|
||||
unsigned int blf_hash(unsigned int val);
|
||||
|
||||
|
@@ -175,8 +175,10 @@ typedef struct FontBLF {
|
||||
/* angle in radians. */
|
||||
float angle;
|
||||
|
||||
#if 0 /* BLF_BLUR_ENABLE */
|
||||
/* blur: 3 or 5 large kernel */
|
||||
int blur;
|
||||
#endif
|
||||
|
||||
/* shadow level. */
|
||||
int shadow;
|
||||
@@ -186,10 +188,10 @@ typedef struct FontBLF {
|
||||
int shadow_y;
|
||||
|
||||
/* shadow color. */
|
||||
float shadow_col[4];
|
||||
unsigned char shadow_color[4];
|
||||
|
||||
/* store color here when drawing shadow or blur. */
|
||||
float orig_col[4];
|
||||
/* main text color. */
|
||||
unsigned char color[4];
|
||||
|
||||
/* Multiplied this matrix with the current one before
|
||||
* draw the text! see blf_draw__start.
|
||||
|
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009 by Janne Karhu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BKE_BOIDS_H__
|
||||
#define __BKE_BOIDS_H__
|
||||
|
||||
/** \file BKE_boids.h
|
||||
* \ingroup bke
|
||||
* \since 2009
|
||||
* \author Janne Karhu
|
||||
*/
|
||||
|
||||
#include "DNA_boid_types.h"
|
||||
|
||||
struct RNG;
|
||||
|
||||
typedef struct BoidBrainData {
|
||||
struct ParticleSimulationData *sim;
|
||||
struct ParticleSettings *part;
|
||||
float timestep, cfra, dfra;
|
||||
float wanted_co[3], wanted_speed;
|
||||
|
||||
/* Goal stuff */
|
||||
struct Object *goal_ob;
|
||||
float goal_co[3];
|
||||
float goal_nor[3];
|
||||
float goal_priority;
|
||||
|
||||
struct RNG *rng;
|
||||
} BoidBrainData;
|
||||
|
||||
void boids_precalc_rules(struct ParticleSettings *part, float cfra);
|
||||
void boid_brain(BoidBrainData *bbd, int p, struct ParticleData *pa);
|
||||
void boid_body(BoidBrainData *bbd, struct ParticleData *pa);
|
||||
void boid_default_settings(BoidSettings *boids);
|
||||
BoidRule *boid_new_rule(int type);
|
||||
BoidState *boid_new_state(BoidSettings *boids);
|
||||
BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state);
|
||||
void boid_free_settings(BoidSettings *boids);
|
||||
BoidSettings *boid_copy_settings(BoidSettings *boids);
|
||||
BoidState *boid_get_current_state(BoidSettings *boids);
|
||||
#endif
|
@@ -237,9 +237,6 @@ int cloth_uses_vgroup(struct ClothModifierData *clmd);
|
||||
void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
|
||||
void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
|
||||
|
||||
// needed for button_object.c
|
||||
void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr );
|
||||
|
||||
// needed for cloth.c
|
||||
int cloth_add_spring (struct ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type);
|
||||
|
||||
|
@@ -109,7 +109,6 @@ enum {
|
||||
CTX_MODE_PAINT_WEIGHT,
|
||||
CTX_MODE_PAINT_VERTEX,
|
||||
CTX_MODE_PAINT_TEXTURE,
|
||||
CTX_MODE_PARTICLE,
|
||||
CTX_MODE_OBJECT
|
||||
};
|
||||
|
||||
|
@@ -73,7 +73,6 @@ void dynamicPaint_freeCanvas(struct DynamicPaintModifierData *pmd);
|
||||
void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd);
|
||||
void dynamicPaint_freeSurfaceData(struct DynamicPaintSurface *surface);
|
||||
|
||||
void dynamicPaint_cacheUpdateFrames(struct DynamicPaintSurface *surface);
|
||||
bool dynamicPaint_surfaceHasColorPreview(struct DynamicPaintSurface *surface);
|
||||
bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, struct Object *ob, int output);
|
||||
void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface);
|
||||
|
@@ -41,9 +41,7 @@ struct Object;
|
||||
struct Scene;
|
||||
struct ListBase;
|
||||
struct Group;
|
||||
struct ParticleSimulationData;
|
||||
struct ParticleData;
|
||||
struct ParticleKey;
|
||||
struct PointCacheKey;
|
||||
|
||||
struct EffectorWeights *BKE_add_effector_weights(struct Group *group);
|
||||
struct PartDeflect *object_add_collision_fields(int type);
|
||||
@@ -95,7 +93,6 @@ typedef struct EffectorCache {
|
||||
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSystem *psys;
|
||||
struct SurfaceModifierData *surmd;
|
||||
|
||||
struct PartDeflect *pd;
|
||||
@@ -110,17 +107,14 @@ typedef struct EffectorCache {
|
||||
} EffectorCache;
|
||||
|
||||
void free_partdeflect(struct PartDeflect *pd);
|
||||
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool for_simulation);
|
||||
struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct EffectorWeights *weights, bool for_simulation);
|
||||
void pdEndEffectors(struct ListBase **effectors);
|
||||
void pdPrecalculateEffectors(struct ListBase *effectors);
|
||||
void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
|
||||
|
||||
void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
|
||||
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
|
||||
void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
|
||||
|
||||
/* needed for boids */
|
||||
float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights);
|
||||
int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], float surface_co[3], float surface_nor[3], float surface_vel[3]);
|
||||
int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity);
|
||||
|
||||
|
@@ -94,7 +94,7 @@ void id_clear_lib_data_ex(struct Main *bmain, struct ID *id, const bool id_in_ma
|
||||
|
||||
struct ListBase *which_libbase(struct Main *mainlib, short type);
|
||||
|
||||
#define MAX_LIBARRAY 35
|
||||
#define MAX_LIBARRAY 34
|
||||
int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
|
||||
|
||||
/* Main API */
|
||||
|
@@ -96,7 +96,6 @@ typedef struct Main {
|
||||
ListBase action;
|
||||
ListBase nodetree;
|
||||
ListBase brush;
|
||||
ListBase particle;
|
||||
ListBase palettes;
|
||||
ListBase paintcurves;
|
||||
ListBase wm;
|
||||
|
@@ -374,7 +374,6 @@ int modifiers_getCageIndex(struct Scene *scene, struct Object *ob,
|
||||
bool modifiers_isModifierEnabled(struct Object *ob, int modifierType);
|
||||
bool modifiers_isSoftbodyEnabled(struct Object *ob);
|
||||
bool modifiers_isClothEnabled(struct Object *ob);
|
||||
bool modifiers_isParticleEnabled(struct Object *ob);
|
||||
|
||||
struct Object *modifiers_isDeformedByArmature(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
|
||||
|
@@ -55,10 +55,7 @@ void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struc
|
||||
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
|
||||
struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches);
|
||||
struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
|
||||
struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys);
|
||||
void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src);
|
||||
void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src);
|
||||
void BKE_object_free_particlesystems(struct Object *ob);
|
||||
void BKE_object_free_softbody(struct Object *ob);
|
||||
void BKE_object_free_bulletsoftbody(struct Object *ob);
|
||||
void BKE_object_free_curve_cache(struct Object *ob);
|
||||
|
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2007 by Janne Karhu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Adaptive time step
|
||||
* Classical SPH
|
||||
* Copyright 2011-2012 AutoCRC
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BKE_PARTICLE_H__
|
||||
#define __BKE_PARTICLE_H__
|
||||
|
||||
/** \file BKE_particle.h
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
struct ParticleSystemModifierData;
|
||||
struct ParticleSystem;
|
||||
struct ParticleKey;
|
||||
struct ParticleSettings;
|
||||
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct DerivedMesh;
|
||||
struct ModifierData;
|
||||
struct MTFace;
|
||||
struct MCol;
|
||||
struct MFace;
|
||||
struct MVert;
|
||||
struct LatticeDeformData;
|
||||
struct LinkNode;
|
||||
struct KDTree;
|
||||
struct RNG;
|
||||
struct BVHTreeRay;
|
||||
struct BVHTreeRayHit;
|
||||
struct EdgeHash;
|
||||
|
||||
#define PARTICLE_COLLISION_MAX_COLLISIONS 10
|
||||
|
||||
#define PARTICLE_P ParticleData * pa; int p
|
||||
#define LOOP_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++)
|
||||
#define LOOP_EXISTING_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) if (!(pa->flag & PARS_UNEXIST))
|
||||
#define LOOP_SHOWN_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) if (!(pa->flag & (PARS_UNEXIST | PARS_NO_DISP)))
|
||||
/* OpenMP: Can only advance one variable within loop definition. */
|
||||
#define LOOP_DYNAMIC_PARTICLES for (p = 0; p < psys->totpart; p++) if ((pa = psys->particles + p)->state.time > 0.0f)
|
||||
|
||||
/* fast but sure way to get the modifier*/
|
||||
#define PARTICLE_PSMD ParticleSystemModifierData * psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
|
||||
|
||||
/* common stuff that many particle functions need */
|
||||
typedef struct ParticleSimulationData {
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSystem *psys;
|
||||
struct ParticleSystemModifierData *psmd;
|
||||
struct ListBase *colliders;
|
||||
/* Courant number. This is used to implement an adaptive time step. Only the
|
||||
* maximum value per time step is important. Only sph_integrate makes use of
|
||||
* this at the moment. Other solvers could, too. */
|
||||
float courant_num;
|
||||
} ParticleSimulationData;
|
||||
|
||||
typedef struct SPHData {
|
||||
ParticleSystem *psys[10];
|
||||
ParticleData *pa;
|
||||
float mass;
|
||||
struct EdgeHash *eh;
|
||||
float *gravity;
|
||||
float hfac;
|
||||
/* Average distance to neighbours (other particles in the support domain),
|
||||
* for calculating the Courant number (adaptive time step). */
|
||||
int pass;
|
||||
float element_size;
|
||||
float flow[3];
|
||||
|
||||
/* Integrator callbacks. This allows different SPH implementations. */
|
||||
void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
|
||||
void (*density_cb) (void *rangedata_v, int index, const float co[3], float squared_dist);
|
||||
} SPHData;
|
||||
|
||||
typedef struct ParticleTexture {
|
||||
float ivel; /* used in reset */
|
||||
float time, life, exist, size; /* used in init */
|
||||
float damp, gravity, field; /* used in physics */
|
||||
float length, clump, kink_freq, kink_amp, effector; /* used in path caching */
|
||||
float rough1, rough2, roughe; /* used in path caching */
|
||||
} ParticleTexture;
|
||||
|
||||
typedef struct ParticleSeam {
|
||||
float v0[3], v1[3];
|
||||
float nor[3], dir[3], tan[3];
|
||||
float length2;
|
||||
} ParticleSeam;
|
||||
|
||||
typedef struct ParticleCacheKey {
|
||||
float co[3];
|
||||
float vel[3];
|
||||
float rot[4];
|
||||
float col[3];
|
||||
float time;
|
||||
int segments;
|
||||
} ParticleCacheKey;
|
||||
|
||||
typedef struct ParticleThreadContext {
|
||||
/* shared */
|
||||
struct ParticleSimulationData sim;
|
||||
struct DerivedMesh *dm;
|
||||
struct Material *ma;
|
||||
|
||||
/* distribution */
|
||||
struct KDTree *tree;
|
||||
|
||||
struct ParticleSeam *seams;
|
||||
int totseam;
|
||||
|
||||
float *jit, *jitoff, *weight;
|
||||
float maxweight;
|
||||
int *index, *skip, jitlevel;
|
||||
|
||||
int cfrom, distr;
|
||||
|
||||
struct ParticleData *tpars;
|
||||
|
||||
/* path caching */
|
||||
bool editupdate;
|
||||
int between, segments, extra_segments;
|
||||
int totchild, totparent, parent_pass;
|
||||
|
||||
float cfra;
|
||||
|
||||
float *vg_length, *vg_clump, *vg_kink;
|
||||
float *vg_rough1, *vg_rough2, *vg_roughe;
|
||||
float *vg_effector;
|
||||
|
||||
struct CurveMapping *clumpcurve;
|
||||
struct CurveMapping *roughcurve;
|
||||
} ParticleThreadContext;
|
||||
|
||||
typedef struct ParticleTask {
|
||||
ParticleThreadContext *ctx;
|
||||
struct RNG *rng, *rng_path;
|
||||
int begin, end;
|
||||
} ParticleTask;
|
||||
|
||||
typedef struct ParticleBillboardData {
|
||||
struct Object *ob;
|
||||
float vec[3], vel[3];
|
||||
float offset[2];
|
||||
float size[2];
|
||||
float tilt, random, time;
|
||||
int uv[3];
|
||||
int lock, num;
|
||||
int totnum;
|
||||
int lifetime;
|
||||
short align, uv_split, anim, split_offset;
|
||||
} ParticleBillboardData;
|
||||
|
||||
typedef struct ParticleCollisionElement {
|
||||
/* pointers to original data */
|
||||
float *x[3], *v[3];
|
||||
|
||||
/* values interpolated from original data*/
|
||||
float x0[3], x1[3], x2[3], p[3];
|
||||
|
||||
/* results for found intersection point */
|
||||
float nor[3], vel[3], uv[2];
|
||||
|
||||
/* count of original data (1-4) */
|
||||
int tot;
|
||||
|
||||
/* index of the collision face */
|
||||
int index;
|
||||
|
||||
/* flags for inversed normal / particle already inside element at start */
|
||||
short inv_nor, inside;
|
||||
} ParticleCollisionElement;
|
||||
|
||||
/* container for moving data between deflet_particle and particle_intersect_face */
|
||||
typedef struct ParticleCollision {
|
||||
struct Object *current;
|
||||
struct Object *hit;
|
||||
struct Object *skip[PARTICLE_COLLISION_MAX_COLLISIONS+1];
|
||||
struct Object *emitter;
|
||||
|
||||
struct CollisionModifierData *md; // collision modifier for current object;
|
||||
|
||||
float f; // time factor of previous collision, needed for substracting face velocity
|
||||
float fac1, fac2;
|
||||
|
||||
float cfra, old_cfra;
|
||||
|
||||
float original_ray_length; //original length of co2-co1, needed for collision time evaluation
|
||||
|
||||
int skip_count;
|
||||
|
||||
ParticleCollisionElement pce;
|
||||
|
||||
/* total_time is the amount of time in this subframe
|
||||
* inv_total_time is the opposite
|
||||
* inv_timestep is the inverse of the amount of time in this frame */
|
||||
float total_time, inv_total_time, inv_timestep;
|
||||
|
||||
float radius;
|
||||
float co1[3], co2[3];
|
||||
float ve1[3], ve2[3];
|
||||
|
||||
float acc[3], boid_z;
|
||||
|
||||
int boid;
|
||||
} ParticleCollision;
|
||||
|
||||
typedef struct ParticleDrawData {
|
||||
float *vdata, *vd; /* vertice data */
|
||||
float *ndata, *nd; /* normal data */
|
||||
float *cdata, *cd; /* color data */
|
||||
float *vedata, *ved; /* velocity data */
|
||||
float *ma_col;
|
||||
int tot_vec_size, flag;
|
||||
int totpoint, totve;
|
||||
} ParticleDrawData;
|
||||
|
||||
#define PARTICLE_DRAW_DATA_UPDATED 1
|
||||
|
||||
#define PSYS_FRAND_COUNT 1024
|
||||
extern unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
|
||||
extern unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
|
||||
extern float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
|
||||
|
||||
void psys_init_rng(void);
|
||||
|
||||
BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
|
||||
{
|
||||
/* XXX far from ideal, this simply scrambles particle random numbers a bit
|
||||
* to avoid obvious correlations.
|
||||
* Can't use previous psys->frand arrays because these require initialization
|
||||
* inside psys_check_enabled, which wreaks havok in multithreaded depgraph updates.
|
||||
*/
|
||||
unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
|
||||
unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
|
||||
return PSYS_FRAND_BASE[(offset + seed * multiplier) % PSYS_FRAND_COUNT];
|
||||
}
|
||||
|
||||
BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float vec[3])
|
||||
{
|
||||
unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
|
||||
unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
|
||||
vec[0] = PSYS_FRAND_BASE[(offset + (seed + 0) * multiplier) % PSYS_FRAND_COUNT];
|
||||
vec[1] = PSYS_FRAND_BASE[(offset + (seed + 1) * multiplier) % PSYS_FRAND_COUNT];
|
||||
vec[2] = PSYS_FRAND_BASE[(offset + (seed + 2) * multiplier) % PSYS_FRAND_COUNT];
|
||||
}
|
||||
|
||||
/* ----------- functions needed outside particlesystem ---------------- */
|
||||
/* particle.c */
|
||||
int count_particles(struct ParticleSystem *psys);
|
||||
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
|
||||
|
||||
int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys);
|
||||
int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys);
|
||||
|
||||
struct ParticleSystem *psys_get_current(struct Object *ob);
|
||||
/* for rna */
|
||||
short psys_get_current_num(struct Object *ob);
|
||||
void psys_set_current_num(Object *ob, int index);
|
||||
/* UNUSED */
|
||||
// struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
|
||||
|
||||
struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
|
||||
|
||||
bool psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
|
||||
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
|
||||
bool psys_check_edited(struct ParticleSystem *psys);
|
||||
|
||||
void psys_check_group_weights(struct ParticleSettings *part);
|
||||
int psys_uses_gravity(struct ParticleSimulationData *sim);
|
||||
|
||||
/* free */
|
||||
void BKE_particlesettings_free(struct ParticleSettings *part);
|
||||
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
void psys_free(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
|
||||
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
|
||||
bool psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
|
||||
|
||||
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
|
||||
void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], struct MCol *mc);
|
||||
|
||||
void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
|
||||
|
||||
CustomDataMask psys_emitter_customdata_mask(struct ParticleSystem *psys);
|
||||
void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache,
|
||||
float fuv[4], float foffset, float vec[3], float nor[3],
|
||||
float utan[3], float vtan[3], float orco[3], float ornor[3]);
|
||||
struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name);
|
||||
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
|
||||
struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
|
||||
struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, struct ParticleSettings *part);
|
||||
void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local);
|
||||
|
||||
void psys_reset(struct ParticleSystem *psys, int mode);
|
||||
|
||||
void psys_find_parents(struct ParticleSimulationData *sim, const bool use_render_params);
|
||||
|
||||
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra, const bool use_render_params);
|
||||
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, const bool use_render_params);
|
||||
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, const bool editupdate, const bool use_render_params);
|
||||
int do_guides(struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
|
||||
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
|
||||
float psys_get_timestep(struct ParticleSimulationData *sim);
|
||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
|
||||
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
|
||||
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, const bool vel);
|
||||
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
|
||||
|
||||
/* child paths */
|
||||
void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part);
|
||||
void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part);
|
||||
void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers,
|
||||
struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
|
||||
struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys, const float parent_orco[3]);
|
||||
|
||||
void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata);
|
||||
void psys_sph_finalise(struct SPHData *sphdata);
|
||||
void psys_sph_density(struct BVHTree *tree, struct SPHData *data, float co[3], float vars[2]);
|
||||
|
||||
/* for anim.c */
|
||||
void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part,
|
||||
struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa,
|
||||
float uv[2], float orco[3]);
|
||||
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa,
|
||||
struct ParticleCacheKey *cache, float mat[4][4], float *scale);
|
||||
|
||||
void psys_thread_context_init(struct ParticleThreadContext *ctx, struct ParticleSimulationData *sim);
|
||||
void psys_thread_context_free(struct ParticleThreadContext *ctx);
|
||||
void psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int endpart, struct ParticleTask **r_tasks, int *r_numtasks);
|
||||
void psys_tasks_free(struct ParticleTask *tasks, int numtasks);
|
||||
|
||||
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
|
||||
void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
/* particle_system.c */
|
||||
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
|
||||
void psys_count_keyed_targets(struct ParticleSimulationData *sim);
|
||||
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
|
||||
void psys_changed_type(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);
|
||||
|
||||
void psys_check_boid_data(struct ParticleSystem *psys);
|
||||
|
||||
void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);
|
||||
|
||||
void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
|
||||
|
||||
/* Callback format for performing operations on ID-pointers for particle systems */
|
||||
typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
|
||||
void BKE_particlesystem_id_loop(struct ParticleSystem *psys, ParticleSystemIDFunc func, void *userdata);
|
||||
|
||||
/* ----------- functions needed only inside particlesystem ------------ */
|
||||
/* particle.c */
|
||||
void psys_disable_all(struct Object *ob);
|
||||
void psys_enable_all(struct Object *ob);
|
||||
|
||||
void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
|
||||
void free_keyed_keys(struct ParticleSystem *psys);
|
||||
void psys_free_particles(struct ParticleSystem *psys);
|
||||
void psys_free_children(struct ParticleSystem *psys);
|
||||
|
||||
void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool velocity);
|
||||
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]);
|
||||
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
|
||||
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
|
||||
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
|
||||
|
||||
float psys_get_dietime_from_cache(struct PointCache *cache, int index);
|
||||
|
||||
void psys_free_pdd(struct ParticleSystem *psys);
|
||||
|
||||
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
||||
void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra);
|
||||
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface,
|
||||
float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3],
|
||||
float orco[3], float ornor[3]);
|
||||
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
|
||||
void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time);
|
||||
|
||||
/* BLI_bvhtree_ray_cast callback */
|
||||
void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
|
||||
void psys_particle_on_dm(struct DerivedMesh *dm_final, int from, int index, int index_dmcache,
|
||||
const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
|
||||
float orco[3], float ornor[3]);
|
||||
|
||||
/* particle_system.c */
|
||||
void distribute_particles(struct ParticleSimulationData *sim, int from);
|
||||
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
|
||||
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, struct ParticleSystem *psys);
|
||||
int psys_particle_dm_face_lookup(struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
|
||||
|
||||
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
|
||||
|
||||
float psys_get_current_display_percentage(struct ParticleSystem *psys);
|
||||
|
||||
typedef struct ParticleRenderElem {
|
||||
int curchild, totchild, reduce;
|
||||
float lambda, t, scalemin, scalemax;
|
||||
} ParticleRenderElem;
|
||||
|
||||
typedef struct ParticleRenderData {
|
||||
ChildParticle *child;
|
||||
ParticleCacheKey **pathcache;
|
||||
ParticleCacheKey **childcache;
|
||||
ListBase pathcachebufs, childcachebufs;
|
||||
int totchild, totcached, totchildcache;
|
||||
struct DerivedMesh *dm;
|
||||
int totdmvert, totdmedge, totdmface;
|
||||
|
||||
float mat[4][4];
|
||||
float viewmat[4][4], winmat[4][4];
|
||||
int winx, winy;
|
||||
|
||||
int do_simplify;
|
||||
int timeoffset;
|
||||
ParticleRenderElem *elems;
|
||||
|
||||
/* ORIGINDEX */
|
||||
const int *index_mf_to_mpoly;
|
||||
const int *index_mp_to_orig;
|
||||
} ParticleRenderData;
|
||||
|
||||
/* psys_reset */
|
||||
#define PSYS_RESET_ALL 1
|
||||
#define PSYS_RESET_DEPSGRAPH 2
|
||||
/* #define PSYS_RESET_CHILDREN 3 */ /*UNUSED*/
|
||||
#define PSYS_RESET_CACHE_MISS 4
|
||||
|
||||
/* index_dmcache */
|
||||
#define DMCACHE_NOTFOUND -1
|
||||
#define DMCACHE_ISCHILD -2
|
||||
|
||||
/* **** Depsgraph evaluation **** */
|
||||
|
||||
struct EvaluationContext;
|
||||
|
||||
void BKE_particle_system_eval(struct EvaluationContext *eval_ctx,
|
||||
struct Scene *scene,
|
||||
struct Object *ob,
|
||||
struct ParticleSystem *psys);
|
||||
|
||||
#endif
|
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2006 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Campbell Barton <ideasman42@gmail.com>
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BKE_POINTCACHE_H__
|
||||
#define __BKE_POINTCACHE_H__
|
||||
|
||||
/** \file BKE_pointcache.h
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_dynamicpaint_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_boid_types.h"
|
||||
#include <stdio.h> /* for FILE */
|
||||
|
||||
/* Point cache clearing option, for BKE_ptcache_id_clear, before
|
||||
* and after are non inclusive (they wont remove the cfra) */
|
||||
#define PTCACHE_CLEAR_ALL 0
|
||||
#define PTCACHE_CLEAR_FRAME 1
|
||||
#define PTCACHE_CLEAR_BEFORE 2
|
||||
#define PTCACHE_CLEAR_AFTER 3
|
||||
|
||||
/* Point cache reset options */
|
||||
#define PTCACHE_RESET_DEPSGRAPH 0
|
||||
#define PTCACHE_RESET_BAKED 1
|
||||
#define PTCACHE_RESET_OUTDATED 2
|
||||
/* #define PTCACHE_RESET_FREE 3 */ /*UNUSED*/
|
||||
|
||||
/* Add the blendfile name after blendcache_ */
|
||||
#define PTCACHE_EXT ".bphys"
|
||||
#define PTCACHE_PATH "blendcache_"
|
||||
|
||||
/* File open options, for BKE_ptcache_file_open */
|
||||
#define PTCACHE_FILE_READ 0
|
||||
#define PTCACHE_FILE_WRITE 1
|
||||
#define PTCACHE_FILE_UPDATE 2
|
||||
|
||||
/* PTCacheID types */
|
||||
#define PTCACHE_TYPE_SOFTBODY 0
|
||||
#define PTCACHE_TYPE_PARTICLES 1
|
||||
#define PTCACHE_TYPE_CLOTH 2
|
||||
#define PTCACHE_TYPE_SMOKE_DOMAIN 3
|
||||
#define PTCACHE_TYPE_SMOKE_HIGHRES 4
|
||||
#define PTCACHE_TYPE_DYNAMICPAINT 5
|
||||
#define PTCACHE_TYPE_RIGIDBODY 6
|
||||
|
||||
/* high bits reserved for flags that need to be stored in file */
|
||||
#define PTCACHE_TYPEFLAG_COMPRESS (1 << 16)
|
||||
#define PTCACHE_TYPEFLAG_EXTRADATA (1 << 17)
|
||||
|
||||
#define PTCACHE_TYPEFLAG_TYPEMASK 0x0000FFFF
|
||||
#define PTCACHE_TYPEFLAG_FLAGMASK 0xFFFF0000
|
||||
|
||||
/* PTCache read return code */
|
||||
#define PTCACHE_READ_EXACT 1
|
||||
#define PTCACHE_READ_INTERPOLATED 2
|
||||
#define PTCACHE_READ_OLD 3
|
||||
|
||||
/* Structs */
|
||||
struct ClothModifierData;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct ParticleKey;
|
||||
struct ParticleSystem;
|
||||
struct PointCache;
|
||||
struct Scene;
|
||||
struct SmokeModifierData;
|
||||
struct SoftBody;
|
||||
struct RigidBodyWorld;
|
||||
|
||||
struct OpenVDBReader;
|
||||
struct OpenVDBWriter;
|
||||
|
||||
/* temp structure for read/write */
|
||||
typedef struct PTCacheData {
|
||||
unsigned int index;
|
||||
float loc[3];
|
||||
float vel[3];
|
||||
float rot[4];
|
||||
float ave[3];
|
||||
float size;
|
||||
float times[3];
|
||||
struct BoidData boids;
|
||||
} PTCacheData;
|
||||
|
||||
typedef struct PTCacheFile {
|
||||
FILE *fp;
|
||||
|
||||
int frame, old_format;
|
||||
unsigned int totpoint, type;
|
||||
unsigned int data_types, flag;
|
||||
|
||||
struct PTCacheData data;
|
||||
void *cur[BPHYS_TOT_DATA];
|
||||
} PTCacheFile;
|
||||
|
||||
#define PTCACHE_VEL_PER_SEC 1
|
||||
|
||||
enum {
|
||||
PTCACHE_FILE_PTCACHE = 0,
|
||||
PTCACHE_FILE_OPENVDB = 1,
|
||||
};
|
||||
|
||||
typedef struct PTCacheID {
|
||||
struct PTCacheID *next, *prev;
|
||||
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
void *calldata;
|
||||
unsigned int type, file_type;
|
||||
unsigned int stack_index;
|
||||
unsigned int flag;
|
||||
|
||||
unsigned int default_step;
|
||||
unsigned int max_step;
|
||||
|
||||
/* flags defined in DNA_object_force.h */
|
||||
unsigned int data_types, info_types;
|
||||
|
||||
/* copies point data to cache data */
|
||||
int (*write_point)(int index, void *calldata, void **data, int cfra);
|
||||
/* copies cache cata to point data */
|
||||
void (*read_point)(int index, void *calldata, void **data, float cfra, float *old_data);
|
||||
/* interpolated between previously read point data and cache data */
|
||||
void (*interpolate_point)(int index, void *calldata, void **data, float cfra, float cfra1, float cfra2, float *old_data);
|
||||
|
||||
/* copies point data to cache data */
|
||||
int (*write_stream)(PTCacheFile *pf, void *calldata);
|
||||
/* copies cache cata to point data */
|
||||
int (*read_stream)(PTCacheFile *pf, void *calldata);
|
||||
|
||||
/* copies point data to cache data */
|
||||
int (*write_openvdb_stream)(struct OpenVDBWriter *writer, void *calldata);
|
||||
/* copies cache cata to point data */
|
||||
int (*read_openvdb_stream)(struct OpenVDBReader *reader, void *calldata);
|
||||
|
||||
/* copies custom extradata to cache data */
|
||||
void (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
|
||||
/* copies custom extradata to cache data */
|
||||
void (*read_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra);
|
||||
/* copies custom extradata to cache data */
|
||||
void (*interpolate_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra, float cfra1, float cfra2);
|
||||
|
||||
/* total number of simulated points (the cfra parameter is just for using same function pointer with totwrite) */
|
||||
int (*totpoint)(void *calldata, int cfra);
|
||||
/* report error if number of points does not match */
|
||||
void (*error)(void *calldata, const char *message);
|
||||
/* number of points written for current cache frame */
|
||||
int (*totwrite)(void *calldata, int cfra);
|
||||
|
||||
int (*write_header)(PTCacheFile *pf);
|
||||
int (*read_header)(PTCacheFile *pf);
|
||||
|
||||
struct PointCache *cache;
|
||||
/* used for setting the current cache from ptcaches list */
|
||||
struct PointCache **cache_ptr;
|
||||
struct ListBase *ptcaches;
|
||||
} PTCacheID;
|
||||
|
||||
typedef struct PTCacheBaker {
|
||||
struct Main *main;
|
||||
struct Scene *scene;
|
||||
int bake;
|
||||
int render;
|
||||
int anim_init;
|
||||
int quick_step;
|
||||
struct PTCacheID pid;
|
||||
|
||||
void (*update_progress)(void *data, float progress, int *cancel);
|
||||
void *bake_job;
|
||||
} PTCacheBaker;
|
||||
|
||||
/* PTCacheEditKey->flag */
|
||||
#define PEK_SELECT 1
|
||||
#define PEK_TAG 2
|
||||
#define PEK_HIDE 4
|
||||
#define PEK_USE_WCO 8
|
||||
|
||||
typedef struct PTCacheEditKey {
|
||||
float *co;
|
||||
float *vel;
|
||||
float *rot;
|
||||
float *time;
|
||||
|
||||
float world_co[3];
|
||||
float ftime;
|
||||
float length;
|
||||
short flag;
|
||||
} PTCacheEditKey;
|
||||
|
||||
/* PTCacheEditPoint->flag */
|
||||
#define PEP_TAG 1
|
||||
#define PEP_EDIT_RECALC 2
|
||||
#define PEP_TRANSFORM 4
|
||||
#define PEP_HIDE 8
|
||||
|
||||
typedef struct PTCacheEditPoint {
|
||||
struct PTCacheEditKey *keys;
|
||||
int totkey;
|
||||
short flag;
|
||||
} PTCacheEditPoint;
|
||||
|
||||
typedef struct PTCacheUndo {
|
||||
struct PTCacheUndo *next, *prev;
|
||||
struct PTCacheEditPoint *points;
|
||||
|
||||
/* particles stuff */
|
||||
struct ParticleData *particles;
|
||||
struct KDTree *emitter_field;
|
||||
float *emitter_cosnos;
|
||||
int psys_flag;
|
||||
|
||||
/* cache stuff */
|
||||
struct ListBase mem_cache;
|
||||
|
||||
int totpoint;
|
||||
char name[64];
|
||||
} PTCacheUndo;
|
||||
|
||||
typedef struct PTCacheEdit {
|
||||
ListBase undo;
|
||||
struct PTCacheUndo *curundo;
|
||||
PTCacheEditPoint *points;
|
||||
|
||||
struct PTCacheID pid;
|
||||
|
||||
/* particles stuff */
|
||||
struct ParticleSystem *psys;
|
||||
struct KDTree *emitter_field;
|
||||
float *emitter_cosnos; /* localspace face centers and normals (average of its verts), from the derived mesh */
|
||||
int *mirror_cache;
|
||||
|
||||
struct ParticleCacheKey **pathcache; /* path cache (runtime) */
|
||||
ListBase pathcachebufs;
|
||||
|
||||
int totpoint, totframes, totcached, edited;
|
||||
|
||||
unsigned char sel_col[3];
|
||||
unsigned char nosel_col[3];
|
||||
} PTCacheEdit;
|
||||
|
||||
/* Particle functions */
|
||||
void BKE_ptcache_make_particle_key(struct ParticleKey *key, int index, void **data, float time);
|
||||
|
||||
/**************** Creating ID's ****************************/
|
||||
void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
|
||||
void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
|
||||
void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
|
||||
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
|
||||
void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, struct Object *ob, struct DynamicPaintSurface *surface);
|
||||
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
|
||||
|
||||
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis);
|
||||
|
||||
/***************** Global funcs ****************************/
|
||||
void BKE_ptcache_remove(void);
|
||||
|
||||
/************ ID specific functions ************************/
|
||||
void BKE_ptcache_id_clear(PTCacheID *id, int mode, unsigned int cfra);
|
||||
int BKE_ptcache_id_exist(PTCacheID *id, int cfra);
|
||||
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode);
|
||||
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale);
|
||||
int BKE_ptcache_object_reset(struct Scene *scene, struct Object *ob, int mode);
|
||||
|
||||
void BKE_ptcache_update_info(PTCacheID *pid);
|
||||
|
||||
/*********** General cache reading/writing ******************/
|
||||
|
||||
/* Size of cache data type. */
|
||||
int BKE_ptcache_data_size(int data_type);
|
||||
|
||||
/* Is point with indes in memory cache */
|
||||
int BKE_ptcache_mem_index_find(struct PTCacheMem *pm, unsigned int index);
|
||||
|
||||
/* Memory cache read/write helpers. */
|
||||
void BKE_ptcache_mem_pointers_init(struct PTCacheMem *pm);
|
||||
void BKE_ptcache_mem_pointers_incr(struct PTCacheMem *pm);
|
||||
int BKE_ptcache_mem_pointers_seek(int point_index, struct PTCacheMem *pm);
|
||||
|
||||
/* Main cache reading call. */
|
||||
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old);
|
||||
|
||||
/* Main cache writing call. */
|
||||
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra);
|
||||
|
||||
/******************* Allocate & free ***************/
|
||||
struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
|
||||
void BKE_ptcache_free_mem(struct ListBase *mem_cache);
|
||||
void BKE_ptcache_free(struct PointCache *cache);
|
||||
void BKE_ptcache_free_list(struct ListBase *ptcaches);
|
||||
struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, bool copy_data);
|
||||
|
||||
/********************** Baking *********************/
|
||||
|
||||
/* Bakes cache with cache_step sized jumps in time, not accurate but very fast. */
|
||||
void BKE_ptcache_quick_cache_all(struct Main *bmain, struct Scene *scene);
|
||||
|
||||
/* Bake cache or simulate to current frame with settings defined in the baker. */
|
||||
void BKE_ptcache_bake(struct PTCacheBaker *baker);
|
||||
|
||||
/* Convert disk cache to memory cache. */
|
||||
void BKE_ptcache_disk_to_mem(struct PTCacheID *pid);
|
||||
|
||||
/* Convert memory cache to disk cache. */
|
||||
void BKE_ptcache_mem_to_disk(struct PTCacheID *pid);
|
||||
|
||||
/* Convert disk cache to memory cache and vice versa. Clears the cache that was converted. */
|
||||
void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
|
||||
|
||||
/* Rename all disk cache files with a new name. Doesn't touch the actual content of the files. */
|
||||
void BKE_ptcache_disk_cache_rename(struct PTCacheID *pid, const char *name_src, const char *name_dst);
|
||||
|
||||
/* Loads simulation from external (disk) cache files. */
|
||||
void BKE_ptcache_load_external(struct PTCacheID *pid);
|
||||
|
||||
/* Set correct flags after successful simulation step */
|
||||
void BKE_ptcache_validate(struct PointCache *cache, int framenr);
|
||||
|
||||
/* Set correct flags after unsuccessful simulation step */
|
||||
void BKE_ptcache_invalidate(struct PointCache *cache);
|
||||
|
||||
#endif
|
@@ -99,7 +99,6 @@ void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
|
||||
void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
|
||||
void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
|
||||
bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime);
|
||||
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
|
||||
void BKE_rigidbody_rebuild_world(struct Scene *scene, float ctime);
|
||||
void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);
|
||||
|
||||
|
@@ -86,7 +86,7 @@ void BKE_sca_controllers_id_loop(struct ListBase *contlist, SCAControllerIDFunc
|
||||
void BKE_sca_actuators_id_loop(struct ListBase *atclist, SCAActuatorIDFunc func, void *userdata);
|
||||
|
||||
|
||||
const char *sca_state_name_get(Object *ob, short bit);
|
||||
const char *sca_state_name_get(struct Object *ob, short bit);
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -49,6 +49,7 @@ struct bScreen;
|
||||
struct uiLayout;
|
||||
struct uiList;
|
||||
struct wmKeyConfig;
|
||||
struct wmManipulatorMap;
|
||||
struct wmNotifier;
|
||||
struct wmWindow;
|
||||
struct wmWindowManager;
|
||||
@@ -96,6 +97,9 @@ typedef struct SpaceType {
|
||||
/* on startup, define dropboxes for spacetype+regions */
|
||||
void (*dropboxes)(void);
|
||||
|
||||
/* initialize manipulator-map-types and manipulator-group-types with the region */
|
||||
void (*manipulators)(void);
|
||||
|
||||
/* return context data */
|
||||
int (*context)(const struct bContext *, const char *, struct bContextDataResult *);
|
||||
|
||||
@@ -284,6 +288,8 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
|
||||
struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
|
||||
void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
|
||||
void BKE_screen_area_free(struct ScrArea *sa);
|
||||
/* Manipulator-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */
|
||||
void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *));
|
||||
|
||||
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
|
||||
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
|
||||
|
@@ -68,7 +68,7 @@ extern void sbObjectToSoftbody(struct Object *ob);
|
||||
/* pass NULL to unlink again */
|
||||
extern void sbSetInterruptCallBack(int (*f)(void));
|
||||
|
||||
extern void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3]);
|
||||
extern void SB_estimate_transform(struct Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3]);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -47,7 +47,6 @@ struct Main;
|
||||
struct Material;
|
||||
struct MTex;
|
||||
struct OceanTex;
|
||||
struct ParticleSettings;
|
||||
struct PointDensity;
|
||||
struct Tex;
|
||||
struct TexMapping;
|
||||
@@ -87,7 +86,6 @@ struct Tex *give_current_lamp_texture(struct Lamp *la);
|
||||
struct Tex *give_current_linestyle_texture(struct FreestyleLineStyle *linestyle);
|
||||
struct Tex *give_current_world_texture(struct World *world);
|
||||
struct Tex *give_current_brush_texture(struct Brush *br);
|
||||
struct Tex *give_current_particle_texture(struct ParticleSettings *part);
|
||||
|
||||
struct bNode *give_current_material_texture_node(struct Material *ma);
|
||||
|
||||
@@ -99,7 +97,6 @@ void set_current_world_texture(struct World *wo, struct Tex *tex);
|
||||
void set_current_material_texture(struct Material *ma, struct Tex *tex);
|
||||
void set_current_lamp_texture(struct Lamp *la, struct Tex *tex);
|
||||
void set_current_linestyle_texture(struct FreestyleLineStyle *linestyle, struct Tex *tex);
|
||||
void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex);
|
||||
|
||||
bool has_current_material_texture(struct Material *ma);
|
||||
|
||||
|
@@ -76,7 +76,6 @@ set(SRC
|
||||
intern/blender_undo.c
|
||||
intern/blendfile.c
|
||||
intern/bmfont.c
|
||||
intern/boids.c
|
||||
intern/bpath.c
|
||||
intern/brush.c
|
||||
intern/bullet.c
|
||||
@@ -148,13 +147,8 @@ set(SRC
|
||||
intern/outliner_treehash.c
|
||||
intern/packedFile.c
|
||||
intern/paint.c
|
||||
intern/particle.c
|
||||
intern/particle_child.c
|
||||
intern/particle_distribute.c
|
||||
intern/particle_system.c
|
||||
intern/pbvh.c
|
||||
intern/pbvh_bmesh.c
|
||||
intern/pointcache.c
|
||||
intern/property.c
|
||||
intern/report.c
|
||||
intern/rigidbody.c
|
||||
@@ -203,7 +197,6 @@ set(SRC
|
||||
BKE_blendfile.h
|
||||
BKE_bmfont.h
|
||||
BKE_bmfont_types.h
|
||||
BKE_boids.h
|
||||
BKE_bpath.h
|
||||
BKE_brush.h
|
||||
BKE_bullet.h
|
||||
@@ -268,9 +261,7 @@ set(SRC
|
||||
BKE_outliner_treehash.h
|
||||
BKE_packedFile.h
|
||||
BKE_paint.h
|
||||
BKE_particle.h
|
||||
BKE_pbvh.h
|
||||
BKE_pointcache.h
|
||||
BKE_property.h
|
||||
BKE_report.h
|
||||
BKE_rigidbody.h
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
@@ -49,7 +50,6 @@
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_report.h"
|
||||
|
@@ -88,7 +88,6 @@ bool id_type_can_have_animdata(const short id_type)
|
||||
case ID_OB:
|
||||
case ID_ME: case ID_MB: case ID_CU: case ID_AR: case ID_LT:
|
||||
case ID_KE:
|
||||
case ID_PA:
|
||||
case ID_MA: case ID_TE: case ID_NT:
|
||||
case ID_LA: case ID_CA: case ID_WO:
|
||||
case ID_LS:
|
||||
@@ -1135,9 +1134,6 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
|
||||
/* meshes */
|
||||
ANIMDATA_IDS_CB(mainptr->mesh.first);
|
||||
|
||||
/* particles */
|
||||
ANIMDATA_IDS_CB(mainptr->particle.first);
|
||||
|
||||
/* speakers */
|
||||
ANIMDATA_IDS_CB(mainptr->speaker.first);
|
||||
|
||||
@@ -1231,9 +1227,6 @@ void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const cha
|
||||
/* meshes */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->mesh.first);
|
||||
|
||||
/* particles */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->particle.first);
|
||||
|
||||
/* speakers */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->speaker.first);
|
||||
|
||||
@@ -2866,9 +2859,6 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
|
||||
/* meshes */
|
||||
EVAL_ANIM_IDS(main->mesh.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* particles */
|
||||
EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* speakers */
|
||||
EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,6 @@
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_sound_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
@@ -463,20 +462,6 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
|
||||
{
|
||||
Object *ob = (Object *)id;
|
||||
ModifierData *md;
|
||||
ParticleSystem *psys;
|
||||
|
||||
#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \
|
||||
{ \
|
||||
PointCache *cache; \
|
||||
for (cache = (ptcaches).first; cache; cache = cache->next) { \
|
||||
if (cache->flag & PTCACHE_DISK_CACHE) { \
|
||||
rewrite_path_fixed(cache->path, \
|
||||
visit_cb, \
|
||||
absbase, \
|
||||
bpath_user_data); \
|
||||
} \
|
||||
} \
|
||||
} (void)0
|
||||
|
||||
/* do via modifiers instead */
|
||||
#if 0
|
||||
@@ -492,16 +477,6 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
|
||||
rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data);
|
||||
}
|
||||
}
|
||||
else if (md->type == eModifierType_Smoke) {
|
||||
SmokeModifierData *smd = (SmokeModifierData *)md;
|
||||
if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
|
||||
BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]);
|
||||
}
|
||||
}
|
||||
else if (md->type == eModifierType_Cloth) {
|
||||
ClothModifierData *clmd = (ClothModifierData *) md;
|
||||
BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches);
|
||||
}
|
||||
else if (md->type == eModifierType_Ocean) {
|
||||
OceanModifierData *omd = (OceanModifierData *) md;
|
||||
rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data);
|
||||
@@ -512,16 +487,6 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
|
||||
}
|
||||
}
|
||||
|
||||
if (ob->soft) {
|
||||
BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
|
||||
}
|
||||
|
||||
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
|
||||
BPATH_TRAVERSE_POINTCACHE(psys->ptcaches);
|
||||
}
|
||||
|
||||
#undef BPATH_TRAVERSE_POINTCACHE
|
||||
|
||||
break;
|
||||
}
|
||||
case ID_SO:
|
||||
|
@@ -45,7 +45,6 @@
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_pointcache.h"
|
||||
|
||||
#include "BPH_mass_spring.h"
|
||||
|
||||
@@ -131,9 +130,6 @@ void cloth_init(ClothModifierData *clmd )
|
||||
|
||||
if (!clmd->sim_parms->effector_weights)
|
||||
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
|
||||
|
||||
if (clmd->point_cache)
|
||||
clmd->point_cache->step = 1;
|
||||
}
|
||||
|
||||
static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
|
||||
@@ -304,35 +300,16 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving)
|
||||
}
|
||||
}
|
||||
|
||||
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
{
|
||||
PTCacheID pid;
|
||||
|
||||
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
|
||||
|
||||
// don't do anything as long as we're in editmode!
|
||||
if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT)
|
||||
return;
|
||||
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
|
||||
}
|
||||
|
||||
static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
|
||||
{
|
||||
PointCache *cache;
|
||||
|
||||
cache= clmd->point_cache;
|
||||
|
||||
/* initialize simulation data if it didn't exist already */
|
||||
if (clmd->clothObject == NULL) {
|
||||
if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
modifier_setError(&(clmd->modifier), "Can't initialize cloth");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (clmd->clothObject == NULL) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
modifier_setError(&(clmd->modifier), "Null cloth object");
|
||||
return 0;
|
||||
}
|
||||
@@ -370,7 +347,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
mul_m4_v3(ob->obmat, verts->xconst);
|
||||
}
|
||||
|
||||
effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true);
|
||||
effectors = pdInitEffectors(clmd->scene, ob, clmd->sim_parms->effector_weights, true);
|
||||
|
||||
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH )
|
||||
cloth_update_verts ( ob, clmd, result );
|
||||
@@ -402,27 +379,14 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
************************************************/
|
||||
void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
|
||||
{
|
||||
PointCache *cache;
|
||||
PTCacheID pid;
|
||||
float timescale;
|
||||
int framenr, startframe, endframe;
|
||||
int cache_result;
|
||||
int framenr = scene->r.cfra, startframe = scene->r.sfra, endframe = scene->r.efra;
|
||||
|
||||
clmd->scene= scene; /* nice to pass on later :) */
|
||||
framenr= (int)scene->r.cfra;
|
||||
cache= clmd->point_cache;
|
||||
|
||||
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
|
||||
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
|
||||
clmd->sim_parms->timescale= timescale * clmd->sim_parms->time_scale;
|
||||
clmd->sim_parms->timescale = 1.0f;
|
||||
|
||||
if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->mvert_num)) {
|
||||
clmd->sim_parms->reset = 0;
|
||||
cache->flag |= PTCACHE_OUTDATED;
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
BKE_ptcache_validate(cache, 0);
|
||||
cache->last_exact= 0;
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
}
|
||||
|
||||
// unused in the moment, calculated separately in implicit.c
|
||||
@@ -430,7 +394,6 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
|
||||
|
||||
/* simulation is only active during a specific period */
|
||||
if (framenr < startframe) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
return;
|
||||
}
|
||||
else if (framenr > endframe) {
|
||||
@@ -442,59 +405,18 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
|
||||
return;
|
||||
|
||||
if (framenr == startframe) {
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
do_init_cloth(ob, clmd, dm, framenr);
|
||||
BKE_ptcache_validate(cache, framenr);
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to read from cache */
|
||||
bool can_simulate = (framenr == clmd->clothObject->last_frame+1) && !(cache->flag & PTCACHE_BAKED);
|
||||
|
||||
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate);
|
||||
|
||||
if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED ||
|
||||
(!can_simulate && cache_result == PTCACHE_READ_OLD)) {
|
||||
BKE_cloth_solver_set_positions(clmd);
|
||||
cloth_to_object (ob, clmd, vertexCos);
|
||||
|
||||
BKE_ptcache_validate(cache, framenr);
|
||||
|
||||
if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
|
||||
BKE_ptcache_write(&pid, framenr);
|
||||
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (cache_result==PTCACHE_READ_OLD) {
|
||||
BKE_cloth_solver_set_positions(clmd);
|
||||
}
|
||||
else if ( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
|
||||
/* if baked and nothing in cache, do nothing */
|
||||
BKE_ptcache_invalidate(cache);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!can_simulate)
|
||||
if (framenr!=clmd->clothObject->last_frame+1)
|
||||
return;
|
||||
|
||||
/* if on second frame, write cache for first frame */
|
||||
if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
|
||||
BKE_ptcache_write(&pid, startframe);
|
||||
|
||||
clmd->sim_parms->timescale *= framenr - cache->simframe;
|
||||
clmd->sim_parms->timescale *= 1.0f;
|
||||
|
||||
/* do simulation */
|
||||
BKE_ptcache_validate(cache, framenr);
|
||||
|
||||
if (!do_step_cloth(ob, clmd, dm, framenr)) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
}
|
||||
else
|
||||
BKE_ptcache_write(&pid, framenr);
|
||||
do_step_cloth(ob, clmd, dm, framenr);
|
||||
|
||||
cloth_to_object (ob, clmd, vertexCos);
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
|
@@ -925,7 +925,6 @@ int CTX_data_mode_enum(const bContext *C)
|
||||
else if (ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
|
||||
else if (ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
|
||||
else if (ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
|
||||
else if (ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,7 +947,6 @@ static const char *data_mode_strings[] = {
|
||||
"weightpaint",
|
||||
"vertexpaint",
|
||||
"imagepaint",
|
||||
"particlemode",
|
||||
"objectmode",
|
||||
NULL
|
||||
};
|
||||
|
@@ -54,6 +54,8 @@
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
@@ -81,8 +83,6 @@
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_tracking.h"
|
||||
@@ -478,7 +478,7 @@ void dag_add_collision_relations(DagForest *dag, Scene *scene, Object *ob, DagNo
|
||||
|
||||
void dag_add_forcefield_relations(DagForest *dag, Scene *scene, Object *ob, DagNode *node, EffectorWeights *effector_weights, bool add_absorption, int skip_forcefield, const char *name)
|
||||
{
|
||||
ListBase *effectors = pdInitEffectors(scene, ob, NULL, effector_weights, false);
|
||||
ListBase *effectors = pdInitEffectors(scene, ob, effector_weights, false);
|
||||
|
||||
if (effectors) {
|
||||
for (EffectorCache *eff = effectors->first; eff; eff = eff->next) {
|
||||
@@ -507,7 +507,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc
|
||||
DagNode *node2;
|
||||
DagNode *node3;
|
||||
Key *key;
|
||||
ParticleSystem *psys;
|
||||
int addtoroot = 1;
|
||||
|
||||
node = dag_get_node(dag, ob);
|
||||
@@ -749,79 +748,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc
|
||||
dag_add_lamp_driver_relations(dag, node, ob->data);
|
||||
}
|
||||
|
||||
/* particles */
|
||||
psys = ob->particlesystem.first;
|
||||
if (psys) {
|
||||
GroupObject *go;
|
||||
|
||||
for (; psys; psys = psys->next) {
|
||||
BoidRule *rule = NULL;
|
||||
BoidState *state = NULL;
|
||||
ParticleSettings *part = psys->part;
|
||||
|
||||
if (part->adt) {
|
||||
dag_add_driver_relation(part->adt, dag, node, 1);
|
||||
}
|
||||
|
||||
dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
|
||||
|
||||
if (!psys_check_enabled(ob, psys, G.is_rendering))
|
||||
continue;
|
||||
|
||||
if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
|
||||
ParticleTarget *pt = psys->targets.first;
|
||||
|
||||
for (; pt; pt = pt->next) {
|
||||
if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
|
||||
node2 = dag_get_node(dag, pt->ob);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
|
||||
node2 = dag_get_node(dag, part->dup_ob);
|
||||
/* note that this relation actually runs in the wrong direction, the problem
|
||||
* is that dupli system all have this (due to parenting), and the render
|
||||
* engine instancing assumes particular ordering of objects in list */
|
||||
dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
|
||||
if (part->dup_ob->type == OB_MBALL)
|
||||
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
|
||||
}
|
||||
|
||||
if (part->ren_as == PART_DRAW_GR && part->dup_group) {
|
||||
for (go = part->dup_group->gobject.first; go; go = go->next) {
|
||||
node2 = dag_get_node(dag, go->ob);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
|
||||
}
|
||||
}
|
||||
|
||||
if (part->type != PART_HAIR) {
|
||||
/* Actual code uses get_collider_cache */
|
||||
dag_add_collision_relations(dag, scene, ob, node, part->collision_group, ob->lay, eModifierType_Collision, NULL, true, "Particle Collision");
|
||||
}
|
||||
|
||||
dag_add_forcefield_relations(dag, scene, ob, node, part->effector_weights, part->type == PART_HAIR, 0, "Particle Force Field");
|
||||
|
||||
if (part->boids) {
|
||||
for (state = part->boids->states.first; state; state = state->next) {
|
||||
for (rule = state->rules.first; rule; rule = rule->next) {
|
||||
Object *ruleob = NULL;
|
||||
if (rule->type == eBoidRuleType_Avoid)
|
||||
ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
|
||||
else if (rule->type == eBoidRuleType_FollowLeader)
|
||||
ruleob = ((BoidRuleFollowLeader *)rule)->ob;
|
||||
|
||||
if (ruleob) {
|
||||
node2 = dag_get_node(dag, ruleob);
|
||||
dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Boid Rule");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* object constraints */
|
||||
for (con = ob->constraints.first; con; con = con->next) {
|
||||
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
|
||||
@@ -1887,38 +1813,6 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
|
||||
return node->lay;
|
||||
}
|
||||
|
||||
/* node was checked to have lasttime != curtime, and is of type ID_OB */
|
||||
static void flush_pointcache_reset(Main *bmain, Scene *scene, DagNode *node,
|
||||
int curtime, unsigned int lay, bool reset)
|
||||
{
|
||||
DagAdjList *itA;
|
||||
Object *ob;
|
||||
|
||||
node->lasttime = curtime;
|
||||
|
||||
for (itA = node->child; itA; itA = itA->next) {
|
||||
if (itA->node->type == ID_OB) {
|
||||
if (itA->node->lasttime != curtime) {
|
||||
ob = (Object *)(itA->node->ob);
|
||||
|
||||
if (reset || (ob->recalc & OB_RECALC_ALL)) {
|
||||
if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) {
|
||||
/* Don't tag nodes which are on invisible layer. */
|
||||
if (itA->node->lay & lay) {
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
lib_id_recalc_data_tag(bmain, &ob->id);
|
||||
}
|
||||
}
|
||||
|
||||
flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, true);
|
||||
}
|
||||
else
|
||||
flush_pointcache_reset(bmain, scene, itA->node, curtime, lay, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* flush layer flags to dependencies */
|
||||
static void dag_scene_flush_layers(Scene *sce, int lay)
|
||||
{
|
||||
@@ -1996,7 +1890,6 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
|
||||
{
|
||||
DagNode *firstnode;
|
||||
DagAdjList *itA;
|
||||
Object *ob;
|
||||
int lasttime;
|
||||
|
||||
if (!DEG_depsgraph_use_legacy()) {
|
||||
@@ -2024,24 +1917,6 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
|
||||
if (!time) {
|
||||
sce->theDag->time++; /* so we know which nodes were accessed */
|
||||
lasttime = sce->theDag->time;
|
||||
for (itA = firstnode->child; itA; itA = itA->next) {
|
||||
if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) {
|
||||
ob = (Object *)(itA->node->ob);
|
||||
|
||||
if (ob->recalc & OB_RECALC_ALL) {
|
||||
if (BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) {
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
lib_id_recalc_data_tag(bmain, &ob->id);
|
||||
}
|
||||
|
||||
flush_pointcache_reset(bmain, sce, itA->node, lasttime,
|
||||
lay, true);
|
||||
}
|
||||
else
|
||||
flush_pointcache_reset(bmain, sce, itA->node, lasttime,
|
||||
lay, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dag_tag_renderlayers(sce, lay);
|
||||
@@ -2234,8 +2109,6 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
}
|
||||
}
|
||||
if (ob->particlesystem.first)
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
@@ -2274,17 +2147,6 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
adt->recalc |= ADT_RECALC_ANIM;
|
||||
}
|
||||
|
||||
if (ob->particlesystem.first) {
|
||||
ParticleSystem *psys = ob->particlesystem.first;
|
||||
|
||||
for (; psys; psys = psys->next) {
|
||||
if (psys_check_enabled(ob, psys, G.is_rendering)) {
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ob->recalc & OB_RECALC_OB)
|
||||
@@ -2576,7 +2438,6 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
|
||||
/* set flags & pointcache for object */
|
||||
if (GS(id->name) == ID_OB) {
|
||||
ob = (Object *)id;
|
||||
BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
|
||||
|
||||
/* So if someone tagged object recalc directly,
|
||||
* id_tag_update bit-field stays relevant
|
||||
@@ -2607,7 +2468,6 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
|
||||
if (!(ob && obt == ob) && obt->data == id) {
|
||||
obt->recalc |= OB_RECALC_DATA;
|
||||
lib_id_recalc_data_tag(bmain, &obt->id);
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2635,30 +2495,6 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
|
||||
obt->recalc |= OB_RECALC_DATA;
|
||||
lib_id_recalc_data_tag(bmain, &obt->id);
|
||||
}
|
||||
|
||||
/* particle settings can use the texture as well */
|
||||
if (obt->particlesystem.first) {
|
||||
ParticleSystem *psys = obt->particlesystem.first;
|
||||
MTex **mtexp, *mtex;
|
||||
int a;
|
||||
for (; psys; psys = psys->next) {
|
||||
mtexp = psys->part->mtex;
|
||||
for (a = 0; a < MAX_MTEX; a++, mtexp++) {
|
||||
mtex = *mtexp;
|
||||
if (mtex && mtex->tex == (Tex *)id) {
|
||||
obt->recalc |= OB_RECALC_DATA;
|
||||
lib_id_recalc_data_tag(bmain, &obt->id);
|
||||
|
||||
if (mtex->mapto & PAMAP_INIT)
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
if (mtex->mapto & PAMAP_CHILD)
|
||||
psys->recalc |= PSYS_RECALC_CHILD;
|
||||
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2670,20 +2506,10 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
|
||||
obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
|
||||
lib_id_recalc_tag(bmain, &obt->id);
|
||||
lib_id_recalc_data_tag(bmain, &obt->id);
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set flags based on particle settings */
|
||||
if (idtype == ID_PA) {
|
||||
ParticleSystem *psys;
|
||||
for (obt = bmain->object.first; obt; obt = obt->id.next)
|
||||
for (psys = obt->particlesystem.first; psys; psys = psys->next)
|
||||
if (&psys->part->id == id)
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
|
||||
if (ELEM(idtype, ID_MA, ID_TE)) {
|
||||
obt = sce->basact ? sce->basact->object : NULL;
|
||||
if (obt && obt->mode & OB_MODE_TEXTURE_PAINT) {
|
||||
@@ -2953,7 +2779,7 @@ void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
|
||||
if (flag) {
|
||||
if (flag & OB_RECALC_OB)
|
||||
lib_id_recalc_tag(bmain, id);
|
||||
if (flag & (OB_RECALC_DATA | PSYS_RECALC))
|
||||
if (flag & OB_RECALC_DATA)
|
||||
lib_id_recalc_data_tag(bmain, id);
|
||||
}
|
||||
else
|
||||
@@ -2969,20 +2795,6 @@ void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
|
||||
ob = (Object *)id;
|
||||
ob->recalc |= (flag & OB_RECALC_ALL);
|
||||
}
|
||||
else if (idtype == ID_PA) {
|
||||
ParticleSystem *psys;
|
||||
/* this is weak still, should be done delayed as well */
|
||||
for (ob = bmain->object.first; ob; ob = ob->id.next) {
|
||||
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
|
||||
if (&psys->part->id == id) {
|
||||
ob->recalc |= (flag & OB_RECALC_ALL);
|
||||
psys->recalc |= (flag & PSYS_RECALC);
|
||||
lib_id_recalc_tag(bmain, &ob->id);
|
||||
lib_id_recalc_data_tag(bmain, &ob->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* disable because this is called on various ID types automatically.
|
||||
* where printing warning is not useful. for now just ignore */
|
||||
|
@@ -48,6 +48,7 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
@@ -68,8 +69,6 @@
|
||||
#include "BKE_mesh_mapping.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
@@ -563,7 +562,7 @@ static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
|
||||
}
|
||||
|
||||
/* check whether bounds intersects a point with given radius */
|
||||
static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
|
||||
static bool UNUSED_FUNCTION(boundIntersectPoint)(Bounds3D *b, float point[3], const float radius)
|
||||
{
|
||||
if (!b->valid)
|
||||
return false;
|
||||
@@ -862,7 +861,7 @@ static void surface_freeUnusedData(DynamicPaintSurface *surface)
|
||||
return;
|
||||
|
||||
/* free bakedata if not active or surface is baked */
|
||||
if (!(surface->flags & MOD_DPAINT_ACTIVE) || (surface->pointcache && surface->pointcache->flag & PTCACHE_BAKED)) {
|
||||
if (!(surface->flags & MOD_DPAINT_ACTIVE)) {
|
||||
free_bakeData(surface->data);
|
||||
}
|
||||
}
|
||||
@@ -897,10 +896,6 @@ void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
|
||||
|
||||
void dynamicPaint_freeSurface(DynamicPaintSurface *surface)
|
||||
{
|
||||
/* point cache */
|
||||
BKE_ptcache_free_list(&(surface->ptcaches));
|
||||
surface->pointcache = NULL;
|
||||
|
||||
if (surface->effector_weights)
|
||||
MEM_freeN(surface->effector_weights);
|
||||
surface->effector_weights = NULL;
|
||||
@@ -961,11 +956,6 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c
|
||||
surface->format = MOD_DPAINT_SURFACE_F_VERTEX;
|
||||
surface->type = MOD_DPAINT_SURFACE_T_PAINT;
|
||||
|
||||
/* cache */
|
||||
surface->pointcache = BKE_ptcache_add(&(surface->ptcaches));
|
||||
surface->pointcache->flag |= PTCACHE_DISK_CACHE;
|
||||
surface->pointcache->step = 1;
|
||||
|
||||
/* Set initial values */
|
||||
surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_DISSOLVE_LOG |
|
||||
MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING;
|
||||
@@ -1056,8 +1046,6 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
|
||||
return false;
|
||||
brush->pmd = pmd;
|
||||
|
||||
brush->psys = NULL;
|
||||
|
||||
brush->flags = MOD_DPAINT_ABS_ALPHA | MOD_DPAINT_RAMP_ALPHA;
|
||||
brush->collision = MOD_DPAINT_COL_VOLUME;
|
||||
|
||||
@@ -1211,7 +1199,6 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn
|
||||
t_brush->particle_radius = brush->particle_radius;
|
||||
t_brush->particle_smooth = brush->particle_smooth;
|
||||
t_brush->paint_distance = brush->paint_distance;
|
||||
t_brush->psys = brush->psys;
|
||||
|
||||
if (brush->paint_ramp)
|
||||
memcpy(t_brush->paint_ramp, brush->paint_ramp, sizeof(ColorBand));
|
||||
@@ -1944,15 +1931,6 @@ static DerivedMesh *dynamicPaint_Modifier_apply(
|
||||
return result;
|
||||
}
|
||||
|
||||
/* update cache frame range */
|
||||
void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
|
||||
{
|
||||
if (surface->pointcache) {
|
||||
surface->pointcache->startframe = surface->start_frame;
|
||||
surface->pointcache->endframe = surface->end_frame;
|
||||
}
|
||||
}
|
||||
|
||||
static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm)
|
||||
{
|
||||
if (canvas->dm) {
|
||||
@@ -2001,31 +1979,10 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
|
||||
if (no_surface_data || current_frame != surface->current_frame ||
|
||||
(int)scene->r.cfra == surface->start_frame)
|
||||
{
|
||||
PointCache *cache = surface->pointcache;
|
||||
PTCacheID pid;
|
||||
surface->current_frame = current_frame;
|
||||
|
||||
/* read point cache */
|
||||
BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
|
||||
pid.cache->startframe = surface->start_frame;
|
||||
pid.cache->endframe = surface->end_frame;
|
||||
BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, NULL, NULL, NULL);
|
||||
|
||||
/* reset non-baked cache at first frame */
|
||||
if ((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) {
|
||||
cache->flag |= PTCACHE_REDO_NEEDED;
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
}
|
||||
|
||||
/* try to read from cache */
|
||||
bool can_simulate = ((int)scene->r.cfra == current_frame) && !(cache->flag & PTCACHE_BAKED);
|
||||
|
||||
if (BKE_ptcache_read(&pid, (float)scene->r.cfra, can_simulate)) {
|
||||
BKE_ptcache_validate(cache, (int)scene->r.cfra);
|
||||
}
|
||||
/* if read failed and we're on surface range do recalculate */
|
||||
else if (can_simulate) {
|
||||
/* if we're on surface range do recalculate */
|
||||
if ((int)scene->r.cfra == current_frame) {
|
||||
/* calculate surface frame */
|
||||
canvas->flags |= MOD_DPAINT_BAKING;
|
||||
dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
|
||||
@@ -2037,9 +1994,6 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
|
||||
{
|
||||
canvas_copyDerivedMesh(canvas, dm);
|
||||
}
|
||||
|
||||
BKE_ptcache_validate(cache, surface->current_frame);
|
||||
BKE_ptcache_write(&pid, surface->current_frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3499,7 +3453,6 @@ typedef struct DynamicPaintPaintData {
|
||||
const float *avg_brushNor;
|
||||
const Vec3f *brushVelocity;
|
||||
|
||||
const ParticleSystem *psys;
|
||||
const float solidradius;
|
||||
|
||||
void *treeData;
|
||||
@@ -3948,283 +3901,6 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Paint a particle system to the surface
|
||||
*/
|
||||
static void dynamic_paint_paint_particle_cell_point_cb_ex(
|
||||
void *userdata, void *UNUSED(userdata_chunk), const int id, const int UNUSED(threadid))
|
||||
{
|
||||
const DynamicPaintPaintData *data = userdata;
|
||||
|
||||
const DynamicPaintSurface *surface = data->surface;
|
||||
const PaintSurfaceData *sData = surface->data;
|
||||
const PaintBakeData *bData = sData->bData;
|
||||
VolumeGrid *grid = bData->grid;
|
||||
|
||||
const DynamicPaintBrushSettings *brush = data->brush;
|
||||
|
||||
const ParticleSystem *psys = data->psys;
|
||||
|
||||
const float timescale = data->timescale;
|
||||
const int c_index = data->c_index;
|
||||
|
||||
KDTree *tree = data->treeData;
|
||||
|
||||
const float solidradius = data->solidradius;
|
||||
const float smooth = brush->particle_smooth * surface->radius_scale;
|
||||
const float range = solidradius + smooth;
|
||||
const float particle_timestep = 0.04f * psys->part->timetweak;
|
||||
|
||||
const int index = grid->t_index[grid->s_pos[c_index] + id];
|
||||
float disp_intersect = 0.0f;
|
||||
float radius = 0.0f;
|
||||
float strength = 0.0f;
|
||||
int part_index = -1;
|
||||
|
||||
/*
|
||||
* With predefined radius, there is no variation between particles.
|
||||
* It's enough to just find the nearest one.
|
||||
*/
|
||||
{
|
||||
KDTreeNearest nearest;
|
||||
float smooth_range, part_solidradius;
|
||||
|
||||
/* Find nearest particle and get distance to it */
|
||||
BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, &nearest);
|
||||
/* if outside maximum range, no other particle can influence either */
|
||||
if (nearest.dist > range)
|
||||
return;
|
||||
|
||||
if (brush->flags & MOD_DPAINT_PART_RAD) {
|
||||
/* use particles individual size */
|
||||
ParticleData *pa = psys->particles + nearest.index;
|
||||
part_solidradius = pa->size;
|
||||
}
|
||||
else {
|
||||
part_solidradius = solidradius;
|
||||
}
|
||||
radius = part_solidradius + smooth;
|
||||
if (nearest.dist < radius) {
|
||||
/* distances inside solid radius has maximum influence -> dist = 0 */
|
||||
smooth_range = max_ff(0.0f, (nearest.dist - part_solidradius));
|
||||
/* do smoothness if enabled */
|
||||
if (smooth)
|
||||
smooth_range /= smooth;
|
||||
|
||||
strength = 1.0f - smooth_range;
|
||||
disp_intersect = radius - nearest.dist;
|
||||
part_index = nearest.index;
|
||||
}
|
||||
}
|
||||
/* If using random per particle radius and closest particle didn't give max influence */
|
||||
if (brush->flags & MOD_DPAINT_PART_RAD && strength < 1.0f && psys->part->randsize > 0.0f) {
|
||||
/*
|
||||
* If we use per particle radius, we have to sample all particles
|
||||
* within max radius range
|
||||
*/
|
||||
KDTreeNearest *nearest;
|
||||
|
||||
float smooth_range = smooth * (1.0f - strength), dist;
|
||||
/* calculate max range that can have particles with higher influence than the nearest one */
|
||||
const float max_range = smooth - strength * smooth + solidradius;
|
||||
/* Make gcc happy! */
|
||||
dist = max_range;
|
||||
|
||||
const int particles = BLI_kdtree_range_search(
|
||||
tree, bData->realCoord[bData->s_pos[index]].v, &nearest, max_range);
|
||||
|
||||
/* Find particle that produces highest influence */
|
||||
for (int n = 0; n < particles; n++) {
|
||||
ParticleData *pa = &psys->particles[nearest[n].index];
|
||||
|
||||
/* skip if out of range */
|
||||
if (nearest[n].dist > (pa->size + smooth))
|
||||
continue;
|
||||
|
||||
/* update hit data */
|
||||
const float s_range = nearest[n].dist - pa->size;
|
||||
/* skip if higher influence is already found */
|
||||
if (smooth_range < s_range)
|
||||
continue;
|
||||
|
||||
/* update hit data */
|
||||
smooth_range = s_range;
|
||||
dist = nearest[n].dist;
|
||||
part_index = nearest[n].index;
|
||||
|
||||
/* If inside solid range and no disp depth required, no need to seek further */
|
||||
if ((s_range < 0.0f) && !ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nearest)
|
||||
MEM_freeN(nearest);
|
||||
|
||||
/* now calculate influence for this particle */
|
||||
const float rad = radius + smooth;
|
||||
if ((rad - dist) > disp_intersect) {
|
||||
disp_intersect = radius - dist;
|
||||
radius = rad;
|
||||
}
|
||||
|
||||
/* do smoothness if enabled */
|
||||
CLAMP_MIN(smooth_range, 0.0f);
|
||||
if (smooth)
|
||||
smooth_range /= smooth;
|
||||
|
||||
const float str = 1.0f - smooth_range;
|
||||
/* if influence is greater, use this one */
|
||||
if (str > strength)
|
||||
strength = str;
|
||||
}
|
||||
|
||||
if (strength > 0.001f) {
|
||||
float paintColor[4] = {0.0f};
|
||||
float depth = 0.0f;
|
||||
float velocity_val = 0.0f;
|
||||
|
||||
/* apply velocity */
|
||||
if ((brush->flags & MOD_DPAINT_USES_VELOCITY) && (part_index != -1)) {
|
||||
float velocity[3];
|
||||
ParticleData *pa = psys->particles + part_index;
|
||||
mul_v3_v3fl(velocity, pa->state.vel, particle_timestep);
|
||||
|
||||
/* substract canvas point velocity */
|
||||
if (bData->velocity) {
|
||||
sub_v3_v3(velocity, bData->velocity[index].v);
|
||||
}
|
||||
velocity_val = normalize_v3(velocity);
|
||||
|
||||
/* store brush velocity for smudge */
|
||||
if ((surface->type == MOD_DPAINT_SURFACE_T_PAINT) &&
|
||||
(brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity))
|
||||
{
|
||||
copy_v3_v3(&bData->brush_velocity[index * 4], velocity);
|
||||
bData->brush_velocity[index * 4 + 3] = velocity_val;
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
|
||||
copy_v3_v3(paintColor, &brush->r);
|
||||
}
|
||||
else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) {
|
||||
/* get displace depth */
|
||||
disp_intersect = (1.0f - sqrtf(disp_intersect / radius)) * radius;
|
||||
depth = max_ff(0.0f, (radius - disp_intersect) / bData->bNormal[index].normal_scale);
|
||||
}
|
||||
|
||||
dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
|
||||
}
|
||||
}
|
||||
|
||||
static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
|
||||
ParticleSystem *psys,
|
||||
DynamicPaintBrushSettings *brush,
|
||||
float timescale)
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
PaintSurfaceData *sData = surface->data;
|
||||
PaintBakeData *bData = sData->bData;
|
||||
VolumeGrid *grid = bData->grid;
|
||||
|
||||
KDTree *tree;
|
||||
int particlesAdded = 0;
|
||||
int invalidParticles = 0;
|
||||
int p = 0;
|
||||
|
||||
const float solidradius = surface->radius_scale *
|
||||
((brush->flags & MOD_DPAINT_PART_RAD) ? part->size : brush->particle_radius);
|
||||
const float smooth = brush->particle_smooth * surface->radius_scale;
|
||||
|
||||
const float range = solidradius + smooth;
|
||||
|
||||
Bounds3D part_bb = {{0}};
|
||||
|
||||
if (psys->totpart < 1)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Build a kd-tree to optimize distance search
|
||||
*/
|
||||
tree = BLI_kdtree_new(psys->totpart);
|
||||
|
||||
/* loop through particles and insert valid ones to the tree */
|
||||
p = 0;
|
||||
for (ParticleData *pa = psys->particles; p < psys->totpart; p++, pa++) {
|
||||
/* Proceed only if particle is active */
|
||||
if ((pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ||
|
||||
(pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ||
|
||||
(pa->flag & PARS_UNEXIST))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* for debug purposes check if any NAN particle proceeds
|
||||
* For some reason they get past activity check, this should rule most of them out */
|
||||
if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {
|
||||
invalidParticles++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* make sure particle is close enough to canvas */
|
||||
if (!boundIntersectPoint(&grid->grid_bounds, pa->state.co, range))
|
||||
continue;
|
||||
|
||||
BLI_kdtree_insert(tree, p, pa->state.co);
|
||||
|
||||
/* calc particle system bounds */
|
||||
boundInsert(&part_bb, pa->state.co);
|
||||
|
||||
particlesAdded++;
|
||||
}
|
||||
if (invalidParticles)
|
||||
printf("Warning: Invalid particle(s) found!\n");
|
||||
|
||||
/* If no suitable particles were found, exit */
|
||||
if (particlesAdded < 1) {
|
||||
BLI_kdtree_free(tree);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* begin thread safe malloc */
|
||||
BLI_begin_threaded_malloc();
|
||||
|
||||
/* only continue if particle bb is close enough to canvas bb */
|
||||
if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) {
|
||||
int c_index;
|
||||
int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
|
||||
|
||||
/* balance tree */
|
||||
BLI_kdtree_balance(tree);
|
||||
|
||||
/* loop through space partitioning grid */
|
||||
for (c_index = 0; c_index < total_cells; c_index++) {
|
||||
/* check cell bounding box */
|
||||
if (!grid->s_num[c_index] ||
|
||||
!boundsIntersectDist(&grid->bounds[c_index], &part_bb, range))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* loop through cell points */
|
||||
DynamicPaintPaintData data = {
|
||||
.surface = surface,
|
||||
.brush = brush, .psys = psys,
|
||||
.solidradius = solidradius, .timescale = timescale, .c_index = c_index,
|
||||
.treeData = tree,
|
||||
};
|
||||
BLI_task_parallel_range_ex(0, grid->s_num[c_index], &data, NULL, 0,
|
||||
dynamic_paint_paint_particle_cell_point_cb_ex,
|
||||
grid->s_num[c_index] > 250, true);
|
||||
}
|
||||
}
|
||||
BLI_end_threaded_malloc();
|
||||
BLI_kdtree_free(tree);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* paint a single point of defined proximity radius to the surface */
|
||||
static void dynamic_paint_paint_single_point_cb_ex(
|
||||
void *userdata, void *UNUSED(userdata_chunk), const int index, const int UNUSED(threadid))
|
||||
@@ -4658,7 +4334,7 @@ static int dynamicPaint_prepareEffectStep(
|
||||
|
||||
/* Init force data if required */
|
||||
if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
|
||||
ListBase *effectors = pdInitEffectors(scene, ob, NULL, surface->effector_weights, true);
|
||||
ListBase *effectors = pdInitEffectors(scene, ob, surface->effector_weights, true);
|
||||
|
||||
/* allocate memory for force data (dir vector + strength) */
|
||||
*force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces");
|
||||
@@ -5562,20 +5238,8 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
|
||||
dynamicPaint_updateBrushMaterials(brushObj, brush->mat, scene, &bMats);
|
||||
|
||||
/* Apply brush on the surface depending on it's collision type */
|
||||
/* Particle brush: */
|
||||
if (brush->collision == MOD_DPAINT_COL_PSYS) {
|
||||
if (brush->psys && brush->psys->part &&
|
||||
ELEM(brush->psys->part->type, PART_EMITTER, PART_FLUID) &&
|
||||
psys_check_enabled(brushObj, brush->psys, G.is_rendering))
|
||||
{
|
||||
/* Paint a particle system */
|
||||
BKE_animsys_evaluate_animdata(scene, &brush->psys->part->id, brush->psys->part->adt,
|
||||
BKE_scene_frame_get(scene), ADT_RECALC_ANIM);
|
||||
dynamicPaint_paintParticles(surface, brush->psys, brush, timescale);
|
||||
}
|
||||
}
|
||||
/* Object center distance: */
|
||||
else if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) {
|
||||
if (brush->collision == MOD_DPAINT_COL_POINT && brushObj != ob) {
|
||||
dynamicPaint_paintSinglePoint(surface, brushObj->loc, brush, brushObj, &bMats, scene, timescale);
|
||||
}
|
||||
/* Mesh volume/proximity: */
|
||||
|
@@ -43,7 +43,6 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
@@ -67,7 +66,6 @@
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_smoke.h"
|
||||
|
||||
@@ -145,12 +143,11 @@ void free_partdeflect(PartDeflect *pd)
|
||||
MEM_freeN(pd);
|
||||
}
|
||||
|
||||
static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
|
||||
static EffectorCache *new_effector_cache(Scene *scene, Object *ob, PartDeflect *pd)
|
||||
{
|
||||
EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
|
||||
eff->scene = scene;
|
||||
eff->ob = ob;
|
||||
eff->psys = psys;
|
||||
eff->pd = pd;
|
||||
eff->frame = -1;
|
||||
return eff;
|
||||
@@ -173,40 +170,16 @@ static void add_object_to_effectors(ListBase **effectors, Scene *scene, Effector
|
||||
if (*effectors == NULL)
|
||||
*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
|
||||
|
||||
eff = new_effector_cache(scene, ob, NULL, ob->pd);
|
||||
eff = new_effector_cache(scene, ob, ob->pd);
|
||||
|
||||
/* make sure imat is up to date */
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
|
||||
BLI_addtail(*effectors, eff);
|
||||
}
|
||||
static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
|
||||
{
|
||||
ParticleSettings *part= psys->part;
|
||||
|
||||
if ( !psys_check_enabled(ob, psys, G.is_rendering) )
|
||||
return;
|
||||
|
||||
if ( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0)
|
||||
return;
|
||||
|
||||
if ( part->pd && part->pd->forcefield && (!for_simulation || weights->weight[part->pd->forcefield] != 0.0f)) {
|
||||
if (*effectors == NULL)
|
||||
*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
|
||||
|
||||
BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd));
|
||||
}
|
||||
|
||||
if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) {
|
||||
if (*effectors == NULL)
|
||||
*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
|
||||
|
||||
BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd2));
|
||||
}
|
||||
}
|
||||
|
||||
/* returns ListBase handle with objects taking part in the effecting */
|
||||
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
|
||||
ListBase *pdInitEffectors(Scene *scene, Object *ob_src,
|
||||
EffectorWeights *weights, bool for_simulation)
|
||||
{
|
||||
Base *base;
|
||||
@@ -220,13 +193,6 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
|
||||
if ( (go->ob->lay & layer) ) {
|
||||
if ( go->ob->pd && go->ob->pd->forcefield )
|
||||
add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src, for_simulation);
|
||||
|
||||
if ( go->ob->particlesystem.first ) {
|
||||
ParticleSystem *psys= go->ob->particlesystem.first;
|
||||
|
||||
for ( ; psys; psys=psys->next )
|
||||
add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src, for_simulation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,13 +201,6 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
|
||||
if ( (base->lay & layer) ) {
|
||||
if ( base->object->pd && base->object->pd->forcefield )
|
||||
add_object_to_effectors(&effectors, scene, weights, base->object, ob_src, for_simulation);
|
||||
|
||||
if ( base->object->particlesystem.first ) {
|
||||
ParticleSystem *psys= base->object->particlesystem.first;
|
||||
|
||||
for ( ; psys; psys=psys->next )
|
||||
add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,8 +253,6 @@ static void precalculate_effector(EffectorCache *eff)
|
||||
if (eff->ob->type == OB_CURVE)
|
||||
eff->flag |= PE_USE_NORMAL_DATA;
|
||||
}
|
||||
else if (eff->psys)
|
||||
psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
|
||||
|
||||
/* Store object velocity */
|
||||
if (eff->ob) {
|
||||
@@ -318,36 +275,6 @@ void pdPrecalculateEffectors(ListBase *effectors)
|
||||
}
|
||||
|
||||
|
||||
void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point)
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
point->loc = state->co;
|
||||
point->vel = state->vel;
|
||||
point->index = pa - sim->psys->particles;
|
||||
point->size = pa->size;
|
||||
point->charge = 0.0f;
|
||||
|
||||
if (part->pd && part->pd->forcefield == PFIELD_CHARGE)
|
||||
point->charge += part->pd->f_strength;
|
||||
|
||||
if (part->pd2 && part->pd2->forcefield == PFIELD_CHARGE)
|
||||
point->charge += part->pd2->f_strength;
|
||||
|
||||
point->vel_to_sec = 1.0f;
|
||||
point->vel_to_frame = psys_get_timestep(sim);
|
||||
|
||||
point->flag = 0;
|
||||
|
||||
if (sim->psys->part->flag & PART_ROT_DYN) {
|
||||
point->ave = state->ave;
|
||||
point->rot = state->rot;
|
||||
}
|
||||
else
|
||||
point->ave = point->rot = NULL;
|
||||
|
||||
point->psys = sim->psys;
|
||||
}
|
||||
|
||||
void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
|
||||
{
|
||||
point->loc = loc;
|
||||
@@ -361,7 +288,6 @@ void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, Effected
|
||||
point->flag = 0;
|
||||
|
||||
point->ave = point->rot = NULL;
|
||||
point->psys = NULL;
|
||||
}
|
||||
void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
|
||||
{
|
||||
@@ -376,8 +302,6 @@ void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, Effecte
|
||||
point->flag = PE_WIND_AS_SPEED;
|
||||
|
||||
point->ave = point->rot = NULL;
|
||||
|
||||
point->psys = NULL;
|
||||
}
|
||||
/************************************************/
|
||||
/* Effectors */
|
||||
@@ -490,7 +414,7 @@ static float falloff_func_rad(PartDeflect *pd, float fac)
|
||||
return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
|
||||
}
|
||||
|
||||
float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *UNUSED(point), EffectorWeights *weights)
|
||||
static float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *UNUSED(point), EffectorWeights *weights)
|
||||
{
|
||||
float temp[3];
|
||||
float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f;
|
||||
@@ -565,7 +489,6 @@ int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], floa
|
||||
}
|
||||
int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int real_velocity)
|
||||
{
|
||||
float cfra = eff->scene->r.cfra;
|
||||
int ret = 0;
|
||||
|
||||
/* In case surface object is in Edit mode when loading the .blend, surface modifier is never executed
|
||||
@@ -602,43 +525,6 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
else if (eff->psys) {
|
||||
ParticleData *pa = eff->psys->particles + *efd->index;
|
||||
ParticleKey state;
|
||||
|
||||
/* exclude the particle itself for self effecting particles */
|
||||
if (eff->psys == point->psys && *efd->index == point->index) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
ParticleSimulationData sim= {NULL};
|
||||
sim.scene= eff->scene;
|
||||
sim.ob= eff->ob;
|
||||
sim.psys= eff->psys;
|
||||
|
||||
/* TODO: time from actual previous calculated frame (step might not be 1) */
|
||||
state.time = cfra - 1.0f;
|
||||
ret = psys_get_particle_state(&sim, *efd->index, &state, 0);
|
||||
|
||||
/* TODO */
|
||||
//if (eff->pd->forcefiled == PFIELD_HARMONIC && ret==0) {
|
||||
// if (pa->dietime < eff->psys->cfra)
|
||||
// eff->flag |= PE_VELOCITY_TO_IMPULSE;
|
||||
//}
|
||||
|
||||
copy_v3_v3(efd->loc, state.co);
|
||||
|
||||
/* rather than use the velocity use rotated x-axis (defaults to velocity) */
|
||||
efd->nor[0] = 1.f;
|
||||
efd->nor[1] = efd->nor[2] = 0.f;
|
||||
mul_qt_v3(state.rot, efd->nor);
|
||||
|
||||
if (real_velocity)
|
||||
copy_v3_v3(efd->vel, state.vel);
|
||||
|
||||
efd->size = pa->size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* use center of object for distance calculus */
|
||||
const Object *ob = eff->ob;
|
||||
@@ -690,7 +576,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p, int *step)
|
||||
static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p)
|
||||
{
|
||||
*p = 0;
|
||||
efd->index = p;
|
||||
@@ -703,31 +589,6 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin
|
||||
*tot = *p+1;
|
||||
}
|
||||
}
|
||||
else if (eff->psys) {
|
||||
*tot = eff->psys->totpart;
|
||||
|
||||
if (eff->pd->forcefield == PFIELD_CHARGE) {
|
||||
/* Only the charge of the effected particle is used for
|
||||
* interaction, not fall-offs. If the fall-offs aren't the
|
||||
* same this will be unphysical, but for animation this
|
||||
* could be the wanted behavior. If you want physical
|
||||
* correctness the fall-off should be spherical 2.0 anyways.
|
||||
*/
|
||||
efd->charge = eff->pd->f_strength;
|
||||
}
|
||||
else if (eff->pd->forcefield == PFIELD_HARMONIC && (eff->pd->flag & PFIELD_MULTIPLE_SPRINGS)==0) {
|
||||
/* every particle is mapped to only one harmonic effector particle */
|
||||
*p= point->index % eff->psys->totpart;
|
||||
*tot= *p + 1;
|
||||
}
|
||||
|
||||
if (eff->psys->part->effector_amount) {
|
||||
int totpart = eff->psys->totpart;
|
||||
int amount = eff->psys->part->effector_amount;
|
||||
|
||||
*step = (totpart > amount) ? totpart/amount : 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*tot = 1;
|
||||
}
|
||||
@@ -990,7 +851,7 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
|
||||
*/
|
||||
EffectorCache *eff;
|
||||
EffectorData efd;
|
||||
int p=0, tot = 1, step = 1;
|
||||
int p=0, tot = 1;
|
||||
|
||||
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
|
||||
/* Check for min distance here? (yes would be cool to add that, ton) */
|
||||
@@ -998,9 +859,9 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
|
||||
if (effectors) for (eff = effectors->first; eff; eff=eff->next) {
|
||||
/* object effectors were fully checked to be OK to evaluate! */
|
||||
|
||||
get_effector_tot(eff, &efd, point, &tot, &p, &step);
|
||||
get_effector_tot(eff, &efd, point, &tot, &p);
|
||||
|
||||
for (; p<tot; p+=step) {
|
||||
for (; p<tot; p++) {
|
||||
if (get_effector_data(eff, &efd, point, 0)) {
|
||||
efd.falloff= effector_falloff(eff, &efd, point, weights);
|
||||
|
||||
|
@@ -43,7 +43,6 @@
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_object_force.h" // for pointcache
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
@@ -78,7 +78,6 @@ static IDType idtypes[] = {
|
||||
{ ID_MSK, "Mask", "masks", BLT_I18NCONTEXT_ID_MASK, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_NT, "NodeTree", "node_groups", BLT_I18NCONTEXT_ID_NODETREE, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_OB, "Object", "objects", BLT_I18NCONTEXT_ID_OBJECT, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_PA, "ParticleSettings", "particles", BLT_I18NCONTEXT_ID_PARTICLESETTINGS, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_PAL, "Palettes", "palettes", BLT_I18NCONTEXT_ID_PALETTE, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_PC, "PaintCurve", "paint_curves", BLT_I18NCONTEXT_ID_PAINTCURVE, IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_SCE, "Scene", "scenes", BLT_I18NCONTEXT_ID_SCENE, IDTYPE_FLAGS_ISLINKABLE },
|
||||
@@ -200,7 +199,6 @@ int BKE_idcode_to_idfilter(const short idcode)
|
||||
CASE_IDFILTER(MSK);
|
||||
CASE_IDFILTER(NT);
|
||||
CASE_IDFILTER(OB);
|
||||
CASE_IDFILTER(PA);
|
||||
CASE_IDFILTER(PAL);
|
||||
CASE_IDFILTER(PC);
|
||||
CASE_IDFILTER(SCE);
|
||||
@@ -244,7 +242,6 @@ short BKE_idcode_from_idfilter(const int idfilter)
|
||||
CASE_IDFILTER(MSK);
|
||||
CASE_IDFILTER(NT);
|
||||
CASE_IDFILTER(OB);
|
||||
CASE_IDFILTER(PA);
|
||||
CASE_IDFILTER(PAL);
|
||||
CASE_IDFILTER(PC);
|
||||
CASE_IDFILTER(SCE);
|
||||
@@ -291,7 +288,6 @@ int BKE_idcode_to_index(const short idcode)
|
||||
CASE_IDINDEX(MSK);
|
||||
CASE_IDINDEX(NT);
|
||||
CASE_IDINDEX(OB);
|
||||
CASE_IDINDEX(PA);
|
||||
CASE_IDINDEX(PAL);
|
||||
CASE_IDINDEX(PC);
|
||||
CASE_IDINDEX(SCE);
|
||||
|
@@ -739,74 +739,6 @@ static const char *world_adrcodes_to_paths(int adrcode, int *array_index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Particle Types */
|
||||
static const char *particle_adrcodes_to_paths(int adrcode, int *array_index)
|
||||
{
|
||||
/* set array index like this in-case nothing sets it correctly */
|
||||
*array_index = 0;
|
||||
|
||||
/* result depends on adrcode */
|
||||
switch (adrcode) {
|
||||
case PART_CLUMP:
|
||||
return "settings.clump_factor";
|
||||
case PART_AVE:
|
||||
return "settings.angular_velocity_factor";
|
||||
case PART_SIZE:
|
||||
return "settings.particle_size";
|
||||
case PART_DRAG:
|
||||
return "settings.drag_factor";
|
||||
case PART_BROWN:
|
||||
return "settings.brownian_factor";
|
||||
case PART_DAMP:
|
||||
return "settings.damp_factor";
|
||||
case PART_LENGTH:
|
||||
return "settings.length";
|
||||
case PART_GRAV_X:
|
||||
*array_index = 0; return "settings.acceleration";
|
||||
case PART_GRAV_Y:
|
||||
*array_index = 1; return "settings.acceleration";
|
||||
case PART_GRAV_Z:
|
||||
*array_index = 2; return "settings.acceleration";
|
||||
case PART_KINK_AMP:
|
||||
return "settings.kink_amplitude";
|
||||
case PART_KINK_FREQ:
|
||||
return "settings.kink_frequency";
|
||||
case PART_KINK_SHAPE:
|
||||
return "settings.kink_shape";
|
||||
case PART_BB_TILT:
|
||||
return "settings.billboard_tilt";
|
||||
|
||||
/* PartDeflect needs to be sorted out properly in rna_object_force;
|
||||
* If anyone else works on this, but is unfamiliar, these particular
|
||||
* settings reference the particles of the system themselves
|
||||
* being used as forces -- it will use the same rna structure
|
||||
* as the similar object forces */
|
||||
#if 0
|
||||
case PART_PD_FSTR:
|
||||
if (part->pd) poin = &(part->pd->f_strength);
|
||||
break;
|
||||
case PART_PD_FFALL:
|
||||
if (part->pd) poin = &(part->pd->f_power);
|
||||
break;
|
||||
case PART_PD_FMAXD:
|
||||
if (part->pd) poin = &(part->pd->maxdist);
|
||||
break;
|
||||
case PART_PD2_FSTR:
|
||||
if (part->pd2) poin = &(part->pd2->f_strength);
|
||||
break;
|
||||
case PART_PD2_FFALL:
|
||||
if (part->pd2) poin = &(part->pd2->f_power);
|
||||
break;
|
||||
case PART_PD2_FMAXD:
|
||||
if (part->pd2) poin = &(part->pd2->maxdist);
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
/* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
|
||||
@@ -872,10 +804,6 @@ static char *get_rna_access(ID *id, int blocktype, int adrcode, char actname[],
|
||||
propname = world_adrcodes_to_paths(adrcode, &dummy_index);
|
||||
break;
|
||||
|
||||
case ID_PA: /* particle */
|
||||
propname = particle_adrcodes_to_paths(adrcode, &dummy_index);
|
||||
break;
|
||||
|
||||
case ID_CU: /* curve */
|
||||
/* this used to be a 'dummy' curve which got evaluated on the fly...
|
||||
* now we've got real var for this!
|
||||
|
@@ -112,7 +112,6 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_speaker.h"
|
||||
@@ -409,9 +408,6 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
|
||||
case ID_BR:
|
||||
if (!test) BKE_brush_make_local(bmain, (Brush *)id, lib_local);
|
||||
return true;
|
||||
case ID_PA:
|
||||
if (!test) BKE_particlesettings_make_local(bmain, (ParticleSettings *)id, lib_local);
|
||||
return true;
|
||||
case ID_GD:
|
||||
if (!test) BKE_gpencil_make_local(bmain, (bGPdata *)id, lib_local);
|
||||
return true;
|
||||
@@ -516,9 +512,6 @@ bool id_copy(Main *bmain, ID *id, ID **newid, bool test)
|
||||
case ID_BR:
|
||||
if (!test) *newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
|
||||
return true;
|
||||
case ID_PA:
|
||||
if (!test) *newid = (ID *)BKE_particlesettings_copy(bmain, (ParticleSettings *)id);
|
||||
return true;
|
||||
case ID_GD:
|
||||
if (!test) *newid = (ID *)BKE_gpencil_data_duplicate(bmain, (bGPdata *)id, false);
|
||||
return true;
|
||||
@@ -636,8 +629,6 @@ ListBase *which_libbase(Main *mainlib, short type)
|
||||
return &(mainlib->nodetree);
|
||||
case ID_BR:
|
||||
return &(mainlib->brush);
|
||||
case ID_PA:
|
||||
return &(mainlib->particle);
|
||||
case ID_WM:
|
||||
return &(mainlib->wm);
|
||||
case ID_GD:
|
||||
@@ -790,7 +781,6 @@ int set_listbasepointers(Main *main, ListBase **lb)
|
||||
lb[INDEX_ID_PAL] = &(main->palettes);
|
||||
lb[INDEX_ID_PC] = &(main->paintcurves);
|
||||
lb[INDEX_ID_BR] = &(main->brush);
|
||||
lb[INDEX_ID_PA] = &(main->particle);
|
||||
lb[INDEX_ID_SPK] = &(main->speaker);
|
||||
|
||||
lb[INDEX_ID_WO] = &(main->world);
|
||||
@@ -901,9 +891,6 @@ void *BKE_libblock_alloc_notest(short type)
|
||||
case ID_BR:
|
||||
id = MEM_callocN(sizeof(Brush), "brush");
|
||||
break;
|
||||
case ID_PA:
|
||||
id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
|
||||
break;
|
||||
case ID_WM:
|
||||
id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
|
||||
break;
|
||||
@@ -1039,9 +1026,6 @@ void BKE_libblock_init_empty(ID *id)
|
||||
case ID_BR:
|
||||
BKE_brush_init((Brush *)id);
|
||||
break;
|
||||
case ID_PA:
|
||||
/* Nothing to do. */
|
||||
break;
|
||||
case ID_PC:
|
||||
/* Nothing to do. */
|
||||
break;
|
||||
@@ -1244,7 +1228,6 @@ void BKE_main_free(Main *mainvar)
|
||||
case 31: BKE_libblock_free_ex(mainvar, id, false); break;
|
||||
case 32: BKE_libblock_free_ex(mainvar, id, false); break;
|
||||
case 33: BKE_libblock_free_ex(mainvar, id, false); break;
|
||||
case 34: BKE_libblock_free_ex(mainvar, id, false); break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_rigidbody_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sensor_types.h"
|
||||
@@ -63,7 +64,6 @@
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist_stack.h"
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_rigidbody.h"
|
||||
#include "BKE_sca.h"
|
||||
#include "BKE_sequencer.h"
|
||||
@@ -167,15 +166,6 @@ static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_particlesystemsObjectLooper(
|
||||
ParticleSystem *UNUSED(psys), ID **id_pointer, void *user_data, int cd_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_sensorsObjectLooper(
|
||||
bSensor *UNUSED(sensor), ID **id_pointer, void *user_data, int cd_flag)
|
||||
{
|
||||
@@ -402,10 +392,6 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
if (toolsett) {
|
||||
CALLBACK_INVOKE(toolsett->skgen_template, IDWALK_NOP);
|
||||
|
||||
CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_NOP);
|
||||
|
||||
library_foreach_paint(&data, &toolsett->imapaint.paint);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_USER);
|
||||
@@ -438,7 +424,6 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_OB:
|
||||
{
|
||||
Object *object = (Object *) id;
|
||||
ParticleSystem *psys;
|
||||
|
||||
/* Object is special, proxies make things hard... */
|
||||
const int data_cd_flag = data.cd_flag;
|
||||
@@ -513,13 +498,13 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
}
|
||||
|
||||
CALLBACK_INVOKE(object->probe, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->parallaxcorrect, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->reflectionplane, IDWALK_NOP);
|
||||
|
||||
modifiers_foreachIDLink(object, library_foreach_modifiersForeachIDLink, &data);
|
||||
BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, &data);
|
||||
|
||||
for (psys = object->particlesystem.first; psys; psys = psys->next) {
|
||||
BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
|
||||
}
|
||||
|
||||
if (object->soft) {
|
||||
CALLBACK_INVOKE(object->soft->collision_group, IDWALK_NOP);
|
||||
|
||||
@@ -734,53 +719,6 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_PA:
|
||||
{
|
||||
ParticleSettings *psett = (ParticleSettings *) id;
|
||||
CALLBACK_INVOKE(psett->dup_group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->dup_ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->bb_ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->collision_group, IDWALK_NOP);
|
||||
|
||||
for (i = 0; i < MAX_MTEX; i++) {
|
||||
if (psett->mtex[i]) {
|
||||
library_foreach_mtex(&data, psett->mtex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (psett->effector_weights) {
|
||||
CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_NOP);
|
||||
}
|
||||
|
||||
if (psett->pd) {
|
||||
CALLBACK_INVOKE(psett->pd->tex, IDWALK_USER);
|
||||
CALLBACK_INVOKE(psett->pd->f_source, IDWALK_NOP);
|
||||
}
|
||||
if (psett->pd2) {
|
||||
CALLBACK_INVOKE(psett->pd2->tex, IDWALK_USER);
|
||||
CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_NOP);
|
||||
}
|
||||
|
||||
if (psett->boids) {
|
||||
BoidState *state;
|
||||
BoidRule *rule;
|
||||
|
||||
for (state = psett->boids->states.first; state; state = state->next) {
|
||||
for (rule = state->rules.first; rule; rule = rule->next) {
|
||||
if (rule->type == eBoidRuleType_Avoid) {
|
||||
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
|
||||
CALLBACK_INVOKE(gabr->ob, IDWALK_NOP);
|
||||
}
|
||||
else if (rule->type == eBoidRuleType_FollowLeader) {
|
||||
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
|
||||
CALLBACK_INVOKE(flbr->ob, IDWALK_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_MC:
|
||||
{
|
||||
MovieClip *clip = (MovieClip *) id;
|
||||
@@ -945,7 +883,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
|
||||
/* Could be the following, but simpler to just always say 'yes' here. */
|
||||
#if 0
|
||||
return ELEM(id_type_used, ID_ME, ID_CU, ID_MB, ID_LT, ID_SPK, ID_AR, ID_LA, ID_CA, /* obdata */
|
||||
ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_PA, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
|
||||
ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
|
||||
/* + constraints, modifiers and game logic ID types... */);
|
||||
#else
|
||||
return true;
|
||||
@@ -985,8 +923,6 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
|
||||
#endif
|
||||
case ID_BR:
|
||||
return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE);
|
||||
case ID_PA:
|
||||
return ELEM(id_type_used, ID_OB, ID_GR, ID_TE);
|
||||
case ID_MC:
|
||||
return ELEM(id_type_used, ID_GD, ID_IM);
|
||||
case ID_MSK:
|
||||
|
@@ -98,7 +98,6 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_sca.h"
|
||||
#include "BKE_speaker.h"
|
||||
#include "BKE_sound.h"
|
||||
@@ -797,9 +796,6 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user)
|
||||
case ID_BR:
|
||||
BKE_brush_free((Brush *)id);
|
||||
break;
|
||||
case ID_PA:
|
||||
BKE_particlesettings_free((ParticleSettings *)id);
|
||||
break;
|
||||
case ID_WM:
|
||||
if (free_windowmanager_cb)
|
||||
free_windowmanager_cb(NULL, (wmWindowManager *)id);
|
||||
|
@@ -401,13 +401,6 @@ bool modifiers_isModifierEnabled(Object *ob, int modifierType)
|
||||
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
||||
}
|
||||
|
||||
bool modifiers_isParticleEnabled(Object *ob)
|
||||
{
|
||||
ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
|
||||
|
||||
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
||||
}
|
||||
|
||||
bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode)
|
||||
{
|
||||
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
@@ -50,6 +50,8 @@
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_movieclip_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
@@ -104,8 +106,6 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_property.h"
|
||||
#include "BKE_rigidbody.h"
|
||||
#include "BKE_sca.h"
|
||||
@@ -129,6 +129,7 @@
|
||||
#include "CCGSubSurf.h"
|
||||
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_probe.h"
|
||||
|
||||
/* Vertex parent modifies original BMesh which is not safe for threading.
|
||||
* Ideally such a modification should be handled as a separate DAG update
|
||||
@@ -161,15 +162,6 @@ void BKE_object_update_base_layer(struct Scene *scene, Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_object_free_particlesystems(Object *ob)
|
||||
{
|
||||
ParticleSystem *psys;
|
||||
|
||||
while ((psys = BLI_pophead(&ob->particlesystem))) {
|
||||
psys_free(ob, psys);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_object_free_softbody(Object *ob)
|
||||
{
|
||||
if (ob->soft) {
|
||||
@@ -208,9 +200,6 @@ void BKE_object_free_modifiers(Object *ob)
|
||||
modifier_free(md);
|
||||
}
|
||||
|
||||
/* particle modifiers were freed, so free the particlesystems as well */
|
||||
BKE_object_free_particlesystems(ob);
|
||||
|
||||
/* same for softbody */
|
||||
BKE_object_free_softbody(ob);
|
||||
|
||||
@@ -307,8 +296,6 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
|
||||
modifier_unique_name(&ob_dst->modifiers, nmd);
|
||||
}
|
||||
|
||||
BKE_object_copy_particlesystems(ob_dst, ob_src);
|
||||
|
||||
/* TODO: smoke?, cloth? */
|
||||
}
|
||||
|
||||
@@ -352,40 +339,8 @@ void BKE_object_free_derived_caches(Object *ob)
|
||||
|
||||
void BKE_object_free_caches(Object *object)
|
||||
{
|
||||
ModifierData *md;
|
||||
short update_flag = 0;
|
||||
|
||||
/* Free particle system caches holding paths. */
|
||||
if (object->particlesystem.first) {
|
||||
ParticleSystem *psys;
|
||||
for (psys = object->particlesystem.first;
|
||||
psys != NULL;
|
||||
psys = psys->next)
|
||||
{
|
||||
psys_free_path_cache(psys, psys->edit);
|
||||
update_flag |= PSYS_RECALC_REDO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory used by cached derived meshes in the particle system modifiers. */
|
||||
for (md = object->modifiers.first; md != NULL; md = md->next) {
|
||||
if (md->type == eModifierType_ParticleSystem) {
|
||||
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
|
||||
if (psmd->dm_final != NULL) {
|
||||
psmd->dm_final->needsFree = 1;
|
||||
psmd->dm_final->release(psmd->dm_final);
|
||||
psmd->dm_final = NULL;
|
||||
if (psmd->dm_deformed != NULL) {
|
||||
psmd->dm_deformed->needsFree = 1;
|
||||
psmd->dm_deformed->release(psmd->dm_deformed);
|
||||
psmd->dm_deformed = NULL;
|
||||
}
|
||||
psmd->flag |= eParticleSystemFlag_file_loaded;
|
||||
update_flag |= OB_RECALC_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag object for update, so once memory critical operation is over and
|
||||
* scene update routines are back to it's business the object will be
|
||||
* guaranteed to be in a known state.
|
||||
@@ -438,6 +393,8 @@ void BKE_object_free(Object *ob)
|
||||
}
|
||||
GPU_lamp_free(ob);
|
||||
|
||||
GPU_probe_free(&ob->gpuprobe);
|
||||
|
||||
BKE_sculptsession_free(ob);
|
||||
|
||||
BLI_freelistN(&ob->pc_ids);
|
||||
@@ -643,6 +600,14 @@ void BKE_object_init(Object *ob)
|
||||
ob->col_mask = 0xffff;
|
||||
ob->preview = NULL;
|
||||
|
||||
/* Viewport Probe defaults */
|
||||
ob->probesize = 256;
|
||||
ob->probeshres = 32;
|
||||
ob->probeflags = (OB_PROBE_AUTO_UPDATE | OB_PROBE_COMPUTE_SH);
|
||||
ob->probeclipsta = 0.1f;
|
||||
ob->probeclipend = 1000.0f;
|
||||
ob->probeclipbias = 0.01f;
|
||||
|
||||
/* NT fluid sim defaults */
|
||||
ob->fluidsimSettings = NULL;
|
||||
|
||||
@@ -864,8 +829,6 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
|
||||
|
||||
sbn->scratch = NULL;
|
||||
|
||||
sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches);
|
||||
|
||||
if (sb->effector_weights)
|
||||
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
|
||||
|
||||
@@ -883,119 +846,6 @@ BulletSoftBody *copy_bulletsoftbody(BulletSoftBody *bsb)
|
||||
return bsbn;
|
||||
}
|
||||
|
||||
ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
|
||||
{
|
||||
ParticleSystem *psysn;
|
||||
ParticleData *pa;
|
||||
int p;
|
||||
|
||||
psysn = MEM_dupallocN(psys);
|
||||
psysn->particles = MEM_dupallocN(psys->particles);
|
||||
psysn->child = MEM_dupallocN(psys->child);
|
||||
|
||||
if (psys->part->type == PART_HAIR) {
|
||||
for (p = 0, pa = psysn->particles; p < psysn->totpart; p++, pa++)
|
||||
pa->hair = MEM_dupallocN(pa->hair);
|
||||
}
|
||||
|
||||
if (psysn->particles && (psysn->particles->keys || psysn->particles->boid)) {
|
||||
ParticleKey *key = psysn->particles->keys;
|
||||
BoidParticle *boid = psysn->particles->boid;
|
||||
|
||||
if (key)
|
||||
key = MEM_dupallocN(key);
|
||||
|
||||
if (boid)
|
||||
boid = MEM_dupallocN(boid);
|
||||
|
||||
for (p = 0, pa = psysn->particles; p < psysn->totpart; p++, pa++) {
|
||||
if (boid)
|
||||
pa->boid = boid++;
|
||||
if (key) {
|
||||
pa->keys = key;
|
||||
key += pa->totkey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (psys->clmd) {
|
||||
psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
|
||||
modifier_copyData((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd);
|
||||
psys->hair_in_dm = psys->hair_out_dm = NULL;
|
||||
}
|
||||
|
||||
BLI_duplicatelist(&psysn->targets, &psys->targets);
|
||||
|
||||
psysn->pathcache = NULL;
|
||||
psysn->childcache = NULL;
|
||||
psysn->edit = NULL;
|
||||
psysn->pdd = NULL;
|
||||
psysn->effectors = NULL;
|
||||
psysn->tree = NULL;
|
||||
psysn->bvhtree = NULL;
|
||||
|
||||
BLI_listbase_clear(&psysn->pathcachebufs);
|
||||
BLI_listbase_clear(&psysn->childcachebufs);
|
||||
psysn->renderdata = NULL;
|
||||
|
||||
psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, false);
|
||||
|
||||
/* XXX - from reading existing code this seems correct but intended usage of
|
||||
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
|
||||
if (psysn->clmd) {
|
||||
psysn->clmd->point_cache = psysn->pointcache;
|
||||
}
|
||||
|
||||
id_us_plus((ID *)psysn->part);
|
||||
|
||||
return psysn;
|
||||
}
|
||||
|
||||
void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src)
|
||||
{
|
||||
ParticleSystem *psys, *npsys;
|
||||
ModifierData *md;
|
||||
|
||||
if (ob_dst->type != OB_MESH) {
|
||||
/* currently only mesh objects can have soft body */
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_listbase_clear(&ob_dst->particlesystem);
|
||||
for (psys = ob_src->particlesystem.first; psys; psys = psys->next) {
|
||||
npsys = BKE_object_copy_particlesystem(psys);
|
||||
|
||||
BLI_addtail(&ob_dst->particlesystem, npsys);
|
||||
|
||||
/* need to update particle modifiers too */
|
||||
for (md = ob_dst->modifiers.first; md; md = md->next) {
|
||||
if (md->type == eModifierType_ParticleSystem) {
|
||||
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
|
||||
if (psmd->psys == psys)
|
||||
psmd->psys = npsys;
|
||||
}
|
||||
else if (md->type == eModifierType_DynamicPaint) {
|
||||
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
|
||||
if (pmd->brush) {
|
||||
if (pmd->brush->psys == psys) {
|
||||
pmd->brush->psys = npsys;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (md->type == eModifierType_Smoke) {
|
||||
SmokeModifierData *smd = (SmokeModifierData *) md;
|
||||
|
||||
if (smd->type == MOD_SMOKE_TYPE_FLOW) {
|
||||
if (smd->flow) {
|
||||
if (smd->flow->psys == psys)
|
||||
smd->flow->psys = npsys;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src)
|
||||
{
|
||||
if (ob_src->soft) {
|
||||
@@ -1152,12 +1002,11 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
|
||||
obn->rigidbody_object = BKE_rigidbody_copy_object(ob);
|
||||
obn->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob);
|
||||
|
||||
BKE_object_copy_particlesystems(obn, ob);
|
||||
|
||||
obn->derivedDeform = NULL;
|
||||
obn->derivedFinal = NULL;
|
||||
|
||||
BLI_listbase_clear(&obn->gpulamp);
|
||||
BLI_listbase_clear(&obn->gpuprobe);
|
||||
BLI_listbase_clear(&obn->pc_ids);
|
||||
|
||||
obn->mpath = NULL;
|
||||
@@ -3672,25 +3521,6 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* set "ignore cache" flag for all caches on this object */
|
||||
static void object_cacheIgnoreClear(Object *ob, int state)
|
||||
{
|
||||
ListBase pidlist;
|
||||
PTCacheID *pid;
|
||||
BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
|
||||
|
||||
for (pid = pidlist.first; pid; pid = pid->next) {
|
||||
if (pid->cache) {
|
||||
if (state)
|
||||
pid->cache->flag |= PTCACHE_IGNORE_CLEAR;
|
||||
else
|
||||
pid->cache->flag &= ~PTCACHE_IGNORE_CLEAR;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_freelistN(&pidlist);
|
||||
}
|
||||
|
||||
/* Note: this function should eventually be replaced by depsgraph functionality.
|
||||
* Avoid calling this in new code unless there is a very good reason for it!
|
||||
*/
|
||||
@@ -3750,11 +3580,7 @@ bool BKE_object_modifier_update_subframe(Scene *scene, Object *ob, bool update_m
|
||||
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
|
||||
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
|
||||
if (update_mesh) {
|
||||
/* ignore cache clear during subframe updates
|
||||
* to not mess up cache validity */
|
||||
object_cacheIgnoreClear(ob, 1);
|
||||
BKE_object_handle_update(G.main->eval_ctx, scene, ob);
|
||||
object_cacheIgnoreClear(ob, 0);
|
||||
}
|
||||
else
|
||||
BKE_object_where_is_calc_time(scene, ob, frame);
|
||||
|
@@ -42,7 +42,6 @@
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
@@ -72,8 +71,6 @@ static Lattice *object_defgroup_lattice_get(ID *id)
|
||||
void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
|
||||
{
|
||||
ModifierData *md;
|
||||
ParticleSystem *psys;
|
||||
int a;
|
||||
|
||||
/* these cases don't use names to refer to vertex groups, so when
|
||||
* they get removed the numbers get out of sync, this corrects that */
|
||||
@@ -98,12 +95,6 @@ void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
|
||||
for (a = 0; a < PSYS_TOT_VG; a++) {
|
||||
psys->vgroup[a] = map[psys->vgroup[a]];
|
||||
}
|
||||
}
|
||||
}
|
||||
/** \} */
|
||||
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
|
||||
@@ -57,7 +58,6 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_anim.h"
|
||||
@@ -825,327 +825,6 @@ const DupliGenerator gen_dupli_faces = {
|
||||
make_duplis_faces /* make_duplis */
|
||||
};
|
||||
|
||||
/* OB_DUPLIPARTS */
|
||||
static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem *psys)
|
||||
{
|
||||
Scene *scene = ctx->scene;
|
||||
Object *par = ctx->object;
|
||||
bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER;
|
||||
bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
|
||||
|
||||
GroupObject *go;
|
||||
Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
|
||||
DupliObject *dob;
|
||||
ParticleDupliWeight *dw;
|
||||
ParticleSettings *part;
|
||||
ParticleData *pa;
|
||||
ChildParticle *cpa = NULL;
|
||||
ParticleKey state;
|
||||
ParticleCacheKey *cache;
|
||||
float ctime, pa_time, scale = 1.0f;
|
||||
float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
|
||||
float (*obmat)[4];
|
||||
int a, b, hair = 0;
|
||||
int totpart, totchild, totgroup = 0 /*, pa_num */;
|
||||
const bool dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene);
|
||||
|
||||
int no_draw_flag = PARS_UNEXIST;
|
||||
|
||||
if (psys == NULL) return;
|
||||
|
||||
part = psys->part;
|
||||
|
||||
if (part == NULL)
|
||||
return;
|
||||
|
||||
if (!psys_check_enabled(par, psys, (ctx->eval_ctx->mode == DAG_EVAL_RENDER)))
|
||||
return;
|
||||
|
||||
if (!for_render)
|
||||
no_draw_flag |= PARS_NO_DISP;
|
||||
|
||||
ctime = BKE_scene_frame_get(scene); /* NOTE: in old animsys, used parent object's timeoffset... */
|
||||
|
||||
totpart = psys->totpart;
|
||||
totchild = psys->totchild;
|
||||
|
||||
BLI_srandom((unsigned int)(31415926 + psys->seed));
|
||||
|
||||
if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
|
||||
ParticleSimulationData sim = {NULL};
|
||||
sim.scene = scene;
|
||||
sim.ob = par;
|
||||
sim.psys = psys;
|
||||
sim.psmd = psys_get_modifier(par, psys);
|
||||
/* make sure emitter imat is in global coordinates instead of render view coordinates */
|
||||
invert_m4_m4(par->imat, par->obmat);
|
||||
|
||||
/* first check for loops (particle system object used as dupli object) */
|
||||
if (part->ren_as == PART_DRAW_OB) {
|
||||
if (ELEM(part->dup_ob, NULL, par))
|
||||
return;
|
||||
}
|
||||
else { /*PART_DRAW_GR */
|
||||
if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->gobject))
|
||||
return;
|
||||
|
||||
if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have a hair particle system, use the path cache */
|
||||
if (part->type == PART_HAIR) {
|
||||
if (psys->flag & PSYS_HAIR_DONE)
|
||||
hair = (totchild == 0 || psys->childcache) && psys->pathcache;
|
||||
if (!hair)
|
||||
return;
|
||||
|
||||
/* we use cache, update totchild according to cached data */
|
||||
totchild = psys->totchildcache;
|
||||
totpart = psys->totcached;
|
||||
}
|
||||
|
||||
psys_check_group_weights(part);
|
||||
|
||||
psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
|
||||
|
||||
/* gather list of objects or single object */
|
||||
if (part->ren_as == PART_DRAW_GR) {
|
||||
if (ctx->do_update) {
|
||||
BKE_group_handle_recalc_and_update(ctx->eval_ctx, scene, par, part->dup_group);
|
||||
}
|
||||
|
||||
if (part->draw & PART_DRAW_COUNT_GR) {
|
||||
for (dw = part->dupliweights.first; dw; dw = dw->next)
|
||||
totgroup += dw->count;
|
||||
}
|
||||
else {
|
||||
for (go = part->dup_group->gobject.first; go; go = go->next)
|
||||
totgroup++;
|
||||
}
|
||||
|
||||
/* we also copy the actual objects to restore afterwards, since
|
||||
* BKE_object_where_is_calc_time will change the object which breaks transform */
|
||||
oblist = MEM_callocN((size_t)totgroup * sizeof(Object *), "dupgroup object list");
|
||||
obcopylist = MEM_callocN((size_t)totgroup * sizeof(Object), "dupgroup copy list");
|
||||
|
||||
if (part->draw & PART_DRAW_COUNT_GR && totgroup) {
|
||||
dw = part->dupliweights.first;
|
||||
|
||||
for (a = 0; a < totgroup; dw = dw->next) {
|
||||
for (b = 0; b < dw->count; b++, a++) {
|
||||
oblist[a] = dw->ob;
|
||||
obcopylist[a] = *dw->ob;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
go = part->dup_group->gobject.first;
|
||||
for (a = 0; a < totgroup; a++, go = go->next) {
|
||||
oblist[a] = go->ob;
|
||||
obcopylist[a] = *go->ob;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ob = part->dup_ob;
|
||||
obcopy = *ob;
|
||||
}
|
||||
|
||||
if (totchild == 0 || part->draw & PART_DRAW_PARENT)
|
||||
a = 0;
|
||||
else
|
||||
a = totpart;
|
||||
|
||||
for (pa = psys->particles; a < totpart + totchild; a++, pa++) {
|
||||
if (a < totpart) {
|
||||
/* handle parent particle */
|
||||
if (pa->flag & no_draw_flag)
|
||||
continue;
|
||||
|
||||
/* pa_num = pa->num; */ /* UNUSED */
|
||||
pa_time = pa->time;
|
||||
size = pa->size;
|
||||
}
|
||||
else {
|
||||
/* handle child particle */
|
||||
cpa = &psys->child[a - totpart];
|
||||
|
||||
/* pa_num = a; */ /* UNUSED */
|
||||
pa_time = psys->particles[cpa->parent].time;
|
||||
size = psys_get_child_size(psys, cpa, ctime, NULL);
|
||||
}
|
||||
|
||||
/* some hair paths might be non-existent so they can't be used for duplication */
|
||||
if (hair && psys->pathcache &&
|
||||
((a < totpart && psys->pathcache[a]->segments < 0) ||
|
||||
(a >= totpart && psys->childcache[a - totpart]->segments < 0)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part->ren_as == PART_DRAW_GR) {
|
||||
/* prevent divide by zero below [#28336] */
|
||||
if (totgroup == 0)
|
||||
continue;
|
||||
|
||||
/* for groups, pick the object based on settings */
|
||||
if (part->draw & PART_DRAW_RAND_GR)
|
||||
b = BLI_rand() % totgroup;
|
||||
else
|
||||
b = a % totgroup;
|
||||
|
||||
ob = oblist[b];
|
||||
obmat = oblist[b]->obmat;
|
||||
}
|
||||
else {
|
||||
obmat = ob->obmat;
|
||||
}
|
||||
|
||||
if (hair) {
|
||||
/* hair we handle separate and compute transform based on hair keys */
|
||||
if (a < totpart) {
|
||||
cache = psys->pathcache[a];
|
||||
psys_get_dupli_path_transform(&sim, pa, NULL, cache, pamat, &scale);
|
||||
}
|
||||
else {
|
||||
cache = psys->childcache[a - totpart];
|
||||
psys_get_dupli_path_transform(&sim, NULL, cpa, cache, pamat, &scale);
|
||||
}
|
||||
|
||||
copy_v3_v3(pamat[3], cache->co);
|
||||
pamat[3][3] = 1.0f;
|
||||
|
||||
}
|
||||
else {
|
||||
/* first key */
|
||||
state.time = ctime;
|
||||
if (psys_get_particle_state(&sim, a, &state, 0) == 0) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
float tquat[4];
|
||||
normalize_qt_qt(tquat, state.rot);
|
||||
quat_to_mat4(pamat, tquat);
|
||||
copy_v3_v3(pamat[3], state.co);
|
||||
pamat[3][3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
|
||||
for (go = part->dup_group->gobject.first, b = 0; go; go = go->next, b++) {
|
||||
|
||||
copy_m4_m4(tmat, oblist[b]->obmat);
|
||||
/* apply particle scale */
|
||||
mul_mat3_m4_fl(tmat, size * scale);
|
||||
mul_v3_fl(tmat[3], size * scale);
|
||||
/* group dupli offset, should apply after everything else */
|
||||
if (!is_zero_v3(part->dup_group->dupli_ofs))
|
||||
sub_v3_v3(tmat[3], part->dup_group->dupli_ofs);
|
||||
/* individual particle transform */
|
||||
mul_m4_m4m4(mat, pamat, tmat);
|
||||
|
||||
dob = make_dupli(ctx, go->ob, mat, a, false, false);
|
||||
dob->particle_system = psys;
|
||||
if (use_texcoords)
|
||||
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* to give ipos in object correct offset */
|
||||
BKE_object_where_is_calc_time(scene, ob, ctime - pa_time);
|
||||
|
||||
copy_v3_v3(vec, obmat[3]);
|
||||
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
|
||||
|
||||
/* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */
|
||||
if ((part->draw & PART_DRAW_ROTATE_OB) == 0) {
|
||||
float xvec[3], q[4], size_mat[4][4], original_size[3];
|
||||
|
||||
mat4_to_size(original_size, obmat);
|
||||
size_to_mat4(size_mat, original_size);
|
||||
|
||||
xvec[0] = -1.f;
|
||||
xvec[1] = xvec[2] = 0;
|
||||
vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
|
||||
quat_to_mat4(obmat, q);
|
||||
obmat[3][3] = 1.0f;
|
||||
|
||||
/* add scaling if requested */
|
||||
if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0)
|
||||
mul_m4_m4m4(obmat, obmat, size_mat);
|
||||
}
|
||||
else if (part->draw & PART_DRAW_NO_SCALE_OB) {
|
||||
/* remove scaling */
|
||||
float size_mat[4][4], original_size[3];
|
||||
|
||||
mat4_to_size(original_size, obmat);
|
||||
size_to_mat4(size_mat, original_size);
|
||||
invert_m4(size_mat);
|
||||
|
||||
mul_m4_m4m4(obmat, obmat, size_mat);
|
||||
}
|
||||
|
||||
mul_m4_m4m4(tmat, pamat, obmat);
|
||||
mul_mat3_m4_fl(tmat, size * scale);
|
||||
|
||||
copy_m4_m4(mat, tmat);
|
||||
|
||||
if (part->draw & PART_DRAW_GLOBAL_OB)
|
||||
add_v3_v3v3(mat[3], mat[3], vec);
|
||||
|
||||
dob = make_dupli(ctx, ob, mat, a, false, false);
|
||||
dob->particle_system = psys;
|
||||
if (use_texcoords)
|
||||
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
|
||||
/* XXX blender internal needs this to be set to dupligroup to render
|
||||
* groups correctly, but we don't want this hack for cycles */
|
||||
if (dupli_type_hack && ctx->group)
|
||||
dob->type = OB_DUPLIGROUP;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore objects since they were changed in BKE_object_where_is_calc_time */
|
||||
if (part->ren_as == PART_DRAW_GR) {
|
||||
for (a = 0; a < totgroup; a++)
|
||||
*(oblist[a]) = obcopylist[a];
|
||||
}
|
||||
else
|
||||
*ob = obcopy;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
if (oblist)
|
||||
MEM_freeN(oblist);
|
||||
if (obcopylist)
|
||||
MEM_freeN(obcopylist);
|
||||
|
||||
if (psys->lattice_deform_data) {
|
||||
end_latt_deform(psys->lattice_deform_data);
|
||||
psys->lattice_deform_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void make_duplis_particles(const DupliContext *ctx)
|
||||
{
|
||||
ParticleSystem *psys;
|
||||
int psysid;
|
||||
|
||||
/* particle system take up one level in id, the particles another */
|
||||
for (psys = ctx->object->particlesystem.first, psysid = 0; psys; psys = psys->next, psysid++) {
|
||||
/* particles create one more level for persistent psys index */
|
||||
DupliContext pctx;
|
||||
copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid, false);
|
||||
make_duplis_particle_system(&pctx, psys);
|
||||
}
|
||||
}
|
||||
|
||||
const DupliGenerator gen_dupli_particles = {
|
||||
OB_DUPLIPARTS, /* type */
|
||||
make_duplis_particles /* make_duplis */
|
||||
};
|
||||
|
||||
/* ------------- */
|
||||
|
||||
/* select dupli generator from given context */
|
||||
@@ -1161,10 +840,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
|
||||
if (ctx->eval_ctx->mode == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) : (restrictflag & OB_RESTRICT_VIEW))
|
||||
return NULL;
|
||||
|
||||
if (transflag & OB_DUPLIPARTS) {
|
||||
return &gen_dupli_particles;
|
||||
}
|
||||
else if (transflag & OB_DUPLIVERTS) {
|
||||
if (transflag & OB_DUPLIVERTS) {
|
||||
if (ctx->object->type == OB_MESH) {
|
||||
return &gen_dupli_verts;
|
||||
}
|
||||
@@ -1222,12 +898,8 @@ int count_duplilist(Object *ob)
|
||||
if (ob->transflag & OB_DUPLIVERTS) {
|
||||
if (ob->type == OB_MESH) {
|
||||
if (ob->transflag & OB_DUPLIVERTS) {
|
||||
ParticleSystem *psys = ob->particlesystem.first;
|
||||
int pdup = 0;
|
||||
|
||||
for (; psys; psys = psys->next)
|
||||
pdup += psys->totpart;
|
||||
|
||||
if (pdup == 0) {
|
||||
Mesh *me = ob->data;
|
||||
return me->totvert;
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
@@ -53,7 +54,6 @@
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_image.h"
|
||||
@@ -257,53 +257,6 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
|
||||
else if (ob->type == OB_LAMP)
|
||||
lamp_drivers_update(scene, ob->data, ctime);
|
||||
|
||||
/* particles */
|
||||
if (ob != scene->obedit && ob->particlesystem.first) {
|
||||
ParticleSystem *tpsys, *psys;
|
||||
DerivedMesh *dm;
|
||||
ob->transflag &= ~OB_DUPLIPARTS;
|
||||
psys = ob->particlesystem.first;
|
||||
while (psys) {
|
||||
/* ensure this update always happens even if psys is disabled */
|
||||
if (psys->recalc & PSYS_RECALC_TYPE) {
|
||||
psys_changed_type(ob, psys);
|
||||
}
|
||||
|
||||
if (psys_check_enabled(ob, psys, eval_ctx->mode == DAG_EVAL_RENDER)) {
|
||||
/* check use of dupli objects here */
|
||||
if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) &&
|
||||
((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) ||
|
||||
(psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
|
||||
{
|
||||
ob->transflag |= OB_DUPLIPARTS;
|
||||
}
|
||||
|
||||
particle_system_update(scene, ob, psys, (eval_ctx->mode == DAG_EVAL_RENDER));
|
||||
psys = psys->next;
|
||||
}
|
||||
else if (psys->flag & PSYS_DELETE) {
|
||||
tpsys = psys->next;
|
||||
BLI_remlink(&ob->particlesystem, psys);
|
||||
psys_free(ob, psys);
|
||||
psys = tpsys;
|
||||
}
|
||||
else
|
||||
psys = psys->next;
|
||||
}
|
||||
|
||||
if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) {
|
||||
/* this is to make sure we get render level duplis in groups:
|
||||
* the derivedmesh must be created before init_render_mesh,
|
||||
* since object_duplilist does dupliparticles before that */
|
||||
CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL;
|
||||
dm = mesh_create_derived_render(scene, ob, data_mask);
|
||||
dm->release(dm);
|
||||
|
||||
for (psys = ob->particlesystem.first; psys; psys = psys->next)
|
||||
psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
}
|
||||
}
|
||||
|
||||
/* quick cache removed */
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,739 +0,0 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) Blender Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Lukas Toenne
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenkernel/intern/particle_child.c
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_noise.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_particle.h"
|
||||
|
||||
struct Material;
|
||||
|
||||
void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
|
||||
short type, short axis, float obmat[4][4], int smooth_start);
|
||||
float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
|
||||
bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
|
||||
void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
|
||||
ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
|
||||
ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t);
|
||||
|
||||
static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3])
|
||||
{
|
||||
float cross[3], nstrand[3], vnor[3], blend;
|
||||
|
||||
if (!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f)))
|
||||
return;
|
||||
|
||||
if (ma->mode & MA_STR_SURFDIFF) {
|
||||
cross_v3_v3v3(cross, surfnor, nor);
|
||||
cross_v3_v3v3(nstrand, nor, cross);
|
||||
|
||||
blend = dot_v3v3(nstrand, surfnor);
|
||||
CLAMP(blend, 0.0f, 1.0f);
|
||||
|
||||
interp_v3_v3v3(vnor, nstrand, surfnor, blend);
|
||||
normalize_v3(vnor);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(vnor, nor);
|
||||
}
|
||||
|
||||
if (ma->strand_surfnor > 0.0f) {
|
||||
if (ma->strand_surfnor > surfdist) {
|
||||
blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor;
|
||||
interp_v3_v3v3(vnor, vnor, surfnor, blend);
|
||||
normalize_v3(vnor);
|
||||
}
|
||||
}
|
||||
|
||||
copy_v3_v3(nor, vnor);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct ParticlePathIterator {
|
||||
ParticleCacheKey *key;
|
||||
int index;
|
||||
float time;
|
||||
|
||||
ParticleCacheKey *parent_key;
|
||||
float parent_rotation[4];
|
||||
} ParticlePathIterator;
|
||||
|
||||
static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *keys, int totkeys,
|
||||
ParticleCacheKey *parent, int index)
|
||||
{
|
||||
BLI_assert(index >= 0 && index < totkeys);
|
||||
|
||||
iter->key = keys + index;
|
||||
iter->index = index;
|
||||
iter->time = (float)index / (float)(totkeys - 1);
|
||||
|
||||
if (parent) {
|
||||
iter->parent_key = parent + index;
|
||||
if (index > 0)
|
||||
mul_qt_qtqt(iter->parent_rotation, iter->parent_key->rot, parent->rot);
|
||||
else
|
||||
copy_qt_qt(iter->parent_rotation, parent->rot);
|
||||
}
|
||||
else {
|
||||
iter->parent_key = NULL;
|
||||
unit_qt(iter->parent_rotation);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct ParticlePathModifier {
|
||||
struct ParticlePathModifier *next, *prev;
|
||||
|
||||
void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys);
|
||||
} ParticlePathModifier;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const float kink[3],
|
||||
float time, float freq, float shape, float amplitude,
|
||||
const float spiral_start[3])
|
||||
{
|
||||
float result[3];
|
||||
|
||||
CLAMP(time, 0.f, 1.f);
|
||||
|
||||
copy_v3_v3(result, state->co);
|
||||
|
||||
{
|
||||
/* Creates a logarithmic spiral:
|
||||
* r(theta) = a * exp(b * theta)
|
||||
*
|
||||
* The "density" parameter b is defined by the shape parameter
|
||||
* and goes up to the Golden Spiral for 1.0
|
||||
* http://en.wikipedia.org/wiki/Golden_spiral
|
||||
*/
|
||||
const float b = shape * (1.0f + sqrtf(5.0f)) / (float)M_PI * 0.25f;
|
||||
/* angle of the spiral against the curve (rotated opposite to make a smooth transition) */
|
||||
const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) :
|
||||
(float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2);
|
||||
|
||||
float spiral_axis[3], rot[3][3];
|
||||
float vec[3];
|
||||
|
||||
float theta = freq * time * 2.0f * (float)M_PI;
|
||||
float radius = amplitude * expf(b * theta);
|
||||
|
||||
/* a bit more intuitive than using negative frequency for this */
|
||||
if (amplitude < 0.0f)
|
||||
theta = -theta;
|
||||
|
||||
cross_v3_v3v3(spiral_axis, dir, kink);
|
||||
normalize_v3(spiral_axis);
|
||||
|
||||
mul_v3_v3fl(vec, kink, -radius);
|
||||
|
||||
axis_angle_normalized_to_mat3(rot, spiral_axis, theta);
|
||||
mul_m3_v3(rot, vec);
|
||||
|
||||
madd_v3_v3fl(vec, kink, amplitude);
|
||||
|
||||
axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle);
|
||||
mul_m3_v3(rot, vec);
|
||||
|
||||
add_v3_v3v3(result, spiral_start, vec);
|
||||
}
|
||||
|
||||
copy_v3_v3(state->co, result);
|
||||
}
|
||||
|
||||
static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, const float parent_orco[3],
|
||||
ChildParticle *cpa, const float orco[3], float hairmat[4][4],
|
||||
ParticleCacheKey *keys, ParticleCacheKey *parent_keys, int *r_totkeys, float *r_max_length)
|
||||
{
|
||||
struct ParticleSettings *part = ctx->sim.psys->part;
|
||||
const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child);
|
||||
const int totkeys = ctx->segments + 1;
|
||||
const int extrakeys = ctx->extra_segments;
|
||||
|
||||
float kink_amp_random = part->kink_amp_random;
|
||||
float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed));
|
||||
float kink_freq = part->kink_freq;
|
||||
float kink_shape = part->kink_shape;
|
||||
float kink_axis_random = part->kink_axis_random;
|
||||
float rough1 = part->rough1;
|
||||
float rough2 = part->rough2;
|
||||
float rough_end = part->rough_end;
|
||||
|
||||
ParticlePathIterator iter;
|
||||
ParticleCacheKey *key;
|
||||
int k;
|
||||
|
||||
float dir[3];
|
||||
float spiral_start[3] = {0.0f, 0.0f, 0.0f};
|
||||
float spiral_start_time = 0.0f;
|
||||
float spiral_par_co[3] = {0.0f, 0.0f, 0.0f};
|
||||
float spiral_par_vel[3] = {0.0f, 0.0f, 0.0f};
|
||||
float spiral_par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
|
||||
float totlen;
|
||||
float cut_time;
|
||||
int start_index = 0, end_index = 0;
|
||||
float kink_base[3];
|
||||
|
||||
if (ptex) {
|
||||
kink_amp *= ptex->kink_amp;
|
||||
kink_freq *= ptex->kink_freq;
|
||||
rough1 *= ptex->rough1;
|
||||
rough2 *= ptex->rough2;
|
||||
rough_end *= ptex->roughe;
|
||||
}
|
||||
|
||||
cut_time = (totkeys - 1) * ptex->length;
|
||||
zero_v3(spiral_start);
|
||||
|
||||
for (k = 0, key = keys; k < totkeys-1; k++, key++) {
|
||||
if ((float)(k + 1) >= cut_time) {
|
||||
float fac = cut_time - (float)k;
|
||||
ParticleCacheKey *par = parent_keys + k;
|
||||
|
||||
start_index = k + 1;
|
||||
end_index = start_index + extrakeys;
|
||||
|
||||
spiral_start_time = ((float)k + fac) / (float)(totkeys - 1);
|
||||
interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac);
|
||||
|
||||
interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac);
|
||||
interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac);
|
||||
interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zero_v3(dir);
|
||||
|
||||
zero_v3(kink_base);
|
||||
kink_base[part->kink_axis] = 1.0f;
|
||||
mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
|
||||
|
||||
for (k = 0, key = keys; k < end_index; k++, key++) {
|
||||
float par_time;
|
||||
float *par_co, *par_vel, *par_rot;
|
||||
|
||||
psys_path_iter_get(&iter, keys, end_index, NULL, k);
|
||||
if (k < start_index) {
|
||||
sub_v3_v3v3(dir, (key+1)->co, key->co);
|
||||
normalize_v3(dir);
|
||||
|
||||
par_time = (float)k / (float)(totkeys - 1);
|
||||
par_co = parent_keys[k].co;
|
||||
par_vel = parent_keys[k].vel;
|
||||
par_rot = parent_keys[k].rot;
|
||||
}
|
||||
else {
|
||||
float spiral_time = (float)(k - start_index) / (float)(extrakeys-1);
|
||||
float kink[3], tmp[3];
|
||||
|
||||
/* use same time value for every point on the spiral */
|
||||
par_time = spiral_start_time;
|
||||
par_co = spiral_par_co;
|
||||
par_vel = spiral_par_vel;
|
||||
par_rot = spiral_par_rot;
|
||||
|
||||
project_v3_v3v3(tmp, kink_base, dir);
|
||||
sub_v3_v3v3(kink, kink_base, tmp);
|
||||
normalize_v3(kink);
|
||||
|
||||
if (kink_axis_random > 0.0f) {
|
||||
float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI;
|
||||
float rot[3][3];
|
||||
|
||||
axis_angle_normalized_to_mat3(rot, dir, a);
|
||||
mul_m3_v3(rot, kink);
|
||||
}
|
||||
|
||||
do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start);
|
||||
}
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time);
|
||||
}
|
||||
|
||||
totlen = 0.0f;
|
||||
for (k = 0, key = keys; k < end_index-1; k++, key++)
|
||||
totlen += len_v3v3((key+1)->co, key->co);
|
||||
|
||||
*r_totkeys = end_index;
|
||||
*r_max_length = totlen;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static bool check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *key, float max_length, float step_length, float *cur_length, float dvec[3])
|
||||
{
|
||||
if (*cur_length + step_length > max_length) {
|
||||
sub_v3_v3v3(dvec, key->co, (key-1)->co);
|
||||
mul_v3_fl(dvec, (max_length - *cur_length) / step_length);
|
||||
add_v3_v3v3(key->co, (key-1)->co, dvec);
|
||||
keys->segments = k;
|
||||
/* something over the maximum step value */
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
*cur_length += step_length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *modifiers,
|
||||
ChildParticle *cpa, ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
|
||||
ParticleCacheKey *keys, ParticleCacheKey *parent_keys, const float parent_orco[3])
|
||||
{
|
||||
struct ParticleSettings *part = ctx->sim.psys->part;
|
||||
struct Material *ma = ctx->ma;
|
||||
const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT);
|
||||
const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL);
|
||||
|
||||
ParticlePathModifier *mod;
|
||||
ParticleCacheKey *key;
|
||||
int totkeys, k;
|
||||
float max_length;
|
||||
|
||||
#if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */
|
||||
for (mod = modifiers->first; mod; mod = mod->next) {
|
||||
mod->apply(keys, totkeys, parent_keys);
|
||||
}
|
||||
#else
|
||||
(void)modifiers;
|
||||
(void)mod;
|
||||
|
||||
if (part->kink == PART_KINK_SPIRAL) {
|
||||
do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length);
|
||||
keys->segments = totkeys - 1;
|
||||
}
|
||||
else {
|
||||
ParticlePathIterator iter;
|
||||
|
||||
totkeys = ctx->segments + 1;
|
||||
max_length = ptex->length;
|
||||
|
||||
for (k = 0, key = keys; k < totkeys; k++, key++) {
|
||||
ParticleKey *par;
|
||||
|
||||
psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
|
||||
par = (ParticleKey *)iter.parent_key;
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const float step_length = 1.0f / (float)(totkeys - 1);
|
||||
|
||||
float cur_length = 0.0f;
|
||||
|
||||
/* we have to correct velocity because of kink & clump */
|
||||
for (k = 0, key = keys; k < totkeys; ++k, ++key) {
|
||||
if (k >= 2) {
|
||||
sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
|
||||
mul_v3_fl((key-1)->vel, 0.5);
|
||||
|
||||
if (ma && draw_col_ma)
|
||||
get_strand_normal(ma, ornor, cur_length, (key-1)->vel);
|
||||
}
|
||||
|
||||
if (use_length_check && k > 1) {
|
||||
float dvec[3];
|
||||
/* check if path needs to be cut before actual end of data points */
|
||||
if (!check_path_length(k, keys, key, max_length, step_length, &cur_length, dvec)) {
|
||||
/* last key */
|
||||
sub_v3_v3v3(key->vel, key->co, (key-1)->co);
|
||||
if (ma && draw_col_ma) {
|
||||
copy_v3_v3(key->col, &ma->r);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == totkeys-1) {
|
||||
/* last key */
|
||||
sub_v3_v3v3(key->vel, key->co, (key-1)->co);
|
||||
}
|
||||
|
||||
if (ma && draw_col_ma) {
|
||||
copy_v3_v3(key->col, &ma->r);
|
||||
get_strand_normal(ma, ornor, cur_length, key->vel);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape,
|
||||
float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
|
||||
{
|
||||
float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
|
||||
float t, dt = 1.f, result[3];
|
||||
|
||||
if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL))
|
||||
return;
|
||||
|
||||
CLAMP(time, 0.f, 1.f);
|
||||
|
||||
if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
|
||||
if (shape < 0.0f)
|
||||
time = (float)pow(time, 1.f + shape);
|
||||
else
|
||||
time = (float)pow(time, 1.f / (1.f - shape));
|
||||
}
|
||||
|
||||
t = time * freq * (float)M_PI;
|
||||
|
||||
if (smooth_start) {
|
||||
dt = fabsf(t);
|
||||
/* smooth the beginning of kink */
|
||||
CLAMP(dt, 0.f, (float)M_PI);
|
||||
dt = sinf(dt / 2.f);
|
||||
}
|
||||
|
||||
if (!ELEM(type, PART_KINK_RADIAL)) {
|
||||
float temp[3];
|
||||
|
||||
kink[axis] = 1.f;
|
||||
|
||||
if (obmat)
|
||||
mul_mat3_m4_v3(obmat, kink);
|
||||
|
||||
mul_qt_v3(par_rot, kink);
|
||||
|
||||
/* make sure kink is normal to strand */
|
||||
project_v3_v3v3(temp, kink, par_vel);
|
||||
sub_v3_v3(kink, temp);
|
||||
normalize_v3(kink);
|
||||
}
|
||||
|
||||
copy_v3_v3(result, state->co);
|
||||
sub_v3_v3v3(par_vec, par_co, state->co);
|
||||
|
||||
switch (type) {
|
||||
case PART_KINK_CURL:
|
||||
{
|
||||
float curl_offset[3];
|
||||
|
||||
/* rotate kink vector around strand tangent */
|
||||
mul_v3_v3fl(curl_offset, kink, amplitude);
|
||||
axis_angle_to_quat(q1, par_vel, t);
|
||||
mul_qt_v3(q1, curl_offset);
|
||||
|
||||
interp_v3_v3v3(par_vec, state->co, par_co, flat);
|
||||
add_v3_v3v3(result, par_vec, curl_offset);
|
||||
break;
|
||||
}
|
||||
case PART_KINK_RADIAL:
|
||||
{
|
||||
if (flat > 0.f) {
|
||||
float proj[3];
|
||||
/* flatten along strand */
|
||||
project_v3_v3v3(proj, par_vec, par_vel);
|
||||
madd_v3_v3fl(result, proj, flat);
|
||||
}
|
||||
|
||||
madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
|
||||
break;
|
||||
}
|
||||
case PART_KINK_WAVE:
|
||||
{
|
||||
madd_v3_v3fl(result, kink, amplitude * sinf(t));
|
||||
|
||||
if (flat > 0.f) {
|
||||
float proj[3];
|
||||
/* flatten along wave */
|
||||
project_v3_v3v3(proj, par_vec, kink);
|
||||
madd_v3_v3fl(result, proj, flat);
|
||||
|
||||
/* flatten along strand */
|
||||
project_v3_v3v3(proj, par_vec, par_vel);
|
||||
madd_v3_v3fl(result, proj, flat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PART_KINK_BRAID:
|
||||
{
|
||||
float y_vec[3] = {0.f, 1.f, 0.f};
|
||||
float z_vec[3] = {0.f, 0.f, 1.f};
|
||||
float vec_one[3], state_co[3];
|
||||
float inp_y, inp_z, length;
|
||||
|
||||
if (par_rot) {
|
||||
mul_qt_v3(par_rot, y_vec);
|
||||
mul_qt_v3(par_rot, z_vec);
|
||||
}
|
||||
|
||||
negate_v3(par_vec);
|
||||
normalize_v3_v3(vec_one, par_vec);
|
||||
|
||||
inp_y = dot_v3v3(y_vec, vec_one);
|
||||
inp_z = dot_v3v3(z_vec, vec_one);
|
||||
|
||||
if (inp_y > 0.5f) {
|
||||
copy_v3_v3(state_co, y_vec);
|
||||
|
||||
mul_v3_fl(y_vec, amplitude * cosf(t));
|
||||
mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
|
||||
}
|
||||
else if (inp_z > 0.0f) {
|
||||
mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
|
||||
madd_v3_v3fl(state_co, y_vec, -0.5f);
|
||||
|
||||
mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
|
||||
mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
|
||||
}
|
||||
else {
|
||||
mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
|
||||
madd_v3_v3fl(state_co, y_vec, -0.5f);
|
||||
|
||||
mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
|
||||
mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
|
||||
}
|
||||
|
||||
mul_v3_fl(state_co, amplitude);
|
||||
add_v3_v3(state_co, par_co);
|
||||
sub_v3_v3v3(par_vec, state->co, state_co);
|
||||
|
||||
length = normalize_v3(par_vec);
|
||||
mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
|
||||
|
||||
add_v3_v3v3(state_co, par_co, y_vec);
|
||||
add_v3_v3(state_co, z_vec);
|
||||
add_v3_v3(state_co, par_vec);
|
||||
|
||||
shape = 2.f * (float)M_PI * (1.f + shape);
|
||||
|
||||
if (t < shape) {
|
||||
shape = t / shape;
|
||||
shape = (float)sqrt((double)shape);
|
||||
interp_v3_v3v3(result, result, state_co, shape);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(result, state_co);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* blend the start of the kink */
|
||||
if (dt < 1.f)
|
||||
interp_v3_v3v3(state->co, state->co, result, dt);
|
||||
else
|
||||
copy_v3_v3(state->co, result);
|
||||
}
|
||||
|
||||
static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
|
||||
float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
|
||||
{
|
||||
float clump = 0.0f;
|
||||
|
||||
if (clumpcurve) {
|
||||
clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
|
||||
|
||||
interp_v3_v3v3(result, co, par_co, clump);
|
||||
}
|
||||
else if (clumpfac != 0.0f) {
|
||||
float cpow;
|
||||
|
||||
if (clumppow < 0.0f)
|
||||
cpow = 1.0f + clumppow;
|
||||
else
|
||||
cpow = 1.0f + 9.0f * clumppow;
|
||||
|
||||
if (clumpfac < 0.0f) /* clump roots instead of tips */
|
||||
clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
|
||||
else
|
||||
clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
|
||||
|
||||
interp_v3_v3v3(result, co, par_co, clump);
|
||||
}
|
||||
|
||||
return clump;
|
||||
}
|
||||
|
||||
float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
|
||||
bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
|
||||
{
|
||||
float clump;
|
||||
|
||||
if (use_clump_noise && clump_noise_size != 0.0f) {
|
||||
float center[3], noisevec[3];
|
||||
float da[4], pa[12];
|
||||
|
||||
mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
|
||||
voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
|
||||
mul_v3_fl(&pa[0], clump_noise_size);
|
||||
add_v3_v3v3(center, par_co, &pa[0]);
|
||||
|
||||
do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
|
||||
}
|
||||
|
||||
clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
|
||||
|
||||
return clump;
|
||||
}
|
||||
|
||||
static void do_rough(const float loc[3], float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
|
||||
{
|
||||
float rough[3];
|
||||
float rco[3];
|
||||
|
||||
if (thres != 0.0f) {
|
||||
if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
copy_v3_v3(rco, loc);
|
||||
mul_v3_fl(rco, t);
|
||||
rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
|
||||
rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
|
||||
rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
|
||||
|
||||
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
|
||||
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
|
||||
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
|
||||
}
|
||||
|
||||
static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
|
||||
{
|
||||
float rough[2];
|
||||
float roughfac;
|
||||
|
||||
roughfac = fac * (float)pow((double)t, shape);
|
||||
copy_v2_v2(rough, loc);
|
||||
rough[0] = -1.0f + 2.0f * rough[0];
|
||||
rough[1] = -1.0f + 2.0f * rough[1];
|
||||
mul_v2_fl(rough, roughfac);
|
||||
|
||||
madd_v3_v3fl(state->co, mat[0], rough[0]);
|
||||
madd_v3_v3fl(state->co, mat[1], rough[1]);
|
||||
}
|
||||
|
||||
static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
|
||||
{
|
||||
float rough[3];
|
||||
float rco[3];
|
||||
|
||||
if (!roughcurve)
|
||||
return;
|
||||
|
||||
fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
|
||||
|
||||
copy_v3_v3(rco, loc);
|
||||
mul_v3_fl(rco, time);
|
||||
rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
|
||||
rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
|
||||
rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
|
||||
|
||||
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
|
||||
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
|
||||
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
|
||||
}
|
||||
|
||||
void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, ParticleTexture *ptex,
|
||||
const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
|
||||
ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
|
||||
int i = cpa - sim->psys->child;
|
||||
int guided = 0;
|
||||
|
||||
if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
|
||||
clumpcurve = (ctx != NULL) ? ctx->clumpcurve : part->clumpcurve;
|
||||
}
|
||||
if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
|
||||
roughcurve = (ctx != NULL) ? ctx->roughcurve : part->roughcurve;
|
||||
}
|
||||
|
||||
float kink_amp = part->kink_amp;
|
||||
float kink_amp_clump = part->kink_amp_clump;
|
||||
float kink_freq = part->kink_freq;
|
||||
float rough1 = part->rough1;
|
||||
float rough2 = part->rough2;
|
||||
float rough_end = part->rough_end;
|
||||
const bool smooth_start = (sim->psys->part->childtype == PART_CHILD_FACES);
|
||||
|
||||
if (ptex) {
|
||||
kink_amp *= ptex->kink_amp;
|
||||
kink_freq *= ptex->kink_freq;
|
||||
rough1 *= ptex->rough1;
|
||||
rough2 *= ptex->rough2;
|
||||
rough_end *= ptex->roughe;
|
||||
}
|
||||
|
||||
if (part->flag & PART_CHILD_EFFECT)
|
||||
/* state is safe to cast, since only co and vel are used */
|
||||
guided = do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
|
||||
|
||||
if (guided == 0) {
|
||||
float orco_offset[3];
|
||||
float clump;
|
||||
|
||||
sub_v3_v3v3(orco_offset, orco, par_orco);
|
||||
clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f,
|
||||
part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
|
||||
|
||||
if (kink_freq != 0.f) {
|
||||
kink_amp *= (1.f - kink_amp_clump * clump);
|
||||
|
||||
do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape,
|
||||
kink_amp, part->kink_flat, part->kink, part->kink_axis,
|
||||
sim->ob->obmat, smooth_start);
|
||||
}
|
||||
}
|
||||
|
||||
if (roughcurve) {
|
||||
do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state);
|
||||
}
|
||||
else {
|
||||
if (rough1 > 0.f)
|
||||
do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
|
||||
|
||||
if (rough2 > 0.f) {
|
||||
float vec[3];
|
||||
psys_frand_vec(sim->psys, i + 27, vec);
|
||||
do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
|
||||
}
|
||||
|
||||
if (rough_end > 0.f) {
|
||||
float vec[3];
|
||||
psys_frand_vec(sim->psys, i + 27, vec);
|
||||
do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,6 @@
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_rigidbody.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
@@ -108,10 +107,6 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
|
||||
if (rbw->objects)
|
||||
free(rbw->objects);
|
||||
|
||||
/* free cache */
|
||||
BKE_ptcache_free_list(&(rbw->ptcaches));
|
||||
rbw->pointcache = NULL;
|
||||
|
||||
/* free effector weights */
|
||||
if (rbw->effector_weights)
|
||||
MEM_freeN(rbw->effector_weights);
|
||||
@@ -921,9 +916,6 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
|
||||
rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
|
||||
rbw->num_solver_iterations = 10; /* 10 is bullet default */
|
||||
|
||||
rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
|
||||
rbw->pointcache->step = 1;
|
||||
|
||||
/* return this sim world */
|
||||
return rbw;
|
||||
}
|
||||
@@ -939,8 +931,6 @@ RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
|
||||
if (rbwn->constraints)
|
||||
id_us_plus(&rbwn->constraints->id);
|
||||
|
||||
rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, false);
|
||||
|
||||
rbwn->objects = NULL;
|
||||
rbwn->physics_world = NULL;
|
||||
rbwn->numbodies = 0;
|
||||
@@ -973,10 +963,9 @@ void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func,
|
||||
}
|
||||
|
||||
/* Add rigid body settings to the specified object */
|
||||
RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
|
||||
RigidBodyOb *BKE_rigidbody_create_object(Scene *UNUSED(scene), Object *ob, short type)
|
||||
{
|
||||
RigidBodyOb *rbo;
|
||||
RigidBodyWorld *rbw = scene->rigidbody_world;
|
||||
|
||||
/* sanity checks
|
||||
* - rigidbody world must exist
|
||||
@@ -1020,18 +1009,14 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
|
||||
/* set initial transform */
|
||||
mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
|
||||
|
||||
/* flag cache as outdated */
|
||||
BKE_rigidbody_cache_reset(rbw);
|
||||
|
||||
/* return this object */
|
||||
return rbo;
|
||||
}
|
||||
|
||||
/* Add rigid body constraint to the specified object */
|
||||
RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
|
||||
RigidBodyCon *BKE_rigidbody_create_constraint(Scene *UNUSED(scene), Object *ob, short type)
|
||||
{
|
||||
RigidBodyCon *rbc;
|
||||
RigidBodyWorld *rbw = scene->rigidbody_world;
|
||||
|
||||
/* sanity checks
|
||||
* - rigidbody world must exist
|
||||
@@ -1081,9 +1066,6 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
|
||||
rbc->motor_ang_max_impulse = 1.0f;
|
||||
rbc->motor_ang_target_velocity = 1.0f;
|
||||
|
||||
/* flag cache as outdated */
|
||||
BKE_rigidbody_cache_reset(rbw);
|
||||
|
||||
/* return this object */
|
||||
return rbc;
|
||||
}
|
||||
@@ -1143,9 +1125,6 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
|
||||
|
||||
/* remove object's settings */
|
||||
BKE_rigidbody_free_object(ob);
|
||||
|
||||
/* flag cache as outdated */
|
||||
BKE_rigidbody_cache_reset(rbw);
|
||||
}
|
||||
|
||||
void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
|
||||
@@ -1159,9 +1138,6 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
|
||||
}
|
||||
/* remove object's settings */
|
||||
BKE_rigidbody_free_constraint(ob);
|
||||
|
||||
/* flag cache as outdated */
|
||||
BKE_rigidbody_cache_reset(rbw);
|
||||
}
|
||||
|
||||
|
||||
@@ -1255,7 +1231,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
|
||||
ListBase *effectors;
|
||||
|
||||
/* get effectors present in the group specified by effector_weights */
|
||||
effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true);
|
||||
effectors = pdInitEffectors(scene, ob, effector_weights, true);
|
||||
if (effectors) {
|
||||
float eff_force[3] = {0.0f, 0.0f, 0.0f};
|
||||
float eff_loc[3], eff_vel[3];
|
||||
@@ -1428,9 +1404,9 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
|
||||
}
|
||||
}
|
||||
|
||||
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
|
||||
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float UNUSED(ctime))
|
||||
{
|
||||
return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe);
|
||||
return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0);
|
||||
}
|
||||
|
||||
/* Sync rigid body and object transformations */
|
||||
@@ -1493,12 +1469,6 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
|
||||
// RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
|
||||
}
|
||||
|
||||
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
|
||||
{
|
||||
if (rbw)
|
||||
rbw->pointcache->flag |= PTCACHE_OUTDATED;
|
||||
}
|
||||
|
||||
/* ------------------ */
|
||||
|
||||
/* Rebuild rigid body world */
|
||||
@@ -1506,27 +1476,10 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
|
||||
void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
|
||||
{
|
||||
RigidBodyWorld *rbw = scene->rigidbody_world;
|
||||
PointCache *cache;
|
||||
PTCacheID pid;
|
||||
int startframe, endframe;
|
||||
|
||||
BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
|
||||
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
|
||||
cache = rbw->pointcache;
|
||||
|
||||
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
|
||||
if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
|
||||
cache->flag |= PTCACHE_OUTDATED;
|
||||
}
|
||||
int startframe = scene->r.sfra;
|
||||
|
||||
if (ctime == startframe + 1 && rbw->ltime == startframe) {
|
||||
if (cache->flag & PTCACHE_OUTDATED) {
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
rigidbody_update_simulation(scene, rbw, true);
|
||||
BKE_ptcache_validate(cache, (int)ctime);
|
||||
cache->last_exact = 0;
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
}
|
||||
rigidbody_update_simulation(scene, rbw, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1535,13 +1488,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
|
||||
{
|
||||
float timestep;
|
||||
RigidBodyWorld *rbw = scene->rigidbody_world;
|
||||
PointCache *cache;
|
||||
PTCacheID pid;
|
||||
int startframe, endframe;
|
||||
|
||||
BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
|
||||
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
|
||||
cache = rbw->pointcache;
|
||||
int startframe = scene->r.sfra, endframe = scene->r.efra;
|
||||
|
||||
if (ctime <= startframe) {
|
||||
rbw->ltime = startframe;
|
||||
@@ -1552,29 +1499,14 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
|
||||
ctime = endframe;
|
||||
}
|
||||
|
||||
/* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
|
||||
if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
|
||||
/* don't try to run the simulation if we don't have a world yet */
|
||||
if (rbw->physics_world == NULL)
|
||||
return;
|
||||
else if (rbw->objects == NULL)
|
||||
rigidbody_update_ob_array(rbw);
|
||||
|
||||
/* try to read from cache */
|
||||
// RB_TODO deal with interpolated, old and baked results
|
||||
bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
|
||||
|
||||
if (BKE_ptcache_read(&pid, ctime, can_simulate)) {
|
||||
BKE_ptcache_validate(cache, (int)ctime);
|
||||
rbw->ltime = ctime;
|
||||
return;
|
||||
}
|
||||
|
||||
/* advance simulation, we can only step one frame forward */
|
||||
if (can_simulate) {
|
||||
/* write cache for first frame when on second frame */
|
||||
if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
|
||||
BKE_ptcache_write(&pid, startframe);
|
||||
}
|
||||
|
||||
if (ctime == rbw->ltime + 1) {
|
||||
/* update and validate simulation */
|
||||
rigidbody_update_simulation(scene, rbw, false);
|
||||
|
||||
@@ -1585,10 +1517,6 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
|
||||
|
||||
rigidbody_update_simulation_post_step(rbw);
|
||||
|
||||
/* write cache for current frame */
|
||||
BKE_ptcache_validate(cache, (int)ctime);
|
||||
BKE_ptcache_write(&pid, (unsigned int)ctime);
|
||||
|
||||
rbw->ltime = ctime;
|
||||
}
|
||||
}
|
||||
@@ -1623,7 +1551,6 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
|
||||
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
|
||||
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
|
||||
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
|
||||
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
|
||||
void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {}
|
||||
void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user