aboutsummaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorJuan Linietsky2016-11-24 20:46:55 -0300
committerJuan Linietsky2016-11-24 20:46:55 -0300
commita732708b9dad4ebc118a0ce854f950c6becb984c (patch)
tree4e740d30a2449e065462bc408e23536d5270ca0e /servers
parent69c30709ec6908e0960707501cc7fea58eb64f01 (diff)
downloadgodot-a732708b9dad4ebc118a0ce854f950c6becb984c.tar.gz
godot-a732708b9dad4ebc118a0ce854f950c6becb984c.tar.zst
godot-a732708b9dad4ebc118a0ce854f950c6becb984c.zip
Blend shapes using transform feedback (GPU)
Diffstat (limited to 'servers')
-rw-r--r--servers/visual/rasterizer.h3
-rw-r--r--servers/visual/visual_server_scene.cpp27
-rw-r--r--servers/visual_server.cpp12
3 files changed, 32 insertions, 10 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 5f536b8fd..21cf391af 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -380,7 +380,8 @@ public:
virtual void portal_set_disable_distance(RID p_portal, float p_distance)=0;
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color)=0;
-
+ virtual void instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance)=0;
+ virtual void instance_remove_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance)=0;
virtual void instance_add_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance)=0;
virtual void instance_remove_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance)=0;
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 2439eacd7..0f7dabcc1 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -738,13 +738,25 @@ void VisualServerScene::instance_attach_object_instance_ID(RID p_instance,Object
}
void VisualServerScene::instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight){
+ Instance *instance = instance_owner.get( p_instance );
+ ERR_FAIL_COND( !instance );
+
+ if (instance->update_item.in_list()) {
+ _update_dirty_instance(instance);
+ }
+
+ ERR_FAIL_INDEX(p_shape,instance->morph_values.size());
+ instance->morph_values[p_shape]=p_weight;
}
+
void VisualServerScene::instance_set_surface_material(RID p_instance,int p_surface, RID p_material){
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
- _update_dirty_instance(instance);
+ if (instance->update_item.in_list()) {
+ _update_dirty_instance(instance);
+ }
ERR_FAIL_INDEX(p_surface,instance->materials.size());
@@ -770,13 +782,13 @@ void VisualServerScene::instance_attach_skeleton(RID p_instance,RID p_skeleton){
return;
if (instance->skeleton.is_valid()) {
- VSG::storage->instance_remove_dependency(p_skeleton,instance);
+ VSG::storage->instance_remove_skeleton(p_skeleton,instance);
}
instance->skeleton=p_skeleton;
if (instance->skeleton.is_valid()) {
- VSG::storage->instance_add_dependency(p_skeleton,instance);
+ VSG::storage->instance_add_skeleton(p_skeleton,instance);
}
_instance_queue_update(instance,true);
@@ -2227,6 +2239,7 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (p_instance->update_aabb)
_update_instance_aabb(p_instance);
+
if (p_instance->update_materials) {
if (p_instance->base_type==VS::INSTANCE_MESH) {
@@ -2239,6 +2252,14 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
}
}
p_instance->materials.resize(new_mat_count);
+
+ int new_morph_count = VSG::storage->mesh_get_morph_target_count(p_instance->base);
+ if (new_morph_count!=p_instance->morph_values.size()) {
+ p_instance->morph_values.resize(new_morph_count);
+ for(int i=0;i<new_morph_count;i++) {
+ p_instance->morph_values[i]=0;
+ }
+ }
}
if ((1<<p_instance->base_type)&VS::INSTANCE_GEOMETRY_MASK) {
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 27b08c4c5..ac894f128 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -709,7 +709,7 @@ Error VisualServer::_surface_set_data(Array p_arrays,uint32_t p_format,uint32_t
} break;
case VS::ARRAY_BONES: {
- ERR_FAIL_COND_V( p_arrays[ai].get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER );
+ ERR_FAIL_COND_V( p_arrays[ai].get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER );
DVector<int> array = p_arrays[ai];
@@ -912,7 +912,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh,PrimitiveType p_primi
bsformat|=(1<<j);
}
- ERR_FAIL_COND( (bsformat)!=(format&(VS::ARRAY_FORMAT_BONES-1)));
+ ERR_FAIL_COND( (bsformat)!=(format&(VS::ARRAY_FORMAT_INDEX-1)));
}
}
@@ -1089,7 +1089,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh,PrimitiveType p_primi
DVector<uint8_t> noindex;
AABB laabb;
- Error err = _surface_set_data(p_blend_shapes[i],format&~ARRAY_FORMAT_INDEX,offsets,total_elem_size,vertex_array,array_len,noindex,0,laabb,bone_aabb);
+ Error err = _surface_set_data(p_blend_shapes[i],format&~ARRAY_FORMAT_INDEX,offsets,total_elem_size,vertex_array_shape,array_len,noindex,0,laabb,bone_aabb);
aabb.merge_with(laabb);
if (err) {
ERR_EXPLAIN("Invalid blend shape array format for surface");
@@ -1194,9 +1194,9 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format,DVector<uint8_t> p
case VS::ARRAY_BONES: {
if (p_format&ARRAY_FLAG_USE_16_BIT_BONES) {
- elem_size=sizeof(uint32_t);
- } else {
elem_size=sizeof(uint16_t)*4;
+ } else {
+ elem_size=sizeof(uint32_t);
}
} break;
@@ -1487,7 +1487,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format,DVector<uint8_t> p
DVector<int>::Write w = arr.write();
for(int j=0;j<p_vertex_len;j++) {
- const int *v = (const int*)&r[j*total_elem_size+offsets[i]];
+ const uint8_t *v = (const uint8_t*)&r[j*total_elem_size+offsets[i]];
for(int k=0;k<4;k++) {
w[j*4+k]=v[k];
}