merged some stuff for okam
This commit is contained in:
parent
7900d5daf2
commit
b0aa49accb
38 changed files with 470 additions and 216 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue