Collada
-=-=-=- -Fixed some DAE import & export bugs -Changed Collada exporter to use the mesh loops API -Added tangent export to Collada exporter -Added triangulation option to Collada exporter -Changed a little how normalmaps are handled in shader. Not sure if it's working properly, be careful. -Fixed some strange bug with kinematic bodies #776 -Fix release compilaiton issues #782
This commit is contained in:
parent
13a848e332
commit
a84ba9c853
25 changed files with 363 additions and 198 deletions
|
@ -4419,7 +4419,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
|
|||
enablers.push_back("#define ENABLE_UV_INTERP\n");
|
||||
if (fragment_flags.use_uv2_interp || vertex_flags.use_uv2_interp)
|
||||
enablers.push_back("#define ENABLE_UV2_INTERP\n");
|
||||
if (fragment_flags.use_tangent_interp || vertex_flags.use_tangent_interp)
|
||||
if (fragment_flags.use_tangent_interp || vertex_flags.use_tangent_interp || fragment_flags.uses_normalmap)
|
||||
enablers.push_back("#define ENABLE_TANGENT_INTERP\n");
|
||||
if (fragment_flags.use_var1_interp || vertex_flags.use_var1_interp)
|
||||
enablers.push_back("#define ENABLE_VAR1_INTERP\n");
|
||||
|
@ -4434,6 +4434,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
|
|||
if (fragment_flags.uses_discard) {
|
||||
enablers.push_back("#define ENABLE_DISCARD\n");
|
||||
}
|
||||
if (fragment_flags.uses_normalmap) {
|
||||
enablers.push_back("#define ENABLE_NORMALMAP\n");
|
||||
}
|
||||
if (light_flags.uses_light) {
|
||||
enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
|
||||
}
|
||||
|
|
|
@ -176,6 +176,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
|
|||
if (vnode->name==vname_discard) {
|
||||
uses_discard=true;
|
||||
}
|
||||
if (vnode->name==vname_normalmap) {
|
||||
uses_normalmap=true;
|
||||
}
|
||||
if (vnode->name==vname_screen_uv) {
|
||||
uses_screen_uv=true;
|
||||
}
|
||||
|
@ -546,6 +549,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
|
|||
uses_screen_uv=false;
|
||||
uses_light=false;
|
||||
uses_time=false;
|
||||
uses_normalmap=false;
|
||||
vertex_code_writes_vertex=false;
|
||||
uniforms=r_uniforms;
|
||||
flags=&r_flags;
|
||||
|
@ -555,6 +559,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
|
|||
r_flags.use_tangent_interp=false;
|
||||
r_flags.use_var1_interp=false;
|
||||
r_flags.use_var2_interp=false;
|
||||
r_flags.uses_normalmap=false;
|
||||
|
||||
String error;
|
||||
int errline,errcol;
|
||||
|
@ -576,8 +581,10 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
|
|||
r_flags.uses_screen_uv=uses_screen_uv;
|
||||
r_flags.uses_light=uses_light;
|
||||
r_flags.uses_time=uses_time;
|
||||
r_flags.uses_normalmap=uses_normalmap;
|
||||
r_code_line=code;
|
||||
r_globals_line=global_code;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -670,6 +677,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
|
|||
mode_replace_table[1]["NORMAL"]="normal";
|
||||
mode_replace_table[1]["TANGENT"]="tangent";
|
||||
mode_replace_table[1]["BINORMAL"]="binormal";
|
||||
mode_replace_table[1]["NORMALMAP"]="normalmap";
|
||||
mode_replace_table[1]["VAR1"]="var1_interp";
|
||||
mode_replace_table[1]["VAR2"]="var2_interp";
|
||||
mode_replace_table[1]["UV"]="uv";
|
||||
|
@ -728,5 +736,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
|
|||
vname_vertex="VERTEX";
|
||||
vname_light="LIGHT";
|
||||
vname_time="TIME";
|
||||
vname_normalmap="NORMALMAP";
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
bool uses_discard;
|
||||
bool uses_time;
|
||||
bool uses_screen_uv;
|
||||
bool uses_normalmap;
|
||||
bool vertex_code_writes_vertex;
|
||||
Flags *flags;
|
||||
|
||||
|
@ -66,6 +67,7 @@ private:
|
|||
StringName vname_vertex;
|
||||
StringName vname_light;
|
||||
StringName vname_time;
|
||||
StringName vname_normalmap;
|
||||
|
||||
Map<StringName,ShaderLanguage::Uniform> *uniforms;
|
||||
|
||||
|
@ -87,6 +89,7 @@ public:
|
|||
bool uses_alpha;
|
||||
bool uses_texscreen;
|
||||
bool uses_texpos;
|
||||
bool uses_normalmap;
|
||||
bool vertex_code_writes_vertex;
|
||||
bool uses_discard;
|
||||
bool uses_screen_uv;
|
||||
|
|
|
@ -819,6 +819,10 @@ void main() {
|
|||
vec4 color = color_interp;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_NORMALMAP)
|
||||
|
||||
vec3 normalmap = vec3(0.0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -833,6 +837,11 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
}
|
||||
|
||||
#if defined(ENABLE_NORMALMAP)
|
||||
|
||||
normal = normalize( tangent_interp * normalmap.x + binormal_interp * normalmap.y + normal_interp * normalmap.z ) * side;
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_DISCARD)
|
||||
if (discard_) {
|
||||
//easy to eliminate dead code
|
||||
|
|
|
@ -925,6 +925,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
|||
normal=rest_info.normal;
|
||||
collider=rest_info.collider_id;
|
||||
collider_vel=rest_info.linear_velocity;
|
||||
collider_shape=rest_info.shape;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1013,6 +1014,12 @@ ObjectID KinematicBody2D::get_collider() const {
|
|||
return collider;
|
||||
}
|
||||
|
||||
|
||||
int KinematicBody2D::get_collider_shape() const {
|
||||
|
||||
ERR_FAIL_COND_V(!colliding,0);
|
||||
return collider_shape;
|
||||
}
|
||||
void KinematicBody2D::set_collide_with_static_bodies(bool p_enable) {
|
||||
|
||||
collide_static=p_enable;
|
||||
|
@ -1076,6 +1083,7 @@ void KinematicBody2D::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_collision_normal"),&KinematicBody2D::get_collision_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_velocity"),&KinematicBody2D::get_collider_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody2D::_get_collider);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody2D::get_collider_shape);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_collide_with_static_bodies","enable"),&KinematicBody2D::set_collide_with_static_bodies);
|
||||
|
@ -1112,6 +1120,8 @@ KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KI
|
|||
colliding=false;
|
||||
collider=0;
|
||||
|
||||
collider_shape=0;
|
||||
|
||||
margin=0.08;
|
||||
}
|
||||
KinematicBody2D::~KinematicBody2D() {
|
||||
|
|
|
@ -254,7 +254,7 @@ class KinematicBody2D : public PhysicsBody2D {
|
|||
Vector2 normal;
|
||||
Vector2 collider_vel;
|
||||
ObjectID collider;
|
||||
|
||||
int collider_shape;
|
||||
|
||||
Variant _get_collider() const;
|
||||
|
||||
|
@ -273,6 +273,7 @@ public:
|
|||
Vector2 get_collision_normal() const;
|
||||
Vector2 get_collider_velocity() const;
|
||||
ObjectID get_collider() const;
|
||||
int get_collider_shape() const;
|
||||
|
||||
void set_collide_with_static_bodies(bool p_enable);
|
||||
bool can_collide_with_static_bodies() const;
|
||||
|
|
|
@ -435,15 +435,20 @@ void Light::_update_visibility() {
|
|||
if (!is_inside_scene())
|
||||
return;
|
||||
|
||||
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
bool editor_ok=true;
|
||||
if (editor_only) {
|
||||
|
||||
if (!get_scene()->is_editor_hint()) {
|
||||
editor_ok=false;
|
||||
} else {
|
||||
editor_ok = (get_scene()->get_edited_scene_root() && (this==get_scene()->get_edited_scene_root() || get_owner()==get_scene()->get_edited_scene_root()));
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool editor_ok=false;
|
||||
#endif
|
||||
|
||||
|
||||
VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && enabled && editor_ok);
|
||||
|
|
|
@ -967,6 +967,7 @@ Vector3 KinematicBody::move(const Vector3& p_motion) {
|
|||
normal=rest.normal;
|
||||
collider=rest.collider_id;
|
||||
collider_vel=rest.linear_velocity;
|
||||
collider_shape=rest.shape;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1055,7 +1056,12 @@ ObjectID KinematicBody::get_collider() const {
|
|||
ERR_FAIL_COND_V(!colliding,0);
|
||||
return collider;
|
||||
}
|
||||
int KinematicBody::get_collider_shape() const {
|
||||
|
||||
ERR_FAIL_COND_V(!colliding,-1);
|
||||
return collider_shape;
|
||||
|
||||
}
|
||||
void KinematicBody::set_collide_with_static_bodies(bool p_enable) {
|
||||
|
||||
collide_static=p_enable;
|
||||
|
@ -1119,6 +1125,7 @@ void KinematicBody::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_collision_normal"),&KinematicBody::get_collision_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_velocity"),&KinematicBody::get_collider_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody::_get_collider);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody::get_collider_shape);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_collide_with_static_bodies","enable"),&KinematicBody::set_collide_with_static_bodies);
|
||||
|
@ -1155,6 +1162,7 @@ KinematicBody::KinematicBody() : PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC)
|
|||
colliding=false;
|
||||
collider=0;
|
||||
margin=0.001;
|
||||
collider_shape=0;
|
||||
}
|
||||
KinematicBody::~KinematicBody() {
|
||||
|
||||
|
|
|
@ -266,6 +266,7 @@ class KinematicBody : public PhysicsBody {
|
|||
Vector3 normal;
|
||||
Vector3 collider_vel;
|
||||
ObjectID collider;
|
||||
int collider_shape;
|
||||
|
||||
|
||||
Variant _get_collider() const;
|
||||
|
@ -291,6 +292,7 @@ public:
|
|||
Vector3 get_collision_normal() const;
|
||||
Vector3 get_collider_velocity() const;
|
||||
ObjectID get_collider() const;
|
||||
int get_collider_shape() const;
|
||||
|
||||
void set_collide_with_static_bodies(bool p_enable);
|
||||
bool can_collide_with_static_bodies() const;
|
||||
|
|
|
@ -1085,7 +1085,9 @@ SceneMainLoop::SceneMainLoop() {
|
|||
|
||||
root->set_physics_object_picking(GLOBAL_DEF("physics/enable_object_picking",true));
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
edited_scene_root=NULL;
|
||||
#endif
|
||||
|
||||
ADD_SIGNAL( MethodInfo("idle_frame"));
|
||||
ADD_SIGNAL( MethodInfo("fixed_frame"));
|
||||
|
|
|
@ -37,9 +37,10 @@ void Timer::_notification(int p_what) {
|
|||
case NOTIFICATION_READY: {
|
||||
|
||||
if (autostart) {
|
||||
if (get_scene()->is_editor_hint() && get_scene()->get_edited_scene_root() && (get_scene()->get_edited_scene_root()==this || get_scene()->get_edited_scene_root()->is_a_parent_of(this)))
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (get_scene()->is_editor_hint() && get_scene()->get_edited_scene_root() && (get_scene()->get_edited_scene_root()==this || get_scene()->get_edited_scene_root()->is_a_parent_of(this)))
|
||||
break;
|
||||
start();
|
||||
#endif start();
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_PROCESS: {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "mesh.h"
|
||||
#include "scene/resources/concave_polygon_shape.h"
|
||||
#include "scene/resources/convex_polygon_shape.h"
|
||||
#include "surface_tool.h"
|
||||
|
||||
static const char*_array_name[]={
|
||||
"vertex_array",
|
||||
|
@ -648,6 +649,30 @@ void Mesh::center_geometry() {
|
|||
|
||||
}
|
||||
|
||||
void Mesh::regen_normalmaps() {
|
||||
|
||||
|
||||
Vector< Ref<SurfaceTool> > surfs;
|
||||
for(int i=0;i<get_surface_count();i++) {
|
||||
|
||||
Ref<SurfaceTool> st = memnew( SurfaceTool );
|
||||
st->create_from(Ref<Mesh>(this),i);
|
||||
surfs.push_back(st);
|
||||
}
|
||||
|
||||
while (get_surface_count()) {
|
||||
surface_remove(0);
|
||||
}
|
||||
|
||||
for(int i=0;i<surfs.size();i++) {
|
||||
|
||||
surfs[i]->generate_tangents();
|
||||
surfs[i]->commit(Ref<Mesh>(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
|
||||
|
||||
if (triangle_mesh.is_valid())
|
||||
|
@ -740,6 +765,8 @@ void Mesh::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("surface_get_name","surf_idx"),&Mesh::surface_get_name);
|
||||
ObjectTypeDB::bind_method(_MD("center_geometry"),&Mesh::center_geometry);
|
||||
ObjectTypeDB::set_method_flags(get_type_static(),_SCS("center_geometry"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
|
||||
ObjectTypeDB::bind_method(_MD("regen_normalmaps"),&Mesh::regen_normalmaps);
|
||||
ObjectTypeDB::set_method_flags(get_type_static(),_SCS("regen_normalmaps"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_custom_aabb","aabb"),&Mesh::set_custom_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_custom_aabb"),&Mesh::get_custom_aabb);
|
||||
|
|
|
@ -167,6 +167,7 @@ public:
|
|||
Ref<Shape> create_convex_shape() const;
|
||||
|
||||
void center_geometry();
|
||||
void regen_normalmaps();
|
||||
|
||||
DVector<Face3> get_faces() const;
|
||||
Ref<TriangleMesh> generate_triangle_mesh() const;
|
||||
|
|
|
@ -105,7 +105,7 @@ void SurfaceTool::add_vertex( const Vector3& p_vertex) {
|
|||
vtx.weights=last_weights;
|
||||
vtx.bones=last_bones;
|
||||
vtx.tangent=last_tangent.normal;
|
||||
vtx.binormal=last_tangent.normal.cross(last_normal).normalized() * last_tangent.d;
|
||||
vtx.binormal=last_normal.cross(last_tangent.normal).normalized() * last_tangent.d;
|
||||
vertex_array.push_back(vtx);
|
||||
first=false;
|
||||
format|=Mesh::ARRAY_FORMAT_VERTEX;
|
||||
|
@ -299,7 +299,9 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
|
|||
w[idx+0]=v.tangent.x;
|
||||
w[idx+1]=v.tangent.y;
|
||||
w[idx+2]=v.tangent.z;
|
||||
float d = v.binormal.dot(v.normal.cross(v.tangent));
|
||||
|
||||
//float d = v.tangent.dot(v.binormal,v.normal);
|
||||
float d = v.binormal.dot( v.normal.cross(v.tangent));
|
||||
w[idx+3]=d<0 ? -1 : 1;
|
||||
}
|
||||
|
||||
|
@ -565,6 +567,7 @@ void SurfaceTool::create_from(const Ref<Mesh>& p_existing, int p_surface) {
|
|||
clear();
|
||||
primitive=p_existing->surface_get_primitive_type(p_surface);
|
||||
_create_list(p_existing,p_surface,&vertex_array,&index_array,format);
|
||||
material=p_existing->surface_get_material(p_surface);
|
||||
|
||||
}
|
||||
|
||||
|
@ -611,166 +614,97 @@ void SurfaceTool::append_from(const Ref<Mesh>& p_existing, int p_surface,const T
|
|||
|
||||
}
|
||||
|
||||
//mikktspace callbacks
|
||||
int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext * pContext) {
|
||||
|
||||
Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData);
|
||||
return varr.size()/3;
|
||||
}
|
||||
int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext * pContext, const int iFace){
|
||||
|
||||
return 3; //always 3
|
||||
}
|
||||
void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert){
|
||||
|
||||
Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData);
|
||||
Vector3 v = varr[iFace*3+iVert]->get().vertex;
|
||||
fvPosOut[0]=v.x;
|
||||
fvPosOut[1]=v.y;
|
||||
fvPosOut[2]=v.z;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert){
|
||||
|
||||
|
||||
Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData);
|
||||
Vector3 v = varr[iFace*3+iVert]->get().normal;
|
||||
fvNormOut[0]=v.x;
|
||||
fvNormOut[1]=v.y;
|
||||
fvNormOut[2]=v.z;
|
||||
|
||||
}
|
||||
void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert){
|
||||
|
||||
Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData);
|
||||
Vector2 v = varr[iFace*3+iVert]->get().uv;
|
||||
fvTexcOut[0]=v.x;
|
||||
//fvTexcOut[1]=v.y;
|
||||
fvTexcOut[1]=1.0-v.y;
|
||||
|
||||
}
|
||||
void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert){
|
||||
|
||||
Vector<List<Vertex>::Element*> &varr = *((Vector<List<Vertex>::Element*>*)pContext->m_pUserData);
|
||||
Vertex &vtx = varr[iFace*3+iVert]->get();
|
||||
|
||||
vtx.tangent = Vector3(fvTangent[0],fvTangent[1],fvTangent[2]);
|
||||
vtx.binormal = vtx.normal.cross(vtx.tangent) * fSign;
|
||||
}
|
||||
|
||||
|
||||
void SurfaceTool::generate_tangents() {
|
||||
|
||||
ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV));
|
||||
ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL));
|
||||
|
||||
|
||||
if (index_array.size()) {
|
||||
|
||||
Vector<List<Vertex>::Element*> vtx;
|
||||
vtx.resize(vertex_array.size());
|
||||
int idx=0;
|
||||
for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
|
||||
vtx[idx++]=E;
|
||||
E->get().binormal=Vector3();
|
||||
E->get().tangent=Vector3();
|
||||
}
|
||||
|
||||
for (List<int>::Element *E=index_array.front();E;) {
|
||||
|
||||
int i[3];
|
||||
i[0]=E->get();
|
||||
E=E->next();
|
||||
ERR_FAIL_COND(!E);
|
||||
i[1]=E->get();
|
||||
E=E->next();
|
||||
ERR_FAIL_COND(!E);
|
||||
i[2]=E->get();
|
||||
E=E->next();
|
||||
ERR_FAIL_COND(!E);
|
||||
bool indexed = index_array.size()>0;
|
||||
if (indexed)
|
||||
deindex();
|
||||
|
||||
|
||||
Vector3 v1 = vtx[ i[0] ]->get().vertex;
|
||||
Vector3 v2 = vtx[ i[1] ]->get().vertex;
|
||||
Vector3 v3 = vtx[ i[2] ]->get().vertex;
|
||||
SMikkTSpaceInterface mkif;
|
||||
mkif.m_getNormal=mikktGetNormal;
|
||||
mkif.m_getNumFaces=mikktGetNumFaces;
|
||||
mkif.m_getNumVerticesOfFace=mikktGetNumVerticesOfFace;
|
||||
mkif.m_getPosition=mikktGetPosition;
|
||||
mkif.m_getTexCoord=mikktGetTexCoord;
|
||||
mkif.m_setTSpaceBasic=mikktSetTSpaceBasic;
|
||||
mkif.m_setTSpace=NULL;
|
||||
|
||||
Vector2 w1 = vtx[ i[0] ]->get().uv;
|
||||
Vector2 w2 = vtx[ i[1] ]->get().uv;
|
||||
Vector2 w3 = vtx[ i[2] ]->get().uv;
|
||||
SMikkTSpaceContext msc;
|
||||
msc.m_pInterface=&mkif;
|
||||
|
||||
|
||||
float x1 = v2.x - v1.x;
|
||||
float x2 = v3.x - v1.x;
|
||||
float y1 = v2.y - v1.y;
|
||||
float y2 = v3.y - v1.y;
|
||||
float z1 = v2.z - v1.z;
|
||||
float z2 = v3.z - v1.z;
|
||||
|
||||
float s1 = w2.x - w1.x;
|
||||
float s2 = w3.x - w1.x;
|
||||
float t1 = w2.y - w1.y;
|
||||
float t2 = w3.y - w1.y;
|
||||
|
||||
float r = (s1 * t2 - s2 * t1);
|
||||
|
||||
Vector3 binormal,tangent;
|
||||
|
||||
if (r==0) {
|
||||
binormal=Vector3(0,0,0);
|
||||
tangent=Vector3(0,0,0);
|
||||
} else {
|
||||
tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||
(t2 * z1 - t1 * z2) * r);
|
||||
binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||
(s1 * z2 - s2 * z1) * r);
|
||||
}
|
||||
|
||||
tangent.normalize();
|
||||
binormal.normalize();
|
||||
Vector3 normal=Plane( v1, v2, v3 ).normal;
|
||||
|
||||
Vector3 tangentp = tangent - normal * normal.dot( tangent );
|
||||
Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
|
||||
|
||||
tangentp.normalize();
|
||||
binormalp.normalize();
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
vtx[ i[j] ]->get().binormal+=binormalp;
|
||||
vtx[ i[j] ]->get().tangent+=tangentp;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
|
||||
E->get().binormal.normalize();
|
||||
E->get().tangent.normalize();
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
for (List<Vertex>::Element *E=vertex_array.front();E;) {
|
||||
|
||||
List< Vertex >::Element *v[3];
|
||||
v[0]=E;
|
||||
v[1]=v[0]->next();
|
||||
ERR_FAIL_COND(!v[1]);
|
||||
v[2]=v[1]->next();
|
||||
ERR_FAIL_COND(!v[2]);
|
||||
E=v[2]->next();
|
||||
|
||||
Vector3 v1 = v[0]->get().vertex;
|
||||
Vector3 v2 = v[1]->get().vertex;
|
||||
Vector3 v3 = v[2]->get().vertex;
|
||||
|
||||
Vector2 w1 = v[0]->get().uv;
|
||||
Vector2 w2 = v[1]->get().uv;
|
||||
Vector2 w3 = v[2]->get().uv;
|
||||
|
||||
|
||||
float x1 = v2.x - v1.x;
|
||||
float x2 = v3.x - v1.x;
|
||||
float y1 = v2.y - v1.y;
|
||||
float y2 = v3.y - v1.y;
|
||||
float z1 = v2.z - v1.z;
|
||||
float z2 = v3.z - v1.z;
|
||||
|
||||
float s1 = w2.x - w1.x;
|
||||
float s2 = w3.x - w1.x;
|
||||
float t1 = w2.y - w1.y;
|
||||
float t2 = w3.y - w1.y;
|
||||
|
||||
float r = (s1 * t2 - s2 * t1);
|
||||
|
||||
Vector3 binormal,tangent;
|
||||
|
||||
if (r==0) {
|
||||
binormal=Vector3(0,0,0);
|
||||
tangent=Vector3(0,0,0);
|
||||
} else {
|
||||
tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||
(t2 * z1 - t1 * z2) * r);
|
||||
binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||
(s1 * z2 - s2 * z1) * r);
|
||||
}
|
||||
|
||||
tangent.normalize();
|
||||
binormal.normalize();
|
||||
Vector3 normal=Plane( v1, v2, v3 ).normal;
|
||||
|
||||
Vector3 tangentp = tangent - normal * normal.dot( tangent );
|
||||
Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
|
||||
|
||||
tangentp.normalize();
|
||||
binormalp.normalize();
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
v[j]->get().binormal=binormalp;
|
||||
v[j]->get().tangent=tangentp;
|
||||
|
||||
}
|
||||
}
|
||||
Vector<List<Vertex>::Element*> vtx;
|
||||
vtx.resize(vertex_array.size());
|
||||
int idx=0;
|
||||
for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
|
||||
vtx[idx++]=E;
|
||||
E->get().binormal=Vector3();
|
||||
E->get().tangent=Vector3();
|
||||
}
|
||||
msc.m_pUserData=&vtx;
|
||||
|
||||
bool res = genTangSpaceDefault(&msc);
|
||||
|
||||
ERR_FAIL_COND(!res);
|
||||
format|=Mesh::ARRAY_FORMAT_TANGENT;
|
||||
|
||||
if (indexed)
|
||||
index();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SurfaceTool::generate_normals() {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define SURFACE_TOOL_H
|
||||
|
||||
#include "scene/resources/mesh.h"
|
||||
|
||||
#include "mikktspace.h"
|
||||
|
||||
|
||||
class SurfaceTool : public Reference {
|
||||
|
@ -82,6 +82,14 @@ private:
|
|||
|
||||
void _create_list(const Ref<Mesh>& p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index,int &lformat);
|
||||
|
||||
|
||||
//mikktspace callbacks
|
||||
static int mikktGetNumFaces(const SMikkTSpaceContext * pContext);
|
||||
static int mikktGetNumVerticesOfFace(const SMikkTSpaceContext * pContext, const int iFace);
|
||||
static void mikktGetPosition(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert);
|
||||
static void mikktGetNormal(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert);
|
||||
static void mikktGetTexCoord(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert);
|
||||
static void mikktSetTSpaceBasic(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -185,6 +185,7 @@ float BodySW::get_param(PhysicsServer::BodyParameter p_param) const {
|
|||
|
||||
void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
|
||||
|
||||
PhysicsServer::BodyMode prev=mode;
|
||||
mode=p_mode;
|
||||
|
||||
switch(p_mode) {
|
||||
|
@ -199,6 +200,10 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
|
|||
set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC && contacts.size());
|
||||
linear_velocity=Vector3();
|
||||
angular_velocity=Vector3();
|
||||
if (mode==PhysicsServer::BODY_MODE_KINEMATIC && prev!=mode) {
|
||||
first_time_kinematic=true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case PhysicsServer::BODY_MODE_RIGID: {
|
||||
|
||||
|
@ -238,6 +243,11 @@ void BodySW::set_state(PhysicsServer::BodyState p_state, const Variant& p_varian
|
|||
new_transform=p_variant;
|
||||
//wakeup_neighbours();
|
||||
set_active(true);
|
||||
if (first_time_kinematic) {
|
||||
_set_transform(p_variant);
|
||||
_set_inv_transform(get_transform().affine_inverse());
|
||||
first_time_kinematic=false;
|
||||
}
|
||||
|
||||
} else if (mode==PhysicsServer::BODY_MODE_STATIC) {
|
||||
_set_transform(p_variant);
|
||||
|
@ -669,6 +679,7 @@ BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_upda
|
|||
island_step=0;
|
||||
island_next=NULL;
|
||||
island_list_next=NULL;
|
||||
first_time_kinematic=false;
|
||||
_set_static(false);
|
||||
density=0;
|
||||
contact_count=0;
|
||||
|
|
|
@ -74,6 +74,7 @@ class BodySW : public CollisionObjectSW {
|
|||
|
||||
bool continuous_cd;
|
||||
bool can_sleep;
|
||||
bool first_time_kinematic;
|
||||
void _update_inertia();
|
||||
virtual void _shapes_changed();
|
||||
Transform new_transform;
|
||||
|
|
|
@ -176,6 +176,7 @@ float Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const {
|
|||
|
||||
void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
|
||||
|
||||
Physics2DServer::BodyMode prev=mode;
|
||||
mode=p_mode;
|
||||
|
||||
switch(p_mode) {
|
||||
|
@ -189,6 +190,9 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
|
|||
set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC && contacts.size());
|
||||
linear_velocity=Vector2();
|
||||
angular_velocity=0;
|
||||
if (mode==Physics2DServer::BODY_MODE_KINEMATIC && prev!=mode) {
|
||||
first_time_kinematic=true;
|
||||
}
|
||||
} break;
|
||||
case Physics2DServer::BODY_MODE_RIGID: {
|
||||
|
||||
|
@ -226,9 +230,15 @@ void Body2DSW::set_state(Physics2DServer::BodyState p_state, const Variant& p_va
|
|||
|
||||
|
||||
if (mode==Physics2DServer::BODY_MODE_KINEMATIC) {
|
||||
new_transform=p_variant;
|
||||
|
||||
new_transform=p_variant;
|
||||
//wakeup_neighbours();
|
||||
set_active(true);
|
||||
if (first_time_kinematic) {
|
||||
_set_transform(p_variant);
|
||||
_set_inv_transform(get_transform().affine_inverse());
|
||||
first_time_kinematic=false;
|
||||
}
|
||||
} else if (mode==Physics2DServer::BODY_MODE_STATIC) {
|
||||
_set_transform(p_variant);
|
||||
_set_inv_transform(get_transform().affine_inverse());
|
||||
|
@ -591,6 +601,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti
|
|||
island_next=NULL;
|
||||
island_list_next=NULL;
|
||||
_set_static(false);
|
||||
first_time_kinematic=false;
|
||||
density=0;
|
||||
contact_count=0;
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ class Body2DSW : public CollisionObject2DSW {
|
|||
bool omit_force_integration;
|
||||
bool active;
|
||||
bool can_sleep;
|
||||
bool first_time_kinematic;
|
||||
void _update_inertia();
|
||||
virtual void _shapes_changed();
|
||||
Matrix32 new_transform;
|
||||
|
|
|
@ -98,11 +98,10 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) {
|
|||
}
|
||||
if (p_key.use_xy_normalmap) {
|
||||
scode+="vec2 ywnormal=tex( fmp_normal_tex,"+uv_str+").wy * vec2(2.0,2.0) - vec2(1.0,1.0);\n";
|
||||
scode+="vec3 normal=vec3(ywnormal,sqrt(1 - (ywnormal.x * ywnormal.x) - (ywnormal.y * ywnormal.y) ));\n";
|
||||
scode+="NORMALMAP=vec3(ywnormal,sqrt(1 - (ywnormal.x * ywnormal.x) - (ywnormal.y * ywnormal.y) ));\n";
|
||||
} else {
|
||||
scode+="vec3 normal=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n";
|
||||
scode+="NORMALMAP=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n";
|
||||
}
|
||||
scode+="NORMAL = mix( NORMAL,mat3(TANGENT,BINORMAL,NORMAL) * normal, fmp_normal);\n";
|
||||
code+=scode;
|
||||
}
|
||||
|
||||
|
|
|
@ -1042,6 +1042,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[]={
|
|||
{ "NORMAL", TYPE_VEC3},
|
||||
{ "TANGENT", TYPE_VEC3},
|
||||
{ "BINORMAL", TYPE_VEC3},
|
||||
{ "NORMALMAP", TYPE_VEC3},
|
||||
{ "UV", TYPE_VEC2},
|
||||
{ "UV2", TYPE_VEC2},
|
||||
{ "COLOR", TYPE_VEC4},
|
||||
|
|
|
@ -749,7 +749,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
|
|||
Vector3 tangent =Vector3(tangent_src->array[tangent_pos+0],tangent_src->array[tangent_pos+1],tangent_src->array[tangent_pos+2]);
|
||||
|
||||
vertex.tangent.normal=tangent;
|
||||
vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? -1 : 1;
|
||||
vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -784,6 +784,8 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
|
|||
vertex.vertex.z = -vertex.vertex.z;
|
||||
SWAP( vertex.normal.z, vertex.normal.y );
|
||||
vertex.normal.z = -vertex.normal.z;
|
||||
SWAP( vertex.tangent.normal.z, vertex.tangent.normal.y );
|
||||
vertex.tangent.normal.z = -vertex.tangent.normal.z;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2468,7 +2468,7 @@ void SpatialEditor::set_state(const Dictionary& p_state) {
|
|||
}
|
||||
|
||||
if (d.has("default_srgb")) {
|
||||
bool use = d["default_light"];
|
||||
bool use = d["default_srgb"];
|
||||
|
||||
viewport_environment->set_enable_fx(Environment::FX_SRGB,use);
|
||||
view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use );
|
||||
|
|
|
@ -83,6 +83,17 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
|
|||
description="Apply modifiers to mesh objects (on a copy!).",
|
||||
default=True,
|
||||
)
|
||||
use_tangent_arrays = BoolProperty(
|
||||
name="Tangent Arrays",
|
||||
description="Export Tangent and Binormal arrays (for normalmapping).",
|
||||
default=False,
|
||||
)
|
||||
use_triangles = BoolProperty(
|
||||
name="Triangulate",
|
||||
description="Export Triangles instead of Polygons.",
|
||||
default=False,
|
||||
)
|
||||
|
||||
use_copy_images = BoolProperty(
|
||||
name="Copy Images",
|
||||
description="Copy Images (create images/ subfolder)",
|
||||
|
@ -118,6 +129,7 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
|
|||
description="Remove double keyframes",
|
||||
default=True,
|
||||
)
|
||||
|
||||
anim_optimize_precision = FloatProperty(
|
||||
name="Precision",
|
||||
description=("Tolerence for comparing double keyframes "
|
||||
|
@ -126,6 +138,7 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
|
|||
soft_min=1, soft_max=16,
|
||||
default=6.0,
|
||||
)
|
||||
|
||||
use_metadata = BoolProperty(
|
||||
name="Use Metadata",
|
||||
default=True,
|
||||
|
|
|
@ -43,6 +43,7 @@ import time
|
|||
import math # math.pi
|
||||
import shutil
|
||||
import bpy
|
||||
import bmesh
|
||||
from mathutils import Vector, Matrix
|
||||
|
||||
#according to collada spec, order matters
|
||||
|
@ -125,6 +126,12 @@ class DaeExporter:
|
|||
tup = (self.vertex.x,self.vertex.y,self.vertex.z,self.normal.x,self.normal.y,self.normal.z)
|
||||
for t in self.uv:
|
||||
tup = tup + (t.x,t.y)
|
||||
if (self.color!=None):
|
||||
tup = tup + (self.color.x,self.color.y,self.color.z)
|
||||
if (self.tangent!=None):
|
||||
tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z)
|
||||
if (self.bitangent!=None):
|
||||
tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z)
|
||||
#for t in self.bones:
|
||||
# tup = tup + (t)
|
||||
#for t in self.weights:
|
||||
|
@ -135,7 +142,9 @@ class DaeExporter:
|
|||
def __init__(self):
|
||||
self.vertex = Vector( (0.0,0.0,0.0) )
|
||||
self.normal = Vector( (0.0,0.0,0.0) )
|
||||
self.color = Vector( (0.0,0.0,0.0) )
|
||||
self.tangent = None
|
||||
self.bitangent = None
|
||||
self.color = None
|
||||
self.uv = []
|
||||
self.uv2 = Vector( (0.0,0.0) )
|
||||
self.bones=[]
|
||||
|
@ -442,10 +451,18 @@ class DaeExporter:
|
|||
self.mesh_cache[node.data]=meshdata
|
||||
return meshdata
|
||||
|
||||
if (len(node.modifiers) and self.config["use_mesh_modifiers"]):
|
||||
mesh=node.to_mesh(self.scene,True,"RENDER") #is this allright?
|
||||
else:
|
||||
mesh=node.data
|
||||
apply_modifiers = len(node.modifiers) and self.config["use_mesh_modifiers"]
|
||||
|
||||
mesh=node.to_mesh(self.scene,apply_modifiers,"RENDER") #is this allright?
|
||||
|
||||
triangulate=self.config["use_triangles"]
|
||||
if (triangulate):
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(mesh)
|
||||
bmesh.ops.triangulate(bm, faces=bm.faces)
|
||||
bm.to_mesh(mesh)
|
||||
bm.free()
|
||||
|
||||
|
||||
mesh.update(calc_tessface=True)
|
||||
vertices=[]
|
||||
|
@ -462,20 +479,22 @@ class DaeExporter:
|
|||
has_uv=False
|
||||
has_uv2=False
|
||||
has_weights=armature!=None
|
||||
has_colors=False
|
||||
has_tangents=self.config["use_tangent_arrays"] # could detect..
|
||||
has_colors=len(mesh.vertex_colors)
|
||||
mat_assign=[]
|
||||
|
||||
uv_layer_count=len(mesh.uv_textures)
|
||||
mesh.calc_tangents()
|
||||
|
||||
for fi in range(len(mesh.tessfaces)):
|
||||
f=mesh.tessfaces[fi]
|
||||
|
||||
for fi in range(len(mesh.polygons)):
|
||||
f=mesh.polygons[fi]
|
||||
|
||||
if (not (f.material_index in surface_indices)):
|
||||
surface_indices[f.material_index]=[]
|
||||
print("Type: "+str(type(f.material_index)))
|
||||
print("IDX: "+str(f.material_index)+"/"+str(len(mesh.materials)))
|
||||
|
||||
|
||||
try:
|
||||
#Bizarre blender behavior i don't understand, so catching exception
|
||||
mat = mesh.materials[f.material_index]
|
||||
|
@ -489,35 +508,42 @@ class DaeExporter:
|
|||
|
||||
indices = surface_indices[f.material_index]
|
||||
vi=[]
|
||||
#make triangles always
|
||||
#vertices always 3
|
||||
"""
|
||||
if (len(f.vertices)==3):
|
||||
vi.append(0)
|
||||
vi.append(1)
|
||||
vi.append(2)
|
||||
elif (len(f.vertices)==4):
|
||||
#todo, should use shortest path
|
||||
vi.append(0)
|
||||
vi.append(1)
|
||||
vi.append(2)
|
||||
vi.append(0)
|
||||
vi.append(2)
|
||||
vi.append(3)
|
||||
"""
|
||||
|
||||
for x in vi:
|
||||
mv = mesh.vertices[f.vertices[x]]
|
||||
for lt in range(f.loop_total):
|
||||
loop_index = f.loop_start + lt
|
||||
ml = mesh.loops[loop_index]
|
||||
mv = mesh.vertices[ml.vertex_index]
|
||||
|
||||
v = self.Vertex()
|
||||
v.vertex = Vector( mv.co )
|
||||
|
||||
for xt in mesh.tessface_uv_textures:
|
||||
d = xt.data[fi]
|
||||
uvsrc = [d.uv1,d.uv2,d.uv3,d.uv4]
|
||||
v.uv.append( Vector( uvsrc[x] ) )
|
||||
for xt in mesh.uv_layers:
|
||||
v.uv.append( Vector( xt.data[loop_index].uv ) )
|
||||
|
||||
if (has_colors):
|
||||
v.color = Vector( mesh.vertex_colors[0].data[loop_index].color )
|
||||
|
||||
v.normal = Vector( ml.normal )
|
||||
|
||||
if (has_tangents):
|
||||
v.tangent = Vector( ml.tangent )
|
||||
v.bitangent = Vector( ml.bitangent )
|
||||
|
||||
if (f.use_smooth):
|
||||
v.normal=Vector( mv.normal )
|
||||
else:
|
||||
v.normal=Vector( f.normal )
|
||||
|
||||
# if (armature):
|
||||
# v.vertex = node.matrix_world * v.vertex
|
||||
|
@ -531,6 +557,7 @@ class DaeExporter:
|
|||
continue;
|
||||
name = node.vertex_groups[vg.group].name
|
||||
if (name in si["bone_index"]):
|
||||
#could still put the weight as 0.0001 maybe
|
||||
if (vg.weight>0.001): #blender has a lot of zero weight stuff
|
||||
v.bones.append(si["bone_index"][name])
|
||||
v.weights.append(vg.weight)
|
||||
|
@ -546,7 +573,11 @@ class DaeExporter:
|
|||
vertices.append(v)
|
||||
vertex_map[tup]=idx
|
||||
|
||||
indices.append(idx)
|
||||
vi.append(idx)
|
||||
|
||||
if (len(vi)>2):
|
||||
#only triangles and above
|
||||
indices.append(vi)
|
||||
|
||||
|
||||
meshid = self.new_id("mesh")
|
||||
|
@ -586,6 +617,37 @@ class DaeExporter:
|
|||
self.writel(S_GEOM,4,'</technique_common>')
|
||||
self.writel(S_GEOM,3,'</source>')
|
||||
|
||||
if (has_tangents):
|
||||
self.writel(S_GEOM,3,'<source id="'+meshid+'-tangents">')
|
||||
float_values=""
|
||||
for v in vertices:
|
||||
float_values+=" "+str(v.tangent.x)+" "+str(v.tangent.y)+" "+str(v.tangent.z)
|
||||
self.writel(S_GEOM,4,'<float_array id="'+meshid+'-tangents-array" count="'+str(len(vertices)*3)+'">'+float_values+'</float_array>')
|
||||
self.writel(S_GEOM,4,'<technique_common>')
|
||||
self.writel(S_GEOM,4,'<accessor source="#'+meshid+'-tangents-array" count="'+str(len(vertices))+'" stride="3">')
|
||||
self.writel(S_GEOM,5,'<param name="X" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Y" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Z" type="float"/>')
|
||||
self.writel(S_GEOM,4,'</accessor>')
|
||||
self.writel(S_GEOM,4,'</technique_common>')
|
||||
self.writel(S_GEOM,3,'</source>')
|
||||
|
||||
self.writel(S_GEOM,3,'<source id="'+meshid+'-bitangents">')
|
||||
float_values=""
|
||||
for v in vertices:
|
||||
float_values+=" "+str(v.bitangent.x)+" "+str(v.bitangent.y)+" "+str(v.bitangent.z)
|
||||
self.writel(S_GEOM,4,'<float_array id="'+meshid+'-bitangents-array" count="'+str(len(vertices)*3)+'">'+float_values+'</float_array>')
|
||||
self.writel(S_GEOM,4,'<technique_common>')
|
||||
self.writel(S_GEOM,4,'<accessor source="#'+meshid+'-bitangents-array" count="'+str(len(vertices))+'" stride="3">')
|
||||
self.writel(S_GEOM,5,'<param name="X" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Y" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Z" type="float"/>')
|
||||
self.writel(S_GEOM,4,'</accessor>')
|
||||
self.writel(S_GEOM,4,'</technique_common>')
|
||||
self.writel(S_GEOM,3,'</source>')
|
||||
|
||||
|
||||
|
||||
# UV Arrays
|
||||
|
||||
for uvi in range(uv_layer_count):
|
||||
|
@ -608,36 +670,75 @@ class DaeExporter:
|
|||
self.writel(S_GEOM,4,'</technique_common>')
|
||||
self.writel(S_GEOM,3,'</source>')
|
||||
|
||||
# Color Arrays
|
||||
|
||||
if (has_colors):
|
||||
self.writel(S_GEOM,3,'<source id="'+meshid+'-colors">')
|
||||
float_values=""
|
||||
for v in vertices:
|
||||
float_values+=" "+str(v.color.x)+" "+str(v.color.y)+" "+str(v.color.z)
|
||||
self.writel(S_GEOM,4,'<float_array id="'+meshid+'-colors-array" count="'+str(len(vertices)*3)+'">'+float_values+'</float_array>')
|
||||
self.writel(S_GEOM,4,'<technique_common>')
|
||||
self.writel(S_GEOM,4,'<accessor source="#'+meshid+'-colors-array" count="'+str(len(vertices))+'" stride="3">')
|
||||
self.writel(S_GEOM,5,'<param name="X" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Y" type="float"/>')
|
||||
self.writel(S_GEOM,5,'<param name="Z" type="float"/>')
|
||||
self.writel(S_GEOM,4,'</accessor>')
|
||||
self.writel(S_GEOM,4,'</technique_common>')
|
||||
self.writel(S_GEOM,3,'</source>')
|
||||
|
||||
# Triangle Lists
|
||||
self.writel(S_GEOM,3,'<vertices id="'+meshid+'-vertices">')
|
||||
self.writel(S_GEOM,4,'<input semantic="POSITION" source="#'+meshid+'-positions"/>')
|
||||
self.writel(S_GEOM,3,'</vertices>')
|
||||
|
||||
prim_type=""
|
||||
if (triangulate):
|
||||
prim_type="triangles"
|
||||
else:
|
||||
prim_type="polygons"
|
||||
|
||||
|
||||
for m in surface_indices:
|
||||
indices = surface_indices[m]
|
||||
mat = materials[m]
|
||||
|
||||
if (mat!=None):
|
||||
matref = self.new_id("trimat")
|
||||
self.writel(S_GEOM,3,'<triangles count="'+str(int(len(indices)/3))+'" material="'+matref+'">') # todo material
|
||||
self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material
|
||||
mat_assign.append( (mat,matref) )
|
||||
else:
|
||||
self.writel(S_GEOM,3,'<triangles count="'+str(int(len(indices)/3))+'">') # todo material
|
||||
self.writel(S_GEOM,4,'<input semantic="VERTEX" source="#'+meshid+'-vertices" offset="0"/>')
|
||||
self.writel(S_GEOM,4,'<input semantic="NORMAL" source="#'+meshid+'-normals" offset="1"/>')
|
||||
extra_indices=0
|
||||
for uvi in range(uv_layer_count):
|
||||
self.writel(S_GEOM,4,'<input semantic="TEXCOORD" source="#'+meshid+'-texcoord-'+str(uvi)+'" offset="'+str(2+uvi)+'" set="'+str(uvi)+'"/>')
|
||||
extra_indices+=1
|
||||
self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material
|
||||
|
||||
int_values="<p>"
|
||||
for i in range(len(indices)):
|
||||
int_values+=" "+str(indices[i]) # vertex index
|
||||
int_values+=" "+str(indices[i]) # normal index
|
||||
for e in range(extra_indices):
|
||||
int_values+=" "+str(indices[i]) # normal index
|
||||
int_values+="</p>"
|
||||
self.writel(S_GEOM,4,int_values)
|
||||
self.writel(S_GEOM,3,'</triangles>')
|
||||
|
||||
self.writel(S_GEOM,4,'<input semantic="VERTEX" source="#'+meshid+'-vertices" offset="0"/>')
|
||||
self.writel(S_GEOM,4,'<input semantic="NORMAL" source="#'+meshid+'-normals" offset="0"/>')
|
||||
|
||||
for uvi in range(uv_layer_count):
|
||||
self.writel(S_GEOM,4,'<input semantic="TEXCOORD" source="#'+meshid+'-texcoord-'+str(uvi)+'" offset="0" set="'+str(uvi)+'"/>')
|
||||
|
||||
if (has_colors):
|
||||
self.writel(S_GEOM,4,'<input semantic="COLOR" source="#'+meshid+'-colors" offset="0"/>')
|
||||
if (has_tangents):
|
||||
self.writel(S_GEOM,4,'<input semantic="TEXTANGENT" source="#'+meshid+'-tangents" offset="0"/>')
|
||||
self.writel(S_GEOM,4,'<input semantic="TEXBINORMAL" source="#'+meshid+'-bitangents" offset="0"/>')
|
||||
|
||||
if (triangulate):
|
||||
int_values="<p>"
|
||||
for p in indices:
|
||||
for i in p:
|
||||
int_values+=" "+str(i)
|
||||
int_values+=" </p>"
|
||||
self.writel(S_GEOM,4,int_values)
|
||||
else:
|
||||
for p in indices:
|
||||
int_values="<p>"
|
||||
for i in p:
|
||||
int_values+=" "+str(i)
|
||||
int_values+=" </p>"
|
||||
self.writel(S_GEOM,4,int_values)
|
||||
|
||||
self.writel(S_GEOM,3,'</'+prim_type+'>')
|
||||
|
||||
|
||||
self.writel(S_GEOM,2,'</mesh>')
|
||||
|
@ -1355,6 +1456,8 @@ class DaeExporter:
|
|||
self.writel(S_ANIM_CLIPS,0,'</library_animation_clips>')
|
||||
|
||||
for s in self.skeletons:
|
||||
if (s.animation_data==None):
|
||||
continue
|
||||
if s in cached_actions:
|
||||
s.animation_data.action = bpy.data.actions[cached_actions[s]]
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue