-=-=-=-

-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:
Juan Linietsky 2014-10-14 01:01:25 -03:00
parent 13a848e332
commit a84ba9c853
25 changed files with 363 additions and 198 deletions

View file

@ -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");
}

View file

@ -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";
}

View file

@ -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;

View file

@ -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

View file

@ -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() {

View file

@ -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;

View file

@ -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);

View file

@ -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() {

View file

@ -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;

View file

@ -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"));

View file

@ -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: {

View file

@ -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);

View file

@ -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;

View file

@ -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() {

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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},

View file

@ -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;
}

View file

@ -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 );

View file

@ -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,

View file

@ -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: