merged some stuff for okam

This commit is contained in:
Juan Linietsky 2015-09-03 23:24:55 -03:00
parent 7900d5daf2
commit b0aa49accb
38 changed files with 470 additions and 216 deletions

View file

@ -710,10 +710,126 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
//find largest source..
/************************/
/* ADD WEIGHTS IF EXIST */
/************************/
Map<int,Vector<Collada::Vertex::Weight> > pre_weights;
bool has_weights=false;
if (skin_controller) {
const Collada::SkinControllerData::Source *weight_src=NULL;
int weight_ofs=0;
if (skin_controller->weights.sources.has("WEIGHT")) {
String weight_id = skin_controller->weights.sources["WEIGHT"].source;
weight_ofs = skin_controller->weights.sources["WEIGHT"].offset;
if (skin_controller->sources.has(weight_id)) {
weight_src = &skin_controller->sources[weight_id];
}
}
int joint_ofs=0;
if (skin_controller->weights.sources.has("JOINT")) {
joint_ofs = skin_controller->weights.sources["JOINT"].offset;
}
//should be OK, given this was pre-checked.
int index_ofs=0;
int wstride = skin_controller->weights.sources.size();
for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) {
int amount = skin_controller->weights.sets[w_i];
Vector<Collada::Vertex::Weight> weights;
for (int a_i=0;a_i<amount;a_i++) {
Collada::Vertex::Weight w;
int read_from = index_ofs+a_i*wstride;
ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA);
int weight_index = skin_controller->weights.indices[read_from+weight_ofs];
ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA);
w.weight = weight_src->array[weight_index];
int bone_index = skin_controller->weights.indices[read_from+joint_ofs];
if (bone_index==-1)
continue; //ignore this weight (refers to bind shape)
ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA);
w.bone_idx=bone_remap[bone_index];
weights.push_back(w);
}
/* FIX WEIGHTS */
weights.sort();
if (weights.size()>4) {
//cap to 4 and make weights add up 1
weights.resize(4);
}
//make sure weights allways add up to 1
float total=0;
for(int i=0;i<weights.size();i++)
total+=weights[i].weight;
if (total)
for(int i=0;i<weights.size();i++)
weights[i].weight/=total;
if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0
//no weights assigned
Collada::Vertex::Weight w;
w.bone_idx=0;
w.weight=1.0;
weights.clear();
weights.push_back(w);
}
pre_weights[w_i]=weights;
/*
for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) {
int dst = E->get();
ERR_EXPLAIN("invalid vertex index in array");
ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA);
vertex_array[dst].weights=weights;
}*/
index_ofs+=wstride*amount;
}
//vertices need to be localized
has_weights=true;
}
Set<Collada::Vertex> vertex_set; //vertex set will be the vertices
List<int> indices_list; //indices will be the indices
Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph)
//Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph)
/**************************/
/* CREATE PRIMITIVE ARRAY */
@ -753,11 +869,16 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
if (!p_optimize)
vertex.uid=vertidx++;
int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers)
int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index;
ERR_FAIL_INDEX_V(vertex_pos,vertex_src->array.size(),ERR_INVALID_DATA);
vertex.vertex=Vector3(vertex_src->array[vertex_pos+0],vertex_src->array[vertex_pos+1],vertex_src->array[vertex_pos+2]);
if (pre_weights.has(vertex_index)) {
vertex.weights=pre_weights[vertex_index];
}
if (normal_src) {
@ -836,9 +957,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
vertex_set.insert(vertex);
}
if (!vertex_map.has(vertex_index))
/* if (!vertex_map.has(vertex_index))
vertex_map[vertex_index]=Set<int>();
vertex_map[vertex_index].insert(index); //should be outside..
vertex_map[vertex_index].insert(index); //should be outside..*/
//build triangles if needed
if (j==0)
prev2[0]=index;
@ -874,120 +995,10 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
vertex_array[F->get().idx]=F->get();
}
/************************/
/* ADD WEIGHTS IF EXIST */
/************************/
if (has_weights) {
bool has_weights=false;
if (skin_controller) {
const Collada::SkinControllerData::Source *weight_src=NULL;
int weight_ofs=0;
if (skin_controller->weights.sources.has("WEIGHT")) {
String weight_id = skin_controller->weights.sources["WEIGHT"].source;
weight_ofs = skin_controller->weights.sources["WEIGHT"].offset;
if (skin_controller->sources.has(weight_id)) {
weight_src = &skin_controller->sources[weight_id];
}
}
int joint_ofs=0;
if (skin_controller->weights.sources.has("JOINT")) {
joint_ofs = skin_controller->weights.sources["JOINT"].offset;
}
//should be OK, given this was pre-checked.
int index_ofs=0;
int wstride = skin_controller->weights.sources.size();
for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) {
int amount = skin_controller->weights.sets[w_i];
if (vertex_map.has(w_i)) { //vertex may no longer be here, don't bother converting
Vector<Collada::Vertex::Weight> weights;
for (int a_i=0;a_i<amount;a_i++) {
Collada::Vertex::Weight w;
int read_from = index_ofs+a_i*wstride;
ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA);
int weight_index = skin_controller->weights.indices[read_from+weight_ofs];
ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA);
w.weight = weight_src->array[weight_index];
int bone_index = skin_controller->weights.indices[read_from+joint_ofs];
if (bone_index==-1)
continue; //ignore this weight (refers to bind shape)
ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA);
w.bone_idx=bone_remap[bone_index];
weights.push_back(w);
}
/* FIX WEIGHTS */
weights.sort();
if (weights.size()>4) {
//cap to 4 and make weights add up 1
weights.resize(4);
}
//make sure weights allways add up to 1
float total=0;
for(int i=0;i<weights.size();i++)
total+=weights[i].weight;
if (total)
for(int i=0;i<weights.size();i++)
weights[i].weight/=total;
if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0
//no weights assigned
Collada::Vertex::Weight w;
w.bone_idx=0;
w.weight=1.0;
weights.clear();
weights.push_back(w);
}
for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) {
int dst = E->get();
ERR_EXPLAIN("invalid vertex index in array");
ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA);
vertex_array[dst].weights=weights;
}
} else {
//zzprint_line("no vertex found for index "+itos(w_i));
}
index_ofs+=wstride*amount;
}
//vertices need to be localized
//if skeleton, localize
Transform local_xform = p_local_xform;
for(int i=0;i<vertex_array.size();i++) {
@ -1000,11 +1011,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
//vertex_array[i].tangent.normal*=-1.0;
}
}
has_weights=true;
}
DVector<int> index_array;
index_array.resize(indices_list.size());
DVector<int>::Write index_arrayw = index_array.write();

View file

@ -1068,12 +1068,14 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
//prepare atlas!
Vector< Image > sources;
Vector< Image > tsources;
bool alpha=false;
bool crop = from->get_option("crop");
EditorProgress ep("make_atlas","Build Atlas For: "+p_path.get_file(),from->get_source_count()+3);
print_line("sources: "+itos(from->get_source_count()));
for(int i=0;i<from->get_source_count();i++) {
String path = EditorImportPlugin::expand_source_path(from->get_source_path(i));
@ -1091,17 +1093,57 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
if (src.detect_alpha())
alpha=true;
sources.push_back(src);
tsources.push_back(src);
}
ep.step("Converting Images",sources.size());
for(int i=0;i<sources.size();i++) {
int base_index=0;
Map<uint64_t,int> source_md5;
Map<int,List<int> > source_map;
for(int i=0;i<tsources.size();i++) {
Image src = tsources[i];
if (alpha) {
sources[i].convert(Image::FORMAT_RGBA);
src.convert(Image::FORMAT_RGBA);
} else {
sources[i].convert(Image::FORMAT_RGB);
src.convert(Image::FORMAT_RGB);
}
DVector<uint8_t> data = src.get_data();
MD5_CTX md5;
DVector<uint8_t>::Read r=data.read();
MD5Init(&md5);
int len=data.size();
for(int j=0;j<len;j++) {
uint8_t b = r[j];
b>>=2; //to aid in comparing
MD5Update(&md5,(unsigned char*)&b,1);
}
MD5Final(&md5);
uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this
tsources[i]=Image(); //clear
if (source_md5.has(*cmp)) {
int sidx=source_md5[*cmp];
source_map[sidx].push_back(i);
print_line("REUSING "+from->get_source_path(i));
} else {
int sidx=sources.size();
source_md5[*cmp]=sidx;
sources.push_back(src);
List<int> sm;
sm.push_back(i);
source_map[sidx]=sm;
}
}
//texturepacker is not really good for optimizing, so..
@ -1141,28 +1183,44 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
Image atlas;
atlas.create(nearest_power_of_2(dst_size.width),nearest_power_of_2(dst_size.height),0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB);
atlases.resize(from->get_source_count());
for(int i=0;i<sources.size();i++) {
int x=dst_positions[i].x;
int y=dst_positions[i].y;
Ref<AtlasTexture> at = memnew( AtlasTexture );
Size2 sz = Size2(sources[i].get_width(),sources[i].get_height());
Rect2 region;
Rect2 margin;
if (crop && sz!=crops[i].size) {
Rect2 rect = crops[i];
rect.size=sz-rect.size;
at->set_region(Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height));
at->set_margin(rect);
region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height);
margin=rect;
atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border));
} else {
at->set_region(Rect2(x+border,y+border,sz.x,sz.y));
region=Rect2(x+border,y+border,sz.x,sz.y);
atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border));
}
String apath = p_path.get_base_dir().plus_file(from->get_source_path(i).get_file().basename()+".atex");
print_line("Atlas Tex: "+apath);
at->set_path(apath);
atlases.push_back(at);
ERR_CONTINUE( !source_map.has(i) );
for (List<int>::Element *E=source_map[i].front();E;E=E->next()) {
Ref<AtlasTexture> at = memnew( AtlasTexture );
at->set_region(region);
at->set_margin(margin);
String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex");
at->set_path(apath);
atlases[E->get()]=at;
print_line("Atlas Tex: "+apath);
}
}
if (ResourceCache::has(p_path)) {
texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() );
@ -1414,6 +1472,9 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
} break; //use default
case EditorImportExport::IMAGE_ACTION_KEEP: {
return Vector<uint8_t>();
} break; //use default
}