mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
Blend shapes using transform feedback (GPU)
This commit is contained in:
parent
69c30709ec
commit
a732708b9d
@ -1111,7 +1111,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e) {
|
||||
case VS::INSTANCE_MESH: {
|
||||
|
||||
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface*>(e->geometry);
|
||||
glBindVertexArray(s->array_id); // everything is so easy nowadays
|
||||
|
||||
if (s->morph_targets.size() && e->instance->morph_values.size()) {
|
||||
//blend shapes, use transform feedback
|
||||
storage->mesh_render_blend_shapes(s,e->instance->morph_values.ptr());
|
||||
//rebind shader
|
||||
state.scene_shader.bind();
|
||||
} else {
|
||||
|
||||
glBindVertexArray(s->array_id); // everything is so easy nowadays
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
|
@ -2274,8 +2274,8 @@ void RasterizerStorageGLES3::_update_material(Material* material) {
|
||||
material->can_cast_shadow_cache=can_cast_shadow;
|
||||
material->is_animated_cache=is_animated;
|
||||
|
||||
for(Map<Instantiable*,int>::Element *E=material->instantiable_owners.front();E;E=E->next()) {
|
||||
E->key()->instance_material_change_notify();
|
||||
for(Map<Geometry*,int>::Element *E=material->geometry_owners.front();E;E=E->next()) {
|
||||
E->key()->material_changed_notify();
|
||||
}
|
||||
|
||||
for(Map<RasterizerScene::InstanceBase*,int>::Element *E=material->instance_owners.front();E;E=E->next()) {
|
||||
@ -2379,32 +2379,32 @@ void RasterizerStorageGLES3::_update_material(Material* material) {
|
||||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::_material_add_instantiable(RID p_material,Instantiable *p_instantiable) {
|
||||
void RasterizerStorageGLES3::_material_add_geometry(RID p_material,Geometry *p_geometry) {
|
||||
|
||||
Material * material = material_owner.getornull(p_material);
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
Map<Instantiable*,int>::Element *I = material->instantiable_owners.find(p_instantiable);
|
||||
Map<Geometry*,int>::Element *I = material->geometry_owners.find(p_geometry);
|
||||
|
||||
if (I) {
|
||||
I->get()++;
|
||||
} else {
|
||||
material->instantiable_owners[p_instantiable]=1;
|
||||
material->geometry_owners[p_geometry]=1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::_material_remove_instantiable(RID p_material,Instantiable *p_instantiable) {
|
||||
void RasterizerStorageGLES3::_material_remove_geometry(RID p_material,Geometry *p_geometry) {
|
||||
|
||||
Material * material = material_owner.getornull(p_material);
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
Map<Instantiable*,int>::Element *I = material->instantiable_owners.find(p_instantiable);
|
||||
Map<Geometry*,int>::Element *I = material->geometry_owners.find(p_geometry);
|
||||
ERR_FAIL_COND(!I);
|
||||
|
||||
I->get()--;
|
||||
if (I->get()==0) {
|
||||
material->instantiable_owners.erase(I);
|
||||
material->geometry_owners.erase(I);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2446,18 +2446,15 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
|
||||
bool has_morph = p_blend_shapes.size();
|
||||
|
||||
Surface::Attrib attribs[VS::ARRAY_MAX],morph_attribs[VS::ARRAY_MAX];
|
||||
Surface::Attrib attribs[VS::ARRAY_MAX];
|
||||
|
||||
int stride=0;
|
||||
int morph_stride=0;
|
||||
|
||||
for(int i=0;i<VS::ARRAY_MAX;i++) {
|
||||
|
||||
if (! (p_format&(1<<i) ) ) {
|
||||
attribs[i].enabled=false;
|
||||
morph_attribs[i].enabled=false;
|
||||
attribs[i].integer=false;
|
||||
morph_attribs[i].integer=false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2466,14 +2463,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].index=i;
|
||||
attribs[i].integer=false;
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].enabled=true;
|
||||
morph_attribs[i].offset=morph_stride;
|
||||
morph_attribs[i].index=i+8;
|
||||
} else {
|
||||
morph_attribs[i].enabled=false;
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
|
||||
case VS::ARRAY_VERTEX: {
|
||||
@ -2494,13 +2483,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
|
||||
if (has_morph) {
|
||||
//morph
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=attribs[i].size*4;
|
||||
}
|
||||
} break;
|
||||
case VS::ARRAY_NORMAL: {
|
||||
|
||||
@ -2516,13 +2498,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
}
|
||||
|
||||
if (has_morph) {
|
||||
//morph
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=12;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TANGENT: {
|
||||
@ -2539,12 +2515,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
}
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=16;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_COLOR: {
|
||||
@ -2561,12 +2531,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
}
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=16;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV: {
|
||||
@ -2583,12 +2547,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=8;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV2: {
|
||||
@ -2604,12 +2562,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
}
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=8;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_BONES: {
|
||||
@ -2627,12 +2580,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
attribs[i].integer=true;
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_UNSIGNED_SHORT;
|
||||
morph_stride+=8;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_WEIGHTS: {
|
||||
@ -2650,12 +2598,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
attribs[i].normalized=GL_FALSE;
|
||||
}
|
||||
|
||||
if (has_morph) {
|
||||
morph_attribs[i].normalized=GL_FALSE;
|
||||
morph_attribs[i].size=attribs[i].size;
|
||||
morph_attribs[i].type=GL_FLOAT;
|
||||
morph_stride+=8;
|
||||
}
|
||||
} break;
|
||||
case VS::ARRAY_INDEX: {
|
||||
|
||||
@ -2678,9 +2620,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
|
||||
for(int i=0;i<VS::ARRAY_MAX-1;i++) {
|
||||
attribs[i].stride=stride;
|
||||
if (has_morph) {
|
||||
morph_attribs[i].stride=morph_stride;
|
||||
}
|
||||
}
|
||||
|
||||
//validate sizes
|
||||
@ -2731,7 +2670,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
|
||||
for(int i=0;i<VS::ARRAY_MAX;i++) {
|
||||
surface->attribs[i]=attribs[i];
|
||||
surface->morph_attribs[i]=morph_attribs[i];
|
||||
}
|
||||
|
||||
{
|
||||
@ -2763,12 +2701,11 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
glGenVertexArrays(1,&surface->array_id);
|
||||
glBindVertexArray(surface->array_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER,surface->vertex_id);
|
||||
} else {
|
||||
} else if (i==1) {
|
||||
//for instancing draw (can be changed and no one cares)
|
||||
glGenVertexArrays(1,&surface->instancing_array_id);
|
||||
glBindVertexArray(surface->instancing_array_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER,surface->vertex_id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2816,17 +2753,17 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
|
||||
glBindVertexArray(mt.array_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER,mt.vertex_id);
|
||||
|
||||
for(int i=0;i<VS::ARRAY_MAX-1;i++) {
|
||||
for(int j=0;j<VS::ARRAY_MAX-1;j++) {
|
||||
|
||||
if (!attribs[i].enabled)
|
||||
if (!attribs[j].enabled)
|
||||
continue;
|
||||
|
||||
if (attribs[i].integer) {
|
||||
glVertexAttribIPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||
if (attribs[j].integer) {
|
||||
glVertexAttribIPointer(attribs[j].index,attribs[j].size,attribs[j].type,attribs[j].stride,((uint8_t*)0)+attribs[j].offset);
|
||||
} else {
|
||||
glVertexAttribPointer(attribs[i].index,attribs[i].size,attribs[i].type,attribs[i].normalized,attribs[i].stride,((uint8_t*)0)+attribs[i].offset);
|
||||
glVertexAttribPointer(attribs[j].index,attribs[j].size,attribs[j].type,attribs[j].normalized,attribs[j].stride,((uint8_t*)0)+attribs[j].offset);
|
||||
}
|
||||
glEnableVertexAttribArray(attribs[i].index);
|
||||
glEnableVertexAttribArray(attribs[j].index);
|
||||
|
||||
}
|
||||
|
||||
@ -2889,13 +2826,13 @@ void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface
|
||||
return;
|
||||
|
||||
if (mesh->surfaces[p_surface]->material.is_valid()) {
|
||||
_material_remove_instantiable(mesh->surfaces[p_surface]->material,mesh);
|
||||
_material_remove_geometry(mesh->surfaces[p_surface]->material,mesh->surfaces[p_surface]);
|
||||
}
|
||||
|
||||
mesh->surfaces[p_surface]->material=p_material;
|
||||
|
||||
if (mesh->surfaces[p_surface]->material.is_valid()) {
|
||||
_material_add_instantiable(mesh->surfaces[p_surface]->material,mesh);
|
||||
_material_add_geometry(mesh->surfaces[p_surface]->material,mesh->surfaces[p_surface]);
|
||||
}
|
||||
|
||||
mesh->instance_material_change_notify();
|
||||
@ -3067,7 +3004,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface){
|
||||
Surface *surface = mesh->surfaces[p_surface];
|
||||
|
||||
if (surface->material.is_valid()) {
|
||||
_material_remove_instantiable(surface->material,mesh);
|
||||
_material_remove_geometry(surface->material,mesh->surfaces[p_surface]);
|
||||
}
|
||||
|
||||
glDeleteBuffers(1,&surface->vertex_id);
|
||||
@ -3241,6 +3178,227 @@ void RasterizerStorageGLES3::mesh_clear(RID p_mesh){
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::mesh_render_blend_shapes(Surface *s, float *p_weights) {
|
||||
|
||||
glBindVertexArray(s->array_id);
|
||||
|
||||
BlendShapeShaderGLES3::Conditionals cond[VS::ARRAY_MAX-1]={
|
||||
BlendShapeShaderGLES3::ENABLE_NORMAL, //will be ignored
|
||||
BlendShapeShaderGLES3::ENABLE_NORMAL,
|
||||
BlendShapeShaderGLES3::ENABLE_TANGENT,
|
||||
BlendShapeShaderGLES3::ENABLE_COLOR,
|
||||
BlendShapeShaderGLES3::ENABLE_UV,
|
||||
BlendShapeShaderGLES3::ENABLE_UV2,
|
||||
BlendShapeShaderGLES3::ENABLE_SKELETON,
|
||||
BlendShapeShaderGLES3::ENABLE_SKELETON,
|
||||
};
|
||||
|
||||
int stride=0;
|
||||
|
||||
if (s->format&VS::ARRAY_FLAG_USE_2D_VERTICES) {
|
||||
stride=2*4;
|
||||
} else {
|
||||
stride=3*4;
|
||||
}
|
||||
|
||||
static const int sizes[VS::ARRAY_MAX-1]={
|
||||
3*4,
|
||||
3*4,
|
||||
4*4,
|
||||
4*4,
|
||||
2*4,
|
||||
2*4,
|
||||
4*4,
|
||||
4*4
|
||||
};
|
||||
|
||||
for(int i=1;i<VS::ARRAY_MAX-1;i++) {
|
||||
shaders.blend_shapes.set_conditional(cond[i],s->format&(1<<i)); //enable conditional for format
|
||||
if (s->format&(1<<i)) {
|
||||
stride+=sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//copy all first
|
||||
float base_weight=1.0;
|
||||
|
||||
int mtc = s->morph_targets.size();
|
||||
|
||||
if (s->mesh->morph_target_mode==VS::MORPH_MODE_NORMALIZED) {
|
||||
|
||||
for(int i=0;i<mtc;i++) {
|
||||
base_weight-=p_weights[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::ENABLE_BLEND,false); //first pass does not blend
|
||||
shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::USE_2D_VERTEX,s->format&VS::ARRAY_FLAG_USE_2D_VERTICES); //use 2D vertices if needed
|
||||
|
||||
shaders.blend_shapes.bind();
|
||||
|
||||
shaders.blend_shapes.set_uniform(BlendShapeShaderGLES3::BLEND_AMOUNT,base_weight);
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, resources.transform_feedback_buffers[0]);
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS,0,s->array_len);
|
||||
glEndTransformFeedback();
|
||||
|
||||
|
||||
shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::ENABLE_BLEND,true); //first pass does not blend
|
||||
shaders.blend_shapes.bind();
|
||||
|
||||
for(int ti=0;ti<mtc;ti++) {
|
||||
float weight = p_weights[ti];
|
||||
|
||||
if (weight<0.001) //not bother with this one
|
||||
continue;
|
||||
|
||||
glBindVertexArray(s->morph_targets[ti].array_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, resources.transform_feedback_buffers[0]);
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, resources.transform_feedback_buffers[1]);
|
||||
|
||||
shaders.blend_shapes.set_uniform(BlendShapeShaderGLES3::BLEND_AMOUNT,weight);
|
||||
|
||||
int ofs=0;
|
||||
for(int i=0;i<VS::ARRAY_MAX-1;i++) {
|
||||
|
||||
if (s->format&(1<<i)) {
|
||||
glEnableVertexAttribArray(i+8);
|
||||
switch(i) {
|
||||
|
||||
case VS::ARRAY_VERTEX: {
|
||||
if (s->format&VS::ARRAY_FLAG_USE_2D_VERTICES) {
|
||||
glVertexAttribPointer(i+8,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
} else {
|
||||
glVertexAttribPointer(i+8,3,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=3*4;
|
||||
}
|
||||
} break;
|
||||
case VS::ARRAY_NORMAL: {
|
||||
glVertexAttribPointer(i+8,3,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=3*4;
|
||||
} break;
|
||||
case VS::ARRAY_TANGENT: {
|
||||
glVertexAttribPointer(i+8,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_COLOR: {
|
||||
glVertexAttribPointer(i+8,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV: {
|
||||
glVertexAttribPointer(i+8,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV2: {
|
||||
glVertexAttribPointer(i+8,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_BONES: {
|
||||
glVertexAttribIPointer(i+8,4,GL_UNSIGNED_INT,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_WEIGHTS: {
|
||||
glVertexAttribPointer(i+8,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
} else {
|
||||
glDisableVertexAttribArray(i+8);
|
||||
}
|
||||
}
|
||||
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS,0,s->array_len);
|
||||
glEndTransformFeedback();
|
||||
|
||||
|
||||
SWAP(resources.transform_feedback_buffers[0],resources.transform_feedback_buffers[1]);
|
||||
|
||||
}
|
||||
|
||||
glDisable(GL_RASTERIZER_DISCARD);
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
|
||||
|
||||
|
||||
glBindVertexArray(resources.transform_feedback_array);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, resources.transform_feedback_buffers[0]);
|
||||
|
||||
int ofs=0;
|
||||
for(int i=0;i<VS::ARRAY_MAX-1;i++) {
|
||||
|
||||
if (s->format&(1<<i)) {
|
||||
glEnableVertexAttribArray(i);
|
||||
switch(i) {
|
||||
|
||||
case VS::ARRAY_VERTEX: {
|
||||
if (s->format&VS::ARRAY_FLAG_USE_2D_VERTICES) {
|
||||
glVertexAttribPointer(i,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
} else {
|
||||
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=3*4;
|
||||
}
|
||||
} break;
|
||||
case VS::ARRAY_NORMAL: {
|
||||
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=3*4;
|
||||
} break;
|
||||
case VS::ARRAY_TANGENT: {
|
||||
glVertexAttribPointer(i,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_COLOR: {
|
||||
glVertexAttribPointer(i,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV: {
|
||||
glVertexAttribPointer(i,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_TEX_UV2: {
|
||||
glVertexAttribPointer(i,2,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=2*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_BONES: {
|
||||
glVertexAttribIPointer(i,4,GL_UNSIGNED_INT,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
case VS::ARRAY_WEIGHTS: {
|
||||
glVertexAttribPointer(i,4,GL_FLOAT,GL_FALSE,stride,((uint8_t*)0)+ofs);
|
||||
ofs+=4*4;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
} else {
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->index_array_len) {
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,s->index_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* MULTIMESH API */
|
||||
|
||||
|
||||
@ -3896,7 +4054,6 @@ void RasterizerStorageGLES3::skeleton_allocate(RID p_skeleton,int p_bones,bool p
|
||||
skeleton_update_list.add(&skeleton->update_list);
|
||||
}
|
||||
|
||||
skeleton->instance_change_notify();
|
||||
|
||||
|
||||
}
|
||||
@ -4017,7 +4174,10 @@ void RasterizerStorageGLES3::update_dirty_skeletons() {
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,0,skeleton->bones.size()*sizeof(float),skeleton->bones.ptr());
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
skeleton->instance_change_notify();
|
||||
|
||||
for (Set<RasterizerScene::InstanceBase*>::Element *E=skeleton->instances.front();E;E=E->next()) {
|
||||
E->get()->base_changed();
|
||||
}
|
||||
|
||||
skeleton_update_list.remove(skeleton_update_list.first());
|
||||
}
|
||||
@ -4505,6 +4665,23 @@ void RasterizerStorageGLES3::portal_set_disabled_color(RID p_portal, const Color
|
||||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance) {
|
||||
|
||||
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||
ERR_FAIL_COND(!skeleton);
|
||||
|
||||
skeleton->instances.insert(p_instance);
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::instance_remove_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance) {
|
||||
|
||||
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||
ERR_FAIL_COND(!skeleton);
|
||||
|
||||
skeleton->instances.erase(p_instance);
|
||||
}
|
||||
|
||||
|
||||
void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance) {
|
||||
|
||||
Instantiable *inst=NULL;
|
||||
@ -4530,9 +4707,6 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene:
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
default: {
|
||||
if (skeleton_owner.owns(p_base)) {
|
||||
inst=skeleton_owner.getornull(p_base);
|
||||
}
|
||||
if (!inst) {
|
||||
ERR_FAIL();
|
||||
}
|
||||
@ -4550,7 +4724,6 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
|
||||
case VS::INSTANCE_MESH: {
|
||||
inst = mesh_owner.getornull(p_base);
|
||||
ERR_FAIL_COND(!inst);
|
||||
|
||||
} break;
|
||||
case VS::INSTANCE_MULTIMESH: {
|
||||
inst = multimesh_owner.getornull(p_base);
|
||||
@ -4569,9 +4742,7 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
|
||||
ERR_FAIL_COND(!inst);
|
||||
} break;
|
||||
default: {
|
||||
if (skeleton_owner.owns(p_base)) {
|
||||
inst=skeleton_owner.getornull(p_base);
|
||||
}
|
||||
|
||||
if (!inst) {
|
||||
ERR_FAIL();
|
||||
}
|
||||
@ -5134,6 +5305,26 @@ bool RasterizerStorageGLES3::free(RID p_rid){
|
||||
glDeleteBuffers(1,&material->ubo_id);
|
||||
}
|
||||
|
||||
//remove from owners
|
||||
for (Map<Geometry*,int>::Element *E=material->geometry_owners.front();E;E=E->next()) {
|
||||
|
||||
Geometry *g = E->key();
|
||||
g->material=RID();
|
||||
}
|
||||
for (Map<RasterizerScene::InstanceBase*,int>::Element *E=material->instance_owners.front();E;E=E->next()) {
|
||||
RasterizerScene::InstanceBase*ins=E->key();
|
||||
if (ins->material_override==p_rid) {
|
||||
ins->material_override=RID();
|
||||
}
|
||||
|
||||
for(int i=0;i<ins->materials.size();i++) {
|
||||
if (ins->materials[i]==p_rid) {
|
||||
ins->materials[i]=RID();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
material_owner.free(p_rid);
|
||||
memdelete(material);
|
||||
|
||||
@ -5144,6 +5335,11 @@ bool RasterizerStorageGLES3::free(RID p_rid){
|
||||
if (skeleton->update_list.in_list()) {
|
||||
skeleton_update_list.remove(&skeleton->update_list);
|
||||
}
|
||||
|
||||
for (Set<RasterizerScene::InstanceBase*>::Element *E=skeleton->instances.front();E;E=E->next()) {
|
||||
E->get()->skeleton=RID();
|
||||
}
|
||||
|
||||
skeleton_allocate(p_rid,0,false);
|
||||
skeleton_owner.free(p_rid);
|
||||
memdelete(skeleton);
|
||||
@ -5370,6 +5566,23 @@ void RasterizerStorageGLES3::initialize() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//transform feedback buffers
|
||||
uint32_t xf_feedback_size = GLOBAL_DEF("rendering/gles3/blend_shape_max_buffer_size_kb",4096);
|
||||
for(int i=0;i<2;i++) {
|
||||
|
||||
glGenBuffers(1,&resources.transform_feedback_buffers[i]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER,resources.transform_feedback_buffers[i]);
|
||||
glBufferData(GL_ARRAY_BUFFER,xf_feedback_size*1024,NULL,GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
shaders.blend_shapes.init();;
|
||||
|
||||
glGenVertexArrays(1,&resources.transform_feedback_array);
|
||||
|
||||
}
|
||||
|
||||
shaders.cubemap_filter.init();
|
||||
|
||||
glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "shader_gles3.h"
|
||||
#include "shaders/copy.glsl.h"
|
||||
#include "shaders/canvas.glsl.h"
|
||||
#include "shaders/blend_shape.glsl.h"
|
||||
#include "shaders/cubemap_filter.glsl.h"
|
||||
#include "self_list.h"
|
||||
#include "shader_compiler_gles3.h"
|
||||
@ -65,6 +66,8 @@ public:
|
||||
|
||||
CubemapFilterShaderGLES3 cubemap_filter;
|
||||
|
||||
BlendShapeShaderGLES3 blend_shapes;
|
||||
|
||||
ShaderCompilerGLES3::IdentifierActions actions_canvas;
|
||||
ShaderCompilerGLES3::IdentifierActions actions_scene;
|
||||
} shaders;
|
||||
@ -79,6 +82,9 @@ public:
|
||||
GLuint quadie;
|
||||
GLuint quadie_array;
|
||||
|
||||
GLuint transform_feedback_buffers[2];
|
||||
GLuint transform_feedback_array;
|
||||
|
||||
} resources;
|
||||
|
||||
struct Info {
|
||||
@ -133,8 +139,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct GeometryOwner : public Instantiable {
|
||||
|
||||
virtual ~GeometryOwner() {}
|
||||
};
|
||||
struct Geometry : Instantiable {
|
||||
|
||||
enum Type {
|
||||
GEOMETRY_INVALID,
|
||||
GEOMETRY_SURFACE,
|
||||
GEOMETRY_IMMEDIATE,
|
||||
GEOMETRY_MULTISURFACE,
|
||||
};
|
||||
|
||||
|
||||
Type type;
|
||||
RID material;
|
||||
uint64_t last_pass;
|
||||
uint32_t index;
|
||||
|
||||
virtual void material_changed_notify() {}
|
||||
|
||||
Geometry() {
|
||||
last_pass=0;
|
||||
index=0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -384,7 +415,7 @@ public:
|
||||
uint32_t index;
|
||||
uint64_t last_pass;
|
||||
|
||||
Map<Instantiable*,int> instantiable_owners;
|
||||
Map<Geometry*,int> geometry_owners;
|
||||
Map<RasterizerScene::InstanceBase*,int> instance_owners;
|
||||
|
||||
bool can_cast_shadow_cache;
|
||||
@ -404,8 +435,8 @@ public:
|
||||
|
||||
mutable SelfList<Material>::List _material_dirty_list;
|
||||
void _material_make_dirty(Material *p_material) const;
|
||||
void _material_add_instantiable(RID p_material,Instantiable *p_instantiable);
|
||||
void _material_remove_instantiable(RID p_material, Instantiable *p_instantiable);
|
||||
void _material_add_geometry(RID p_material,Geometry *p_instantiable);
|
||||
void _material_remove_geometry(RID p_material, Geometry *p_instantiable);
|
||||
|
||||
|
||||
mutable RID_Owner<Material> material_owner;
|
||||
@ -433,31 +464,9 @@ public:
|
||||
/* MESH API */
|
||||
|
||||
|
||||
struct Geometry : Instantiable {
|
||||
|
||||
enum Type {
|
||||
GEOMETRY_INVALID,
|
||||
GEOMETRY_SURFACE,
|
||||
GEOMETRY_IMMEDIATE,
|
||||
GEOMETRY_MULTISURFACE,
|
||||
};
|
||||
|
||||
Type type;
|
||||
RID material;
|
||||
uint64_t last_pass;
|
||||
uint32_t index;
|
||||
|
||||
Geometry() {
|
||||
last_pass=0;
|
||||
index=0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct GeometryOwner : public Instantiable {
|
||||
|
||||
virtual ~GeometryOwner() {}
|
||||
};
|
||||
|
||||
struct Mesh;
|
||||
struct Surface : public Geometry {
|
||||
@ -475,7 +484,7 @@ public:
|
||||
};
|
||||
|
||||
Attrib attribs[VS::ARRAY_MAX];
|
||||
Attrib morph_attribs[VS::ARRAY_MAX];
|
||||
|
||||
|
||||
|
||||
Mesh *mesh;
|
||||
@ -512,6 +521,10 @@ public:
|
||||
|
||||
bool active;
|
||||
|
||||
virtual void material_changed_notify() {
|
||||
mesh->instance_material_change_notify();
|
||||
}
|
||||
|
||||
Surface() {
|
||||
|
||||
array_byte_size=0;
|
||||
@ -590,6 +603,8 @@ public:
|
||||
virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const;
|
||||
virtual void mesh_clear(RID p_mesh);
|
||||
|
||||
void mesh_render_blend_shapes(Surface *s, float *p_weights);
|
||||
|
||||
/* MULTIMESH API */
|
||||
|
||||
struct MultiMesh : public GeometryOwner {
|
||||
@ -699,12 +714,13 @@ public:
|
||||
|
||||
/* SKELETON API */
|
||||
|
||||
struct Skeleton : Instantiable {
|
||||
struct Skeleton : RID_Data {
|
||||
int size;
|
||||
bool use_2d;
|
||||
Vector<float> bones; //4x3 or 4x2 depending on what is needed
|
||||
GLuint ubo;
|
||||
SelfList<Skeleton> update_list;
|
||||
Set<RasterizerScene::InstanceBase*> instances; //instances using skeleton
|
||||
|
||||
Skeleton() : update_list(this) {
|
||||
size=0;
|
||||
@ -843,6 +859,8 @@ public:
|
||||
virtual void portal_set_disable_distance(RID p_portal, float p_distance);
|
||||
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color);
|
||||
|
||||
virtual void instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance);
|
||||
virtual void instance_remove_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance);
|
||||
|
||||
virtual void instance_add_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance);
|
||||
virtual void instance_remove_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance);
|
||||
|
@ -502,6 +502,25 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
|
||||
glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name );
|
||||
}
|
||||
|
||||
//if feedback exists, set it up
|
||||
|
||||
if (feedback_count) {
|
||||
Vector<const char*> feedback;
|
||||
for(int i=0;i<feedback_count;i++) {
|
||||
|
||||
if (feedbacks[i].conditional==-1 || (1<<feedbacks[i].conditional)&conditional_version.version) {
|
||||
//conditional for this feedback is enabled
|
||||
print_line("tf varying: "+itos(feedback.size())+" "+String(feedbacks[i].name));
|
||||
feedback.push_back(feedbacks[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
if (feedback.size()) {
|
||||
glTransformFeedbackVaryings(v.id,feedback.size(),feedback.ptr(),GL_INTERLEAVED_ATTRIBS );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glLinkProgram(v.id);
|
||||
|
||||
glGetProgramiv(v.id, GL_LINK_STATUS, &status);
|
||||
@ -604,7 +623,7 @@ GLint ShaderGLES3::get_uniform_location(const String& p_name) const {
|
||||
}
|
||||
|
||||
|
||||
void ShaderGLES3::setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start) {
|
||||
void ShaderGLES3::setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count, const Feedback* p_feedback, int p_feedback_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start) {
|
||||
|
||||
ERR_FAIL_COND(version);
|
||||
conditional_version.key=0;
|
||||
@ -623,6 +642,8 @@ void ShaderGLES3::setup(const char** p_conditional_defines, int p_conditional_co
|
||||
attribute_pair_count=p_attribute_count;
|
||||
ubo_pairs=p_ubo_pairs;
|
||||
ubo_count=p_ubo_pair_count;
|
||||
feedbacks=p_feedback;
|
||||
feedback_count=p_feedback_count;
|
||||
|
||||
//split vertex and shader code (thank you, retarded shader compiler programmers from you know what company).
|
||||
{
|
||||
|
@ -87,6 +87,12 @@ protected:
|
||||
int index;
|
||||
};
|
||||
|
||||
struct Feedback {
|
||||
|
||||
const char *name;
|
||||
int conditional;
|
||||
};
|
||||
|
||||
bool uniforms_dirty;
|
||||
private:
|
||||
|
||||
@ -95,6 +101,7 @@ private:
|
||||
int texunit_pair_count;
|
||||
int conditional_count;
|
||||
int ubo_count;
|
||||
int feedback_count;
|
||||
int vertex_code_start;
|
||||
int fragment_code_start;
|
||||
int attribute_pair_count;
|
||||
@ -162,6 +169,7 @@ private:
|
||||
const AttributePair *attribute_pairs;
|
||||
const TexUnitPair *texunit_pairs;
|
||||
const UBOPair *ubo_pairs;
|
||||
const Feedback *feedbacks;
|
||||
const char* vertex_code;
|
||||
const char* fragment_code;
|
||||
CharString fragment_code0;
|
||||
@ -293,7 +301,7 @@ protected:
|
||||
_FORCE_INLINE_ int _get_uniform(int p_which) const;
|
||||
_FORCE_INLINE_ void _set_conditional(int p_which, bool p_value);
|
||||
|
||||
void setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start);
|
||||
void setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs,int p_ubo_pair_count, const Feedback* p_feedback, int p_feedback_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start);
|
||||
|
||||
ShaderGLES3();
|
||||
public:
|
||||
|
@ -7,4 +7,5 @@ if env['BUILDERS'].has_key('GLES3_GLSL'):
|
||||
env.GLES3_GLSL('scene.glsl');
|
||||
env.GLES3_GLSL('cubemap_filter.glsl');
|
||||
env.GLES3_GLSL('cube_to_dp.glsl');
|
||||
env.GLES3_GLSL('blend_shape.glsl');
|
||||
|
||||
|
197
drivers/gles3/shaders/blend_shape.glsl
Normal file
197
drivers/gles3/shaders/blend_shape.glsl
Normal file
@ -0,0 +1,197 @@
|
||||
[vertex]
|
||||
|
||||
|
||||
/*
|
||||
from VisualServer:
|
||||
|
||||
ARRAY_VERTEX=0,
|
||||
ARRAY_NORMAL=1,
|
||||
ARRAY_TANGENT=2,
|
||||
ARRAY_COLOR=3,
|
||||
ARRAY_TEX_UV=4,
|
||||
ARRAY_TEX_UV2=5,
|
||||
ARRAY_BONES=6,
|
||||
ARRAY_WEIGHTS=7,
|
||||
ARRAY_INDEX=8,
|
||||
*/
|
||||
|
||||
#ifdef USE_2D_VERTEX
|
||||
#define VFORMAT vec2
|
||||
#else
|
||||
#define VFORMAT vec3
|
||||
#endif
|
||||
|
||||
/* INPUT ATTRIBS */
|
||||
|
||||
layout(location=0) in highp VFORMAT vertex_attrib;
|
||||
layout(location=1) in vec3 normal_attrib;
|
||||
|
||||
#ifdef ENABLE_TANGENT
|
||||
layout(location=2) in vec4 tangent_attrib;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
layout(location=3) in vec4 color_attrib;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV
|
||||
layout(location=4) in vec2 uv_attrib;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2
|
||||
layout(location=5) in vec2 uv2_attrib;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SKELETON
|
||||
layout(location=6) in ivec4 bone_attrib;
|
||||
layout(location=7) in vec4 weight_attrib;
|
||||
#endif
|
||||
|
||||
/* BLEND ATTRIBS */
|
||||
|
||||
#ifdef ENABLE_BLEND
|
||||
|
||||
layout(location=8) in highp VFORMAT vertex_attrib_blend;
|
||||
layout(location=9) in vec3 normal_attrib_blend;
|
||||
|
||||
#ifdef ENABLE_TANGENT
|
||||
layout(location=10) in vec4 tangent_attrib_blend;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
layout(location=11) in vec4 color_attrib_blend;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV
|
||||
layout(location=12) in vec2 uv_attrib_blend;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2
|
||||
layout(location=13) in vec2 uv2_attrib_blend;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SKELETON
|
||||
layout(location=14) in ivec4 bone_attrib_blend;
|
||||
layout(location=15) in vec4 weight_attrib_blend;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* OUTPUTS */
|
||||
|
||||
out VFORMAT vertex_out; //tfb:
|
||||
|
||||
#ifdef ENABLE_NORMAL
|
||||
out vec3 normal_out; //tfb:ENABLE_NORMAL
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TANGENT
|
||||
out vec4 tangent_out; //tfb:ENABLE_TANGENT
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
out vec4 color_out; //tfb:ENABLE_COLOR
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV
|
||||
out vec2 uv_out; //tfb:ENABLE_UV
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2
|
||||
out vec2 uv2_out; //tfb:ENABLE_UV2
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SKELETON
|
||||
out ivec4 bone_out; //tfb:ENABLE_SKELETON
|
||||
out vec4 weight_out; //tfb:ENABLE_SKELETON
|
||||
#endif
|
||||
|
||||
uniform float blend_amount;
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
#ifdef ENABLE_BLEND
|
||||
|
||||
vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
|
||||
|
||||
#ifdef ENABLE_NORMAL
|
||||
normal_out = normal_attrib_blend + normal_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TANGENT
|
||||
|
||||
tangent_out.xyz = tangent_attrib_blend.xyz + tangent_attrib.xyz * blend_amount;
|
||||
tangent_out.w = tangent_attrib_blend.w; //just copy, no point in blending his
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
color_out = color_attrib_blend + color_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV
|
||||
|
||||
uv_out = uv_attrib_blend + uv_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2
|
||||
|
||||
uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_SKELETON
|
||||
|
||||
bone_out = bone_attrib_blend;
|
||||
weight_out = weight_attrib_blend + weight_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#else //ENABLE_BLEND
|
||||
|
||||
|
||||
vertex_out = vertex_attrib * blend_amount;
|
||||
|
||||
#ifdef ENABLE_NORMAL
|
||||
normal_out = normal_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TANGENT
|
||||
|
||||
tangent_out.xyz = tangent_attrib.xyz * blend_amount;
|
||||
tangent_out.w = tangent_attrib.w; //just copy, no point in blending his
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
color_out = color_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV
|
||||
|
||||
uv_out = uv_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_UV2
|
||||
|
||||
uv2_out = uv2_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_SKELETON
|
||||
|
||||
bone_out = bone_attrib;
|
||||
weight_out = weight_attrib * blend_amount;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
|
||||
[fragment]
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
}
|
||||
|
39
methods.py
39
methods.py
@ -671,6 +671,7 @@ class LegacyGLHeaderStruct:
|
||||
self.fragment_lines=[]
|
||||
self.uniforms=[]
|
||||
self.attributes=[]
|
||||
self.feedbacks=[]
|
||||
self.fbos=[]
|
||||
self.conditionals=[]
|
||||
self.enums={}
|
||||
@ -823,6 +824,20 @@ def include_file_in_legacygl_header( filename, header_data, depth ):
|
||||
bind=bind.replace("attrib:","").strip()
|
||||
header_data.attributes+=[(name,bind)]
|
||||
|
||||
if ( line.strip().find("out ")==0 and line.find("tfb:")!=-1):
|
||||
uline = line.replace("out ","");
|
||||
uline = uline.replace("highp ","");
|
||||
uline = uline.replace(";","");
|
||||
uline = uline[ uline.find(" "): ].strip()
|
||||
|
||||
|
||||
if (uline.find("//")!=-1):
|
||||
name,bind = uline.split("//")
|
||||
if (bind.find("tfb:")!=-1):
|
||||
name=name.strip()
|
||||
bind=bind.replace("tfb:","").strip()
|
||||
header_data.feedbacks+=[(name,bind)]
|
||||
|
||||
|
||||
line=line.replace("\r","")
|
||||
line=line.replace("\n","")
|
||||
@ -1039,12 +1054,14 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
|
||||
fd.write("\t\tstatic const Enum *_enums=NULL;\n")
|
||||
fd.write("\t\tstatic const EnumValue *_enum_values=NULL;\n")
|
||||
|
||||
conditionals_found = []
|
||||
if (len(header_data.conditionals)):
|
||||
|
||||
fd.write("\t\tstatic const char* _conditional_strings[]={\n")
|
||||
if (len(header_data.conditionals)):
|
||||
for x in header_data.conditionals:
|
||||
fd.write("\t\t\t\"#define "+x+"\\n\",\n");
|
||||
conditionals_found.append(x)
|
||||
fd.write("\t\t};\n\n");
|
||||
else:
|
||||
fd.write("\t\tstatic const char **_conditional_strings=NULL;\n")
|
||||
@ -1070,6 +1087,24 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
|
||||
else:
|
||||
fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n")
|
||||
|
||||
feedback_count=0
|
||||
|
||||
if (len(header_data.feedbacks)):
|
||||
|
||||
fd.write("\t\tstatic const Feedback _feedbacks[]={\n")
|
||||
for x in header_data.feedbacks:
|
||||
name = x[0]
|
||||
cond = x[1]
|
||||
if (cond in conditionals_found):
|
||||
fd.write("\t\t\t{\""+name+"\","+str(conditionals_found.index(cond))+"},\n");
|
||||
else:
|
||||
fd.write("\t\t\t{\""+name+"\",-1},\n");
|
||||
|
||||
feedback_count+=1
|
||||
|
||||
fd.write("\t\t};\n\n");
|
||||
else:
|
||||
fd.write("\t\tstatic const Feedback* _feedbacks=NULL;\n")
|
||||
|
||||
if (len(header_data.texunits)):
|
||||
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
|
||||
@ -1109,9 +1144,9 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
|
||||
fd.write("\t\tstatic const int _fragment_code_start="+str(header_data.fragment_offset)+";\n")
|
||||
|
||||
if output_attribs:
|
||||
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_attribute_pairs,"+str(len(header_data.attributes))+", _texunit_pairs,"+str(len(header_data.texunits))+",_ubo_pairs,"+str(len(header_data.ubos))+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
|
||||
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_attribute_pairs,"+str(len(header_data.attributes))+", _texunit_pairs,"+str(len(header_data.texunits))+",_ubo_pairs,"+str(len(header_data.ubos))+",_feedbacks,"+str(feedback_count)+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
|
||||
else:
|
||||
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_texunit_pairs,"+str(len(header_data.texunits))+",_enums,"+str(len(header_data.enums))+",_enum_values,"+str(enum_value_count)+",_ubo_pairs,"+str(len(header_data.ubos))+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
|
||||
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_texunit_pairs,"+str(len(header_data.texunits))+",_enums,"+str(len(header_data.enums))+",_enum_values,"+str(enum_value_count)+",_ubo_pairs,"+str(len(header_data.ubos))+",_feedbacks,"+str(feedback_count)+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
|
||||
|
||||
fd.write("\t};\n\n")
|
||||
|
||||
|
@ -316,14 +316,14 @@ void Mesh::add_surface(uint32_t p_format,PrimitiveType p_primitive,const DVector
|
||||
|
||||
}
|
||||
|
||||
void Mesh::add_surface_from_arrays(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes) {
|
||||
void Mesh::add_surface_from_arrays(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,uint32_t p_flags) {
|
||||
|
||||
|
||||
ERR_FAIL_COND(p_arrays.size()!=ARRAY_MAX);
|
||||
|
||||
Surface s;
|
||||
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh,(VisualServer::PrimitiveType)p_primitive, p_arrays,p_blend_shapes);
|
||||
VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh,(VisualServer::PrimitiveType)p_primitive, p_arrays,p_blend_shapes,p_flags);
|
||||
surfaces.push_back(s);
|
||||
|
||||
|
||||
@ -1024,7 +1024,7 @@ void Mesh::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_morph_target_mode","mode"),&Mesh::set_morph_target_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_morph_target_mode"),&Mesh::get_morph_target_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_surface_from_arrays","primitive","arrays","blend_shapes"),&Mesh::add_surface_from_arrays,DEFVAL(Array()));
|
||||
ObjectTypeDB::bind_method(_MD("add_surface_from_arrays","primitive","arrays","blend_shapes","compress_flags"),&Mesh::add_surface_from_arrays,DEFVAL(Array()),DEFVAL(ARRAY_COMPRESS_DEFAULT));
|
||||
ObjectTypeDB::bind_method(_MD("get_surface_count"),&Mesh::get_surface_count);
|
||||
ObjectTypeDB::bind_method(_MD("surface_remove","surf_idx"),&Mesh::surface_remove);
|
||||
ObjectTypeDB::bind_method(_MD("surface_get_array_len","surf_idx"),&Mesh::surface_get_array_len);
|
||||
|
@ -77,6 +77,22 @@ public:
|
||||
ARRAY_FORMAT_WEIGHTS=1<<ARRAY_WEIGHTS,
|
||||
ARRAY_FORMAT_INDEX=1<<ARRAY_INDEX,
|
||||
|
||||
ARRAY_COMPRESS_BASE=(ARRAY_INDEX+1),
|
||||
ARRAY_COMPRESS_VERTEX=1<<(ARRAY_VERTEX+ARRAY_COMPRESS_BASE), // mandatory
|
||||
ARRAY_COMPRESS_NORMAL=1<<(ARRAY_NORMAL+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TANGENT=1<<(ARRAY_TANGENT+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_COLOR=1<<(ARRAY_COLOR+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV=1<<(ARRAY_TEX_UV+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV2=1<<(ARRAY_TEX_UV2+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_BONES=1<<(ARRAY_BONES+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_WEIGHTS=1<<(ARRAY_WEIGHTS+ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_INDEX=1<<(ARRAY_INDEX+ARRAY_COMPRESS_BASE),
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES=ARRAY_COMPRESS_INDEX<<1,
|
||||
ARRAY_FLAG_USE_16_BIT_BONES=ARRAY_COMPRESS_INDEX<<2,
|
||||
|
||||
ARRAY_COMPRESS_DEFAULT=ARRAY_COMPRESS_VERTEX|ARRAY_COMPRESS_NORMAL|ARRAY_COMPRESS_TANGENT|ARRAY_COMPRESS_COLOR|ARRAY_COMPRESS_TEX_UV|ARRAY_COMPRESS_TEX_UV2|ARRAY_COMPRESS_WEIGHTS
|
||||
|
||||
};
|
||||
|
||||
enum PrimitiveType {
|
||||
@ -122,7 +138,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
void add_surface_from_arrays(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array());
|
||||
void add_surface_from_arrays(PrimitiveType p_primitive, const Array& p_arrays, const Array& p_blend_shapes=Array(), uint32_t p_flags=ARRAY_COMPRESS_DEFAULT);
|
||||
void add_surface(uint32_t p_format,PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const AABB& p_aabb,const Vector<DVector<uint8_t> >& p_blend_shapes=Vector<DVector<uint8_t> >(),const Vector<AABB>& p_bone_aabbs=Vector<AABB>());
|
||||
|
||||
Array surface_get_arrays(int p_surface) const;
|
||||
|
@ -355,7 +355,30 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
|
||||
w=DVector<Color>::Write();
|
||||
a[i]=array;
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_BONES:
|
||||
case Mesh::ARRAY_FORMAT_BONES: {
|
||||
|
||||
|
||||
DVector<int> array;
|
||||
array.resize(varr_len*4);
|
||||
DVector<int>::Write w = array.write();
|
||||
|
||||
int idx=0;
|
||||
for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next(),idx+=4) {
|
||||
|
||||
const Vertex &v=E->get();
|
||||
|
||||
ERR_CONTINUE( v.bones.size()!=4 );
|
||||
|
||||
for(int j=0;j<4;j++) {
|
||||
w[idx+j]=v.bones[j];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
w=DVector<int>::Write();
|
||||
a[i]=array;
|
||||
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_WEIGHTS: {
|
||||
|
||||
|
||||
@ -367,18 +390,11 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
|
||||
for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next(),idx+=4) {
|
||||
|
||||
const Vertex &v=E->get();
|
||||
ERR_CONTINUE( v.weights.size()!=4 );
|
||||
|
||||
for(int j=0;j<4;j++) {
|
||||
switch(i) {
|
||||
case Mesh::ARRAY_WEIGHTS: {
|
||||
ERR_CONTINUE( v.weights.size()!=4 );
|
||||
w[idx+j]=v.weights[j];
|
||||
} break;
|
||||
case Mesh::ARRAY_BONES: {
|
||||
ERR_CONTINUE( v.bones.size()!=4 );
|
||||
w[idx+j]=v.bones[j];
|
||||
} break;
|
||||
}
|
||||
|
||||
w[idx+j]=v.weights[j];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ struct ColladaImport {
|
||||
Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
|
||||
Error _create_resources(Collada::Node *p_node);
|
||||
Error _create_material(const String& p_material);
|
||||
Error _create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >());
|
||||
Error _create_mesh_surfaces(bool p_optimize, Ref<Mesh>& p_mesh, const Map<String,Collada::NodeGeometry::Material>& p_material_map, const Collada::MeshData &meshdata, const Transform& p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >(), bool p_for_morph=false);
|
||||
Error load(const String& p_path, int p_flags, bool p_force_make_tangents=false);
|
||||
void _fix_param_animation_tracks();
|
||||
void create_animation(int p_clip,bool p_make_tracks_in_all_bones);
|
||||
@ -597,7 +597,7 @@ static void _generate_tangents_and_binormals(const DVector<int>& p_indices,const
|
||||
}
|
||||
}
|
||||
|
||||
Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes) {
|
||||
Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes,bool p_for_morph) {
|
||||
|
||||
|
||||
bool local_xform_mirror=p_local_xform.basis.determinant() < 0;
|
||||
@ -1072,7 +1072,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
|
||||
DVector<Color> final_color_array;
|
||||
DVector<Vector3> final_uv_array;
|
||||
DVector<Vector3> final_uv2_array;
|
||||
DVector<float> final_bone_array;
|
||||
DVector<int> final_bone_array;
|
||||
DVector<float> final_weight_array;
|
||||
|
||||
uint32_t final_format=0;
|
||||
@ -1223,12 +1223,12 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
|
||||
|
||||
if (has_weights) {
|
||||
DVector<float> weightarray;
|
||||
DVector<float> bonearray;
|
||||
DVector<int> bonearray;
|
||||
|
||||
weightarray.resize(vertex_array.size()*4);
|
||||
DVector<float>::Write weightarrayw = weightarray.write();
|
||||
bonearray.resize(vertex_array.size()*4);
|
||||
DVector<float>::Write bonearrayw = bonearray.write();
|
||||
DVector<int>::Write bonearrayw = bonearray.write();
|
||||
|
||||
for(int k=0;k<vlen;k++) {
|
||||
float sum=0;
|
||||
@ -1237,7 +1237,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
|
||||
if (l<vertex_array[k].weights.size()) {
|
||||
weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=vertex_array[k].weights[l].weight;
|
||||
sum+=weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l];
|
||||
bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=vertex_array[k].weights[l].bone_idx;
|
||||
bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=int(vertex_array[k].weights[l].bone_idx);
|
||||
//COLLADA_PRINT(itos(k)+": "+rtos(bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l])+":"+rtos(weightarray[k*VS::ARRAY_WEIGHTS_SIZE+l]));
|
||||
} else {
|
||||
|
||||
@ -1254,7 +1254,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
|
||||
}
|
||||
|
||||
weightarrayw = DVector<float>::Write();
|
||||
bonearrayw = DVector<float>::Write();
|
||||
bonearrayw = DVector<int>::Write();
|
||||
|
||||
final_weight_array = weightarray;
|
||||
final_bone_array = bonearray;
|
||||
@ -1461,14 +1461,20 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
|
||||
|
||||
// print_line("want surface "+itos(mi)+" has "+itos(p_morph_meshes[mi]->get_surface_count()));
|
||||
Array a = p_morph_meshes[mi]->surface_get_arrays(surface);
|
||||
a[Mesh::ARRAY_BONES]=Variant();
|
||||
a[Mesh::ARRAY_WEIGHTS]=Variant();
|
||||
//add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not)
|
||||
|
||||
if (final_weight_array.size())
|
||||
a[Mesh::ARRAY_WEIGHTS]=final_weight_array;
|
||||
if (final_bone_array.size())
|
||||
a[Mesh::ARRAY_BONES]=final_bone_array;
|
||||
|
||||
a[Mesh::ARRAY_INDEX]=Variant();
|
||||
//a.resize(Mesh::ARRAY_MAX); //no need for index
|
||||
mr.push_back(a);
|
||||
}
|
||||
|
||||
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,d,mr);
|
||||
|
||||
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,d,mr,p_for_morph?0:Mesh::ARRAY_COMPRESS_DEFAULT);
|
||||
|
||||
if (material.is_valid()) {
|
||||
p_mesh->surface_set_material(surface, material);
|
||||
@ -1692,7 +1698,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
|
||||
if (collada.state.mesh_data_map.has(meshid)) {
|
||||
Ref<Mesh> mesh=Ref<Mesh>(memnew( Mesh ));
|
||||
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
|
||||
Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL);
|
||||
Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL,Vector<Ref<Mesh> >(),true);
|
||||
ERR_FAIL_COND_V(err,err);
|
||||
|
||||
morphs.push_back(mesh);
|
||||
|
@ -1840,6 +1840,8 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
void ScriptEditor::_help_class_open(const String& p_class) {
|
||||
|
||||
if (p_class=="")
|
||||
return;
|
||||
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user