Light Baker!

-=-=-=-=-=-=

-Support for lightmap baker, have fun figuring out how it works before tutorial is published.
This commit is contained in:
Juan Linietsky 2014-06-11 10:41:03 -03:00
parent 6f0b4678e2
commit 9b8696d3dd
61 changed files with 4252 additions and 1430 deletions

View file

@ -169,6 +169,7 @@ if (env_base['target']=='debug'):
env_base.platforms = {}
for p in platform_list:
if env_base['platform'] != "" and env_base['platform'] != p:

View file

@ -19,9 +19,37 @@ f = open("global_defaults.cpp","wb")
f.write(gd_cpp)
f.close()
import os
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
e=os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
txt = ""
ec_valid=True
if (len(e)!=64):
ec_valid=False
else:
for i in range(len(e)>>1):
if (i>0):
txt+=","
txts="0x"+e[i*2:i*2+2]
try:
int(txts,16)
except:
ec_valid=False
txt+=txts
if (not ec_valid):
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
print("Invalid AES256 encryption key, not 64 bits hex: "+e)
f = open("script_encryption_key.cpp", "wb")
f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
env.add_source_files(env.core_sources,"*.cpp")
Export('env')
import make_binders

View file

@ -1418,7 +1418,7 @@ String _Marshalls::variant_to_base64(const Variant& p_var) {
err = encode_variant(p_var,&w[0],len);
ERR_FAIL_COND_V( err != OK, "" );
int b64len = len / 3 * 4 + 4;
int b64len = len / 3 * 4 + 4 + 1;
DVector<uint8_t> b64buff;
b64buff.resize(b64len);
DVector<uint8_t>::Write w64 = b64buff.write();
@ -1437,7 +1437,7 @@ Variant _Marshalls::base64_to_variant(const String& p_str) {
CharString cstr = p_str.ascii();
DVector<uint8_t> buf;
buf.resize(strlen / 4 * 3);
buf.resize(strlen / 4 * 3 + 1);
DVector<uint8_t>::Write w = buf.write();
int len = base64_decode((char*)(&w[0]), (char*)cstr.get_data(), strlen);

View file

@ -1399,14 +1399,17 @@ int Image::get_format_pallete_size(Format p_format) {
}
void Image::decompress() {
Error Image::decompress() {
if (format>=FORMAT_BC1 && format<=FORMAT_BC5 && _image_decompress_bc)
_image_decompress_bc(this);
if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc)
else if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc)
_image_decompress_pvrtc(this);
if (format==FORMAT_ETC && _image_decompress_etc)
else if (format==FORMAT_ETC && _image_decompress_etc)
_image_decompress_etc(this);
else
return ERR_UNAVAILABLE;
return OK;
}

View file

@ -45,8 +45,8 @@
class Image {
enum {
MAX_WIDTH=4096, // force a limit somehow
MAX_HEIGHT=4096 // force a limit somehow
MAX_WIDTH=16384, // force a limit somehow
MAX_HEIGHT=16384// force a limit somehow
};
public:
@ -317,7 +317,7 @@ public:
Error compress(CompressMode p_mode=COMPRESS_BC);
Image compressed(int p_mode); /* from the Image::CompressMode enum */
void decompress();
Error decompress();
void fix_alpha_edges();
void premultiply_alpha();

View file

@ -193,7 +193,9 @@ Error ResourceInteractiveLoaderXML::close_tag(const String& p_name) {
void ResourceInteractiveLoaderXML::unquote(String& p_str) {
p_str=p_str.strip_edges();
p_str=p_str.strip_edges().replace("\"","").xml_unescape();
/*p_str=p_str.strip_edges();
p_str=p_str.replace("\"","");
p_str=p_str.replace("&gt;","<");
p_str=p_str.replace("&lt;",">");
@ -205,7 +207,7 @@ void ResourceInteractiveLoaderXML::unquote(String& p_str) {
p_str=p_str.replace("&#"+String::num(i)+";",chr);
}
p_str=p_str.replace("&amp;","&");
*/
//p_str.parse_utf8( p_str.ascii(true).get_data() );
}
@ -652,11 +654,14 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
while( idx<len*2) {
CharType c=get_char();
if (c<=32)
continue;
if (idx&1) {
byte|=HEX2CHR(c);
bytesptr[idx>>1]=byte;
//printf("%x\n",int(byte));
} else {
byte=HEX2CHR(c)<<4;

View file

@ -68,7 +68,7 @@ friend class ResourceFormatLoaderXML;
List<RES> resource_cache;
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true);
Error close_tag(const String& p_name);
void unquote(String& p_str);
_FORCE_INLINE_ void unquote(String& p_str);
Error goto_end_of_tag();
Error parse_property_data(String &r_data);
Error parse_property(Variant& r_v, String &r_name);

View file

@ -335,15 +335,6 @@ AABB AABB::grow(real_t p_by) const {
aabb.grow_by(p_by);
return aabb;
}
void AABB::grow_by(real_t p_amount) {
pos.x-=p_amount;
pos.y-=p_amount;
pos.z-=p_amount;
size.x+=2.0*p_amount;
size.y+=2.0*p_amount;
size.z+=2.0*p_amount;
}
void AABB::get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const {

View file

@ -73,6 +73,8 @@ public:
AABB intersection(const AABB& p_aabb) const; ///get box where two intersect, empty if no intersection occurs
bool intersects_segment(const Vector3& p_from, const Vector3& p_to,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
bool intersects_ray(const Vector3& p_from, const Vector3& p_dir,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
_FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &from,const Vector3& p_dir, float t0, float t1) const;
_FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_plane, int p_plane_count) const;
bool intersects_plane(const Plane &p_plane) const;
@ -89,7 +91,7 @@ public:
_FORCE_INLINE_ real_t get_shortest_axis_size() const;
AABB grow(real_t p_by) const;
void grow_by(real_t p_amount);
_FORCE_INLINE_ void grow_by(real_t p_amount);
void get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const;
_FORCE_INLINE_ Vector3 get_endpoint(int p_point) const;
@ -314,6 +316,63 @@ inline real_t AABB::get_shortest_axis_size() const {
return max_size;
}
bool AABB::smits_intersect_ray(const Vector3 &from,const Vector3& dir, float t0, float t1) const {
float divx=1.0/dir.x;
float divy=1.0/dir.y;
float divz=1.0/dir.z;
Vector3 upbound=pos+size;
float tmin, tmax, tymin, tymax, tzmin, tzmax;
if (dir.x >= 0) {
tmin = (pos.x - from.x) * divx;
tmax = (upbound.x - from.x) * divx;
}
else {
tmin = (upbound.x - from.x) * divx;
tmax = (pos.x - from.x) * divx;
}
if (dir.y >= 0) {
tymin = (pos.y - from.y) * divy;
tymax = (upbound.y - from.y) * divy;
}
else {
tymin = (upbound.y - from.y) * divy;
tymax = (pos.y - from.y) * divy;
}
if ( (tmin > tymax) || (tymin > tmax) )
return false;
if (tymin > tmin)
tmin = tymin;
if (tymax < tmax)
tmax = tymax;
if (dir.z >= 0) {
tzmin = (pos.z - from.z) * divz;
tzmax = (upbound.z - from.z) * divz;
}
else {
tzmin = (upbound.z - from.z) * divz;
tzmax = (pos.z - from.z) * divz;
}
if ( (tmin > tzmax) || (tzmin > tmax) )
return false;
if (tzmin > tmin)
tmin = tzmin;
if (tzmax < tmax)
tmax = tzmax;
return ( (tmin < t1) && (tmax > t0) );
}
void AABB::grow_by(real_t p_amount) {
pos.x-=p_amount;
pos.y-=p_amount;
pos.z-=p_amount;
size.x+=2.0*p_amount;
size.y+=2.0*p_amount;
size.z+=2.0*p_amount;
}
typedef AABB Rect3;
#endif // AABB_H

View file

@ -247,7 +247,7 @@ bool Face3::intersects_aabb(const AABB& p_aabb) const {
p_aabb.get_edge(i,from,to);
Vector3 e1=from-to;
for (int j=0;j<3;j++) {
Vector3 e2=edge_norms[i];
Vector3 e2=edge_norms[j];
Vector3 axis=vec3_cross( e1, e2 );

View file

@ -86,6 +86,7 @@ public:
}
bool intersects_aabb(const AABB& p_aabb) const;
_FORCE_INLINE_ bool intersects_aabb2(const AABB& p_aabb) const;
operator String() const;
inline Face3() {}
@ -94,4 +95,172 @@ public:
};
bool Face3::intersects_aabb2(const AABB& p_aabb) const {
Vector3 perp = (vertex[0]-vertex[2]).cross(vertex[0]-vertex[1]);
Vector3 half_extents = p_aabb.size * 0.5;
Vector3 ofs = p_aabb.pos + half_extents;
Vector3 sup =Vector3(
(perp.x>0) ? -half_extents.x : half_extents.x,
(perp.y>0) ? -half_extents.y : half_extents.y,
(perp.z>0) ? -half_extents.z : half_extents.z
);
float d = perp.dot(vertex[0]);
float dist_a = perp.dot(ofs+sup)-d;
float dist_b = perp.dot(ofs-sup)-d;
if (dist_a*dist_b > 0)
return false; //does not intersect the plane
#define TEST_AXIS(m_ax)\
{\
float aabb_min=p_aabb.pos.m_ax;\
float aabb_max=p_aabb.pos.m_ax+p_aabb.size.m_ax;\
float tri_min,tri_max;\
for (int i=0;i<3;i++) {\
if (i==0 || vertex[i].m_ax > tri_max)\
tri_max=vertex[i].m_ax;\
if (i==0 || vertex[i].m_ax < tri_min)\
tri_min=vertex[i].m_ax;\
}\
\
if (tri_max<aabb_min || aabb_max<tri_min)\
return false;\
}
TEST_AXIS(x);
TEST_AXIS(y);
TEST_AXIS(z);
#undef TEST_AXIS
Vector3 edge_norms[3]={
vertex[0]-vertex[1],
vertex[1]-vertex[2],
vertex[2]-vertex[0],
};
for (int i=0;i<12;i++) {
Vector3 from,to;
switch(i) {
case 0:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
} break;
case 1:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
} break;
case 2:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
} break;
case 3:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
} break;
case 4:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
} break;
case 5:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
} break;
case 6:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
} break;
case 7:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
} break;
case 8:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
} break;
case 9:{
from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
} break;
case 10:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
} break;
case 11:{
from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
} break;
}
Vector3 e1=from-to;
for (int j=0;j<3;j++) {
Vector3 e2=edge_norms[j];
Vector3 axis=vec3_cross( e1, e2 );
if (axis.length_squared()<0.0001)
continue; // coplanar
//axis.normalize();
Vector3 sup2 =Vector3(
(axis.x>0) ? -half_extents.x : half_extents.x,
(axis.y>0) ? -half_extents.y : half_extents.y,
(axis.z>0) ? -half_extents.z : half_extents.z
);
float maxB = axis.dot(ofs+sup2);
float minB = axis.dot(ofs-sup2);
if (minB>maxB) {
SWAP(maxB,minB);
}
float minT=1e20,maxT=-1e20;
for (int k=0;k<3;k++) {
float d=axis.dot(vertex[k]);
if (d > maxT)
maxT=d;
if (d < minT)
minT=d;
}
if (maxB<minT || maxT<minB)
return false;
}
}
return true;
}
#endif // FACE3_H

View file

@ -89,11 +89,13 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant& p_iter,uint32_t p_offs
bool err=false;
if (type==TYPE_ARRAY) {
return _get_at_ofs(p_offset+8+pos*4,rd.ptr(),err);
uint32_t vpos = decode_uint32(rd.ptr() + p_offset+8+pos*4);
return _get_at_ofs(vpos,rd.ptr(),err);
} else if (type==TYPE_DICT) {
return _get_at_ofs(p_offset+8+pos*12+8,rd.ptr(),err);
uint32_t vpos = decode_uint32(rd.ptr() + p_offset+8+pos*12+4);
return _get_at_ofs(vpos,rd.ptr(),err);
} else {
ERR_FAIL_V(Variant());
}
@ -127,6 +129,15 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs,const uint8_t *p_buf,boo
}
uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
DVector<uint8_t>::Read rd=data.read();
const uint8_t *r=&rd[p_ofs];
uint32_t type = decode_uint32(r);
return type;
};
int PackedDataContainer::_size(uint32_t p_ofs) const {
DVector<uint8_t>::Read rd=data.read();
@ -408,6 +419,10 @@ Variant PackedDataContainerRef::_iter_get(const Variant& p_iter){
return from->_iter_get_ofs(p_iter,offset);
}
bool PackedDataContainerRef::_is_dictionary() const {
return from->_type_at_ofs(offset) == PackedDataContainer::TYPE_DICT;
};
void PackedDataContainerRef::_bind_methods() {
@ -415,6 +430,7 @@ void PackedDataContainerRef::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_iter_init"),&PackedDataContainerRef::_iter_init);
ObjectTypeDB::bind_method(_MD("_iter_get"),&PackedDataContainerRef::_iter_get);
ObjectTypeDB::bind_method(_MD("_iter_next"),&PackedDataContainerRef::_iter_next);
ObjectTypeDB::bind_method(_MD("_is_dictionary"),&PackedDataContainerRef::_is_dictionary);
}

View file

@ -68,6 +68,7 @@ class PackedDataContainer : public Resource {
friend class PackedDataContainerRef;
Variant _key_at_ofs(uint32_t p_ofs,const Variant& p_key,bool &err) const;
Variant _get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, bool &err) const;
uint32_t _type_at_ofs(uint32_t p_ofs) const;
int _size(uint32_t p_ofs) const;
protected:
@ -100,6 +101,7 @@ public:
Variant _iter_init(const Array& p_iter);
Variant _iter_next(const Array& p_iter);
Variant _iter_get(const Variant& p_iter);
bool _is_dictionary() const;
int size() const;
virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const;

View file

@ -229,8 +229,6 @@ ScriptDebugger::ScriptDebugger() {
}
bool PlaceHolderScriptInstance::set(const StringName& p_name, const Variant& p_value) {
if (values.has(p_name)) {

View file

@ -166,6 +166,7 @@ public:
virtual ~ScriptLanguage() {};
};
extern uint8_t script_encryption_key[32];
class PlaceHolderScriptInstance : public ScriptInstance {

View file

@ -1596,6 +1596,7 @@ bool String::is_numeric() const {
};
#define IS_DIGIT(m_d) ( (m_d)>='0' && (m_d)<='9' )
#define IS_HEX_DIGIT(m_d) ( ( (m_d)>='0' && (m_d)<='9' ) || ( (m_d)>='a' && (m_d)<='f' ) || ( (m_d)>='A' && (m_d)<='F' ) )
template<class C>
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
@ -2891,23 +2892,107 @@ String String::xml_escape(bool p_escape_quotes) const {
return str;
}
static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src,int p_src_len,CharType *p_dst) {
int len=0;
while(p_src_len) {
if (*p_src=='&') {
int eat=0;
if (p_src_len>=4 && p_src[1]=='#') {
CharType c=0;
for(int i=2;i<p_src_len;i++) {
eat=i+1;
CharType ct=p_src[i];
if (ct==';') {
break;
} else if (ct>='0' && ct<='9') {
ct=ct-'0';
} else if (ct>='a' && ct<='f') {
ct=(ct-'a')+10;
} else if (ct>='A' && ct<='F') {
ct=(ct-'A')+10;
} else {
continue;
}
c<<=4;
c|=ct;
}
if (p_dst)
*p_dst=c;
} else if (p_src_len>=4 && p_src[1]=='g' && p_src[2]=='t' && p_src[3]==';') {
if (p_dst)
*p_dst='<';
eat=4;
} else if (p_src_len>=4 && p_src[1]=='l' && p_src[2]=='t' && p_src[3]==';') {
if (p_dst)
*p_dst='>';
eat=4;
} else if (p_src_len>=5 && p_src[1]=='a' && p_src[2]=='m' && p_src[3]=='p' && p_src[4]==';') {
if (p_dst)
*p_dst='&';
eat=5;
} else if (p_src_len>=6 && p_src[1]=='q' && p_src[2]=='u' && p_src[3]=='o' && p_src[4]=='t' && p_src[5]==';') {
if (p_dst)
*p_dst='"';
eat=6;
} else if (p_src_len>=6 && p_src[1]=='a' && p_src[2]=='p' && p_src[3]=='o' && p_src[4]=='s' && p_src[5]==';') {
if (p_dst)
*p_dst='\'';
eat=6;
} else {
if (p_dst)
*p_dst=*p_src;
eat=1;
}
if (p_dst)
p_dst++;
len++;
p_src+=eat;
p_src_len-=eat;
} else {
if (p_dst) {
*p_dst=*p_src;
p_dst++;
}
len++;
p_src++;
p_src_len--;
}
}
return len;
}
String String::xml_unescape() const {
String str=*this;
str=str.strip_edges();
//str=str.replace("\"","");
str=str.replace("&gt;","<");
str=str.replace("&lt;",">");
str=str.replace("&apos;","'");
str=str.replace("&quot;","\"");
/*
for (int i=1;i<32;i++) {
char chr[2]={i,0};
str=str.replace("&#"+String::num(i)+";",chr);
}*/
str=str.replace("&amp;","&");
String str;
int l = length();
int len = _xml_unescape(c_str(),l,NULL);
if (len==0)
return String();
str.resize(len+1);
_xml_unescape(c_str(),l,&str[0]);
str[len]=0;
return str;
}

View file

@ -2907,7 +2907,7 @@ bool Variant::iter_init(Variant& r_iter,bool &valid) const {
ref.push_back(r_iter);
Variant vref=ref;
const Variant *refp[]={&vref};
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next,refp,1,ce);
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init,refp,1,ce);
if (ref.size()!=1 || ce.error!=Variant::CallError::CALL_OK) {
valid=false;

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -1042,8 +1042,8 @@ void RasterizerGLES2::texture_set_size_override(RID p_texture,int p_width, int p
ERR_FAIL_COND(!texture);
ERR_FAIL_COND(texture->render_target);
ERR_FAIL_COND(p_width<=0 || p_width>4096);
ERR_FAIL_COND(p_height<=0 || p_height>4096);
ERR_FAIL_COND(p_width<=0 || p_width>16384);
ERR_FAIL_COND(p_height<=0 || p_height>16384);
//real texture size is in alloc width and height
texture->width=p_width;
texture->height=p_height;
@ -5471,6 +5471,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
const ParamOverrideMap* prev_overrides=NULL; // make it diferent than NULL
const Skeleton *prev_skeleton =NULL;
uint8_t prev_sort_flags=0xFF;
const BakedLightData *prev_baked_light=NULL;
Geometry::Type prev_geometry_type=Geometry::GEOMETRY_INVALID;
@ -5486,6 +5487,9 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false);
material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,false);
// material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_TEXTURE,false);
}
@ -5503,8 +5507,10 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
uint8_t sort_flags= e->sort_flags;
const Skeleton *skeleton = e->skeleton;
const Geometry *geometry_cmp = e->geometry_cmp;
const BakedLightData *baked_light = e->instance->baked_light;
bool rebind=false;
bool bind_baked_light_octree=false;
bool additive=false;
@ -5622,6 +5628,32 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
current_blend_mode=desired_blend_mode;
}
material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,false);
// material_shader.set_conditional(MaterialShaderGLES2::USE_AMBIENT_TEXTURE,false);
if (!additive && baked_light) {
if (baked_light->mode==VS::BAKED_LIGHT_OCTREE && baked_light->octree_texture.is_valid() && e->instance->baked_light_octree_xform) {
material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,true);
bind_baked_light_octree=true;
if (prev_baked_light!=baked_light) {
Texture *tex=texture_owner.get(baked_light->octree_texture);
if (tex) {
glActiveTexture(GL_TEXTURE5);
glBindTexture(tex->target,tex->tex_id); //bind the texture
}
}
} else if (baked_light->mode==VS::BAKED_LIGHT_LIGHTMAPS) {
//material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_TEXTURE,true);
}
}
if (int(prev_baked_light!=NULL) ^ int(baked_light!=NULL)) {
rebind=true;
}
}
if (sort_flags!=prev_sort_flags) {
@ -5672,6 +5704,18 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
}
}
if (bind_baked_light_octree && (baked_light!=prev_baked_light || rebind)) {
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_INVERSE_TRANSFORM, *e->instance->baked_light_octree_xform);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_SIZE, baked_light->octree_lattice_size);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_DIVIDE, baked_light->octree_lattice_divide);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_STEPS, baked_light->octree_steps);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,5);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_PIX_SIZE,baked_light->octree_tex_pixel_size);
}
_set_cull(e->mirror,p_reverse_cull);
@ -5726,6 +5770,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
prev_light=e->light;
prev_light_type=e->light_type;
prev_sort_flags=sort_flags;
prev_baked_light=baked_light;
// prev_geometry_type=geometry->type;
}

View file

@ -93,6 +93,13 @@ varying vec3 tangent_interp;
varying vec3 binormal_interp;
#endif
#ifdef ENABLE_AMBIENT_OCTREE
uniform highp mat4 ambient_octree_inverse_transform;
varying highp vec3 ambient_octree_coords;
#endif
#ifdef USE_FOG
varying vec4 fog_interp;
@ -173,12 +180,19 @@ void main() {
#ifdef USE_UNIFORM_INSTANCING
highp mat4 modelview = (camera_inverse_transform * (world_transform * instance_transform));
#ifdef ENABLE_AMBIENT_OCTREE
highp mat4 ambient_octree_transform = (ambient_octree_inverse_transform * (world_transform * instance_transform));
#endif
#else
#ifdef USE_ATTRIBUTE_INSTANCING
highp mat4 minst=mat4(instance_row0,instance_row1,instance_row2,instance_row3);
highp mat4 modelview = (camera_inverse_transform * (world_transform * minst));
#ifdef ENABLE_AMBIENT_OCTREE
highp mat4 ambient_octree_transform = (ambient_octree_inverse_transform * (world_transform * minst));
#endif
#else
@ -201,9 +215,16 @@ void main() {
);*/
highp mat4 modelview = (camera_inverse_transform * (world_transform * minst));
#ifdef ENABLE_AMBIENT_OCTREE
highp mat4 ambient_octree_transform = (ambient_octree_inverse_transform * (world_transform * minst));
#endif
#else
highp mat4 modelview = (camera_inverse_transform * world_transform);
#ifdef ENABLE_AMBIENT_OCTREE
highp mat4 ambient_octree_transform = (ambient_octree_inverse_transform * world_transform);
#endif
#endif
#endif
@ -233,6 +254,11 @@ void main() {
#endif
#ifdef ENABLE_AMBIENT_OCTREE
ambient_octree_coords = (ambient_octree_transform * vertex_in).xyz;
#endif
vertex_interp = (modelview * vertex_in).xyz;
normal_interp = normalize((modelview * vec4(normal_in,0.0)).xyz);
@ -515,6 +541,16 @@ vec3 process_shade(in vec3 normal, in vec3 light_dir, in vec3 eye_vec, in vec3 d
uniform float const_light_mult;
uniform float time;
#ifdef ENABLE_AMBIENT_OCTREE
varying highp vec3 ambient_octree_coords;
uniform highp float ambient_octree_lattice_size;
uniform highp vec2 ambient_octree_pix_size;
uniform highp float ambient_octree_lattice_divide;
uniform highp sampler2D ambient_octree_tex;
uniform int ambient_octree_steps;
#endif
FRAGMENT_SHADER_GLOBALS
@ -745,10 +781,57 @@ FRAGMENT_SHADER_CODE
}
#endif
#ifdef ENABLE_AMBIENT_OCTREE
vec3 ambientmap_color = vec3(0.0,0.0,0.0);
{
//read position from initial lattice grid
highp vec3 lattice_pos = floor(ambient_octree_coords*ambient_octree_lattice_size);
highp vec2 octant_uv = highp vec2(lattice_pos.x+ambient_octree_lattice_size*lattice_pos.z,lattice_pos.y);
octant_uv=(octant_uv*highp vec2(2.0,4.0)+highp vec2(0.0,4.0));
highp float ld = 1.0/ambient_octree_lattice_size;
//go down the octree
for(int i=0;i<ambient_octree_steps;i++) {
highp vec3 sub=mod(ambient_octree_coords,ld);
ld*=0.5;
highp vec3 s = step(ld,sub);
octant_uv+=s.xy;
octant_uv.y+=s.z*2.0;
octant_uv=(octant_uv+0.5)*ambient_octree_pix_size;
highp vec4 new_uv = texture2D(ambient_octree_tex,octant_uv);
octant_uv=floor(highp vec2( dot(new_uv.xy,highp vec2(65280.0,255.0)), dot(new_uv.zw,highp vec2(65280.0,255.0)) )+0.5);//+ambient_octree_pix_size*0.5;
}
//sample color
octant_uv=(octant_uv+0.5)*ambient_octree_pix_size;
highp vec3 sub=(mod(ambient_octree_coords,ld)/ld);
octant_uv.xy+=sub.xy*ambient_octree_pix_size.xy;
vec3 col_up=texture2D(ambient_octree_tex,octant_uv).rgb;
octant_uv.y+=ambient_octree_pix_size.y*2.0;
vec3 col_down=texture2D(ambient_octree_tex,octant_uv).rgb;
ambientmap_color=mix(col_down,col_up,1.0-sub.z);
ambientmap_color*=diffuse.rgb;
}
#endif
float shadow_attenuation = 1.0;
#ifdef LIGHT_USE_SHADOW
#ifdef LIGHT_TYPE_DIRECTIONAL
@ -921,6 +1004,8 @@ FRAGMENT_SHADER_CODE
#endif
#ifdef USE_VERTEX_LIGHTING
vec3 ambient = light_ambient*diffuse.rgb;
@ -933,11 +1018,13 @@ FRAGMENT_SHADER_CODE
diffuse.rgb=(diffuse.rgb * diffuse_interp.rgb + specular * specular_interp)*shadow_attenuation + ambient;
diffuse.rgb+=emission * const_light_mult;
#endif
#ifdef ENABLE_AMBIENT_OCTREE
diffuse.rgb+=ambientmap_color;
#endif
#ifdef USE_SHADOW_PASS

View file

@ -130,6 +130,8 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
getifaddrs(&ifAddrStruct);
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr)
continue;
if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
// is a valid IP4 Address

View file

@ -31,6 +31,7 @@
#include "global_constants.h"
#include "gd_compiler.h"
#include "os/file_access.h"
#include "io/file_access_encrypted.h"
/* TODO:
@ -1591,7 +1592,28 @@ void GDScript::_bind_methods() {
Error GDScript::load_byte_code(const String& p_path) {
Vector<uint8_t> bytecode = FileAccess::get_file_as_array(p_path);
Vector<uint8_t> bytecode;
if (p_path.ends_with("gde")) {
FileAccess *fa = FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!fa,ERR_CANT_OPEN);
FileAccessEncrypted *fae = memnew( FileAccessEncrypted );
ERR_FAIL_COND_V(!fae,ERR_CANT_OPEN);
Vector<uint8_t> key;
key.resize(32);
for(int i=0;i<key.size();i++) {
key[i]=script_encryption_key[i];
}
Error err = fae->open_and_parse(fa,key,FileAccessEncrypted::MODE_READ);
ERR_FAIL_COND_V(err,err);
bytecode.resize(fae->get_len());
fae->get_buffer(bytecode.ptr(),bytecode.size());
memdelete(fae);
} else {
bytecode = FileAccess::get_file_as_array(p_path);
}
ERR_FAIL_COND_V(bytecode.size()==0,ERR_PARSE_ERROR);
path=p_path;
@ -2225,7 +2247,7 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path,const String& p_orig
Ref<GDScript> scriptres(script);
if (p_path.ends_with(".gdc")) {
if (p_path.ends_with(".gde") || p_path.ends_with(".gdc")) {
script->set_script_path(p_original_path); // script needs this.
script->set_path(p_original_path);
@ -2258,6 +2280,7 @@ void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_ext
p_extensions->push_back("gd");
p_extensions->push_back("gdc");
p_extensions->push_back("gde");
}
bool ResourceFormatLoaderGDScript::handles_type(const String& p_type) const {
@ -2268,7 +2291,7 @@ bool ResourceFormatLoaderGDScript::handles_type(const String& p_type) const {
String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const {
String el = p_path.extension().to_lower();
if (el=="gd" || el=="gdc")
if (el=="gd" || el=="gdc" || el=="gde")
return "GDScript";
return "";
}

View file

@ -757,6 +757,7 @@ void GDTokenizerText::_advance() {
{Variant::_RID,"RID"},
{Variant::OBJECT,"Object"},
{Variant::INPUT_EVENT,"InputEvent"},
{Variant::NODE_PATH,"NodePath"},
{Variant::DICTIONARY,"dict"},
{Variant::DICTIONARY,"Dictionary"},
{Variant::ARRAY,"Array"},

View file

@ -14,6 +14,8 @@
#include "gd_script.h"
#include "io/resource_loader.h"
#include "os/file_access.h"
#include "io/file_access_encrypted.h"
GDScriptLanguage *script_language_gd=NULL;
@ -25,6 +27,7 @@ ResourceFormatSaverGDScript *resource_saver_gd=NULL;
#include "tools/editor/editor_import_export.h"
#include "gd_tokenizer.h"
#include "tools/editor/editor_node.h"
#include "tools/editor/editor_settings.h"
class EditorExportGDScript : public EditorExportPlugin {
@ -34,20 +37,69 @@ public:
virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) {
//compile gdscript to bytecode
if (p_path.ends_with(".gd")) {
Vector<uint8_t> file = FileAccess::get_file_as_array(p_path);
if (file.empty())
return file;
String txt;
txt.parse_utf8((const char*)file.ptr(),file.size());
file = GDTokenizerBuffer::parse_code_string(txt);
if (!file.empty()) {
print_line("PREV: "+p_path);
p_path=p_path.basename()+".gdc";
print_line("NOW: "+p_path);
return file;
}
if (EditorImportExport::get_singleton()->script_get_action()!=EditorImportExport::SCRIPT_ACTION_NONE) {
if (p_path.ends_with(".gd")) {
Vector<uint8_t> file = FileAccess::get_file_as_array(p_path);
if (file.empty())
return file;
String txt;
txt.parse_utf8((const char*)file.ptr(),file.size());
file = GDTokenizerBuffer::parse_code_string(txt);
if (!file.empty()) {
if (EditorImportExport::get_singleton()->script_get_action()==EditorImportExport::SCRIPT_ACTION_ENCRYPT) {
String tmp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/script.gde");
FileAccess *fa = FileAccess::open(tmp_path,FileAccess::WRITE);
String skey=EditorImportExport::get_singleton()->script_get_encryption_key().to_lower();
Vector<uint8_t> key;
key.resize(32);
for(int i=0;i<32;i++) {
int v=0;
if (i*2<skey.length()) {
CharType ct = skey[i*2];
if (ct>='0' && ct<='9')
ct=ct-'0';
else if (ct>='a' && ct<='f')
ct=10+ct-'a';
v|=ct<<4;
}
if (i*2+1<skey.length()) {
CharType ct = skey[i*2+1];
if (ct>='0' && ct<='9')
ct=ct-'0';
else if (ct>='a' && ct<='f')
ct=10+ct-'a';
v|=ct;
}
key[i]=v;
}
FileAccessEncrypted *fae=memnew(FileAccessEncrypted);
Error err = fae->open_and_parse(fa,key,FileAccessEncrypted::MODE_WRITE_AES256);
if (err==OK) {
fae->store_buffer(file.ptr(),file.size());
p_path=p_path.basename()+".gde";
}
memdelete(fae);
file=FileAccess::get_file_as_array(tmp_path);
return file;
} else {
p_path=p_path.basename()+".gdc";
return file;
}
}
}
}
return Vector<uint8_t>();

View file

@ -31,7 +31,9 @@
#include "scene/resources/surface_tool.h"
#include "message_queue.h"
#include "scene/3d/light.h"
#include "scene/3d/baked_light_instance.h"
#include "io/marshalls.h"
#include "scene/scene_string_names.h"
bool GridMap::_set(const StringName& p_name, const Variant& p_value) {
@ -53,6 +55,8 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) {
set_center_z(p_value);
} else if (name=="cell/scale") {
set_cell_scale(p_value);
} else if (name=="lighting/bake") {
set_use_baked_light(p_value);
} else if (name=="theme/bake") {
set_bake(p_value);
/* } else if (name=="cells") {
@ -120,6 +124,7 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) {
g.baked=b;
g.bake_instance=VS::get_singleton()->instance_create();;
VS::get_singleton()->instance_set_base(g.bake_instance,g.baked->get_rid());
VS::get_singleton()->instance_geometry_set_baked_light(g.bake_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID());
}
}
@ -169,6 +174,8 @@ bool GridMap::_get(const StringName& p_name,Variant &r_ret) const {
r_ret= get_center_z();
} else if (name=="cell/scale") {
r_ret= cell_scale;
} else if (name=="lighting/bake") {
r_ret=is_using_baked_light();
} else if (name=="theme/bake") {
r_ret= bake;
} else if (name=="data") {
@ -231,6 +238,7 @@ void GridMap::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::OBJECT, "theme/theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"));
p_list->push_back( PropertyInfo( Variant::BOOL, "theme/bake"));
p_list->push_back( PropertyInfo( Variant::BOOL, "lighting/bake"));
p_list->push_back( PropertyInfo( Variant::REAL, "cell/size",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
p_list->push_back( PropertyInfo( Variant::INT, "cell/octant_size",PROPERTY_HINT_RANGE,"1,1024,1") );
p_list->push_back( PropertyInfo( Variant::BOOL, "cell/center_x") );
@ -428,6 +436,8 @@ void GridMap::set_cell_item(int p_x,int p_y,int p_z, int p_item,int p_rot){
ii.multimesh->set_mesh(ii.mesh);
ii.multimesh_instance = VS::get_singleton()->instance_create();
VS::get_singleton()->instance_set_base(ii.multimesh_instance,ii.multimesh->get_rid());
VS::get_singleton()->instance_geometry_set_baked_light(ii.multimesh_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID());
if (!baked_lock) {
//unbake just in case
@ -863,6 +873,12 @@ void GridMap::_notification(int p_what) {
awaiting_update=false;
last_transform=get_global_transform();
if (use_baked_light) {
_find_baked_light();
}
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@ -883,6 +899,17 @@ void GridMap::_notification(int p_what) {
_octant_exit_world(E->key());
}
if (use_baked_light) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
}
_baked_light_changed();
}
//_queue_dirty_map(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
//_update_dirty_map_callback();
//_update_area_instances();
@ -1028,6 +1055,14 @@ void GridMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_unused_area_id","area"),&GridMap::get_unused_area_id);
ObjectTypeDB::bind_method(_MD("bake_geometry"),&GridMap::bake_geometry);
ObjectTypeDB::bind_method(_MD("_baked_light_changed"),&GridMap::_baked_light_changed);
ObjectTypeDB::bind_method(_MD("set_use_baked_light","use"),&GridMap::set_use_baked_light);
ObjectTypeDB::bind_method(_MD("is_using_baked_light","use"),&GridMap::is_using_baked_light);
ObjectTypeDB::bind_method(_MD("_get_baked_light_meshes"),&GridMap::_get_baked_light_meshes);
ObjectTypeDB::set_method_flags("GridMap","bake_geometry",METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
ObjectTypeDB::bind_method(_MD("clear"),&GridMap::clear);
@ -1496,6 +1531,108 @@ void GridMap::bake_geometry() {
}
void GridMap::_baked_light_changed() {
// if (!baked_light_instance)
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
// else
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
for(Map<OctantKey,Octant*>::Element *E=octant_map.front();E;E=E->next()) {
for(Map<int,Octant::ItemInstances>::Element *F=E->get()->items.front();F;F=F->next()) {
VS::get_singleton()->instance_geometry_set_baked_light(F->get().multimesh_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID());
}
}
}
void GridMap::_find_baked_light() {
Node *n=get_parent();
while(n) {
BakedLightInstance *bl=n->cast_to<BakedLightInstance>();
if (bl) {
baked_light_instance=bl;
baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
_baked_light_changed();
return;
}
n=n->get_parent();
}
_baked_light_changed();
}
Array GridMap::_get_baked_light_meshes() {
if (theme.is_null())
return Array();
Vector3 ofs(cell_size*0.5*int(center_x),cell_size*0.5*int(center_y),cell_size*0.5*int(center_z));
Array meshes;
for (Map<IndexKey,Cell>::Element *E=cell_map.front();E;E=E->next()) {
int id = E->get().item;
if (!theme->has_item(id))
continue;
Ref<Mesh> mesh=theme->get_item_mesh(id);
if (mesh.is_null())
continue;
IndexKey ik=E->key();
Vector3 cellpos = Vector3(ik.x,ik.y,ik.z );
Transform xform;
xform.basis.set_orthogonal_index(E->get().rot);
xform.set_origin( cellpos*cell_size+ofs);
xform.basis.scale(Vector3(cell_scale,cell_scale,cell_scale));
meshes.push_back(xform);
meshes.push_back(mesh);
}
return meshes;
}
void GridMap::set_use_baked_light(bool p_use) {
if (use_baked_light==p_use)
return;
use_baked_light=p_use;
if (is_inside_world()) {
if (!p_use) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
}
_baked_light_changed();
} else {
_find_baked_light();
}
}
}
bool GridMap::is_using_baked_light() const{
return use_baked_light;
}
GridMap::GridMap() {
@ -1516,7 +1653,8 @@ GridMap::GridMap() {
bake=false;
cell_scale=1.0;
baked_light_instance=NULL;
use_baked_light=false;
}

View file

@ -38,6 +38,8 @@
//should scale better with hardware that supports instancing
class BakedLightInstance;
class GridMap : public Spatial {
@ -202,6 +204,14 @@ class GridMap : public Spatial {
void _clear_internal(bool p_keep_areas=false);
BakedLightInstance *baked_light_instance;
bool use_baked_light;
void _find_baked_light();
void _baked_light_changed();
Array _get_baked_light_meshes();
protected:
bool _set(const StringName& p_name, const Variant& p_value);
@ -211,6 +221,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
public:
enum {
@ -262,6 +273,8 @@ public:
void bake_geometry();
void set_use_baked_light(bool p_use);
bool is_using_baked_light() const;
void clear();
GridMap();

View file

@ -30,7 +30,7 @@ def get_flags():
('theora', 'no'),
('tools', 'no'),
('nedmalloc', 'no'),
('vorbis', 'yes'),
('vorbis', 'no'),
('musepack', 'no'),
('squirrel', 'no'),
('squish', 'no'),

View file

@ -1,7 +0,0 @@
#include "baked_light.h"
#include "mesh_instance.h"
BakedLight::BakedLight() {
}

View file

@ -1,15 +0,0 @@
#ifndef BAKED_LIGHT_H
#define BAKED_LIGHT_H
#include "scene/3d/spatial.h"
class BakedLightBaker;
class BakedLight : public Spatial {
OBJ_TYPE(BakedLight,Spatial);
public:
BakedLight();
};
#endif // BAKED_LIGHT_H

View file

@ -0,0 +1,65 @@
#include "baked_light_instance.h"
#include "scene/scene_string_names.h"
RID BakedLightInstance::get_baked_light_instance() const {
if (baked_light.is_null())
return RID();
else
return get_instance();
}
void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) {
baked_light=p_baked_light;
RID base_rid;
if (baked_light.is_valid())
base_rid=baked_light->get_rid();
else
base_rid=RID();
set_base(base_rid);
if (is_inside_world()) {
emit_signal(SceneStringNames::get_singleton()->baked_light_changed);
// for (List<Node*>::Element *E=baked_geometry.front();E;E=E->next()) {
// VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID());
// }
}
}
Ref<BakedLight> BakedLightInstance::get_baked_light() const{
return baked_light;
}
AABB BakedLightInstance::get_aabb() const {
return AABB(Vector3(0,0,0),Vector3(1,1,1));
}
DVector<Face3> BakedLightInstance::get_faces(uint32_t p_usage_flags) const {
return DVector<Face3>();
}
void BakedLightInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_baked_light","baked_light"),&BakedLightInstance::set_baked_light);
ObjectTypeDB::bind_method(_MD("get_baked_light"),&BakedLightInstance::get_baked_light);
ObjectTypeDB::bind_method(_MD("get_baked_light_instance"),&BakedLightInstance::get_baked_light_instance);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"baked_light",PROPERTY_HINT_RESOURCE_TYPE,"BakedLight"),_SCS("set_baked_light"),_SCS("get_baked_light"));
ADD_SIGNAL( MethodInfo("baked_light_changed"));
}
BakedLightInstance::BakedLightInstance() {
}

View file

@ -0,0 +1,33 @@
#ifndef BAKED_LIGHT_INSTANCE_H
#define BAKED_LIGHT_INSTANCE_H
#include "scene/3d/visual_instance.h"
#include "scene/resources/baked_light.h"
class BakedLightBaker;
class BakedLightInstance : public VisualInstance {
OBJ_TYPE(BakedLightInstance,VisualInstance);
Ref<BakedLight> baked_light;
protected:
static void _bind_methods();
public:
RID get_baked_light_instance() const;
void set_baked_light(const Ref<BakedLight>& baked_light);
Ref<BakedLight> get_baked_light() const;
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
BakedLightInstance();
};
#endif // BAKED_LIGHT_H

View file

@ -351,6 +351,17 @@ void Light::set_operator(Operator p_op) {
}
void Light::set_bake_mode(BakeMode p_bake_mode) {
bake_mode=p_bake_mode;
}
Light::BakeMode Light::get_bake_mode() const {
return bake_mode;
}
Light::Operator Light::get_operator() const {
return op;
@ -416,6 +427,18 @@ void Light::approximate_opengl_attenuation(float p_constant, float p_linear, flo
}
void Light::set_enabled(bool p_enabled) {
enabled=p_enabled;
VS::get_singleton()->instance_light_set_enabled(get_instance(),enabled);
}
bool Light::is_enabled() const{
return enabled;
}
void Light::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_parameter","variable","value"), &Light::set_parameter );
@ -428,8 +451,14 @@ void Light::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_projector:Texture"), &Light::get_projector );
ObjectTypeDB::bind_method(_MD("set_operator","operator"), &Light::set_operator );
ObjectTypeDB::bind_method(_MD("get_operator"), &Light::get_operator );
ObjectTypeDB::bind_method(_MD("set_bake_mode","bake_mode"), &Light::set_bake_mode );
ObjectTypeDB::bind_method(_MD("get_bake_mode"), &Light::get_bake_mode );
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"), &Light::set_enabled );
ObjectTypeDB::bind_method(_MD("is_enabled"), &Light::is_enabled );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "params/bake_mode",PROPERTY_HINT_ENUM,"Disabled,Indirect,Full"), _SCS("set_bake_mode"), _SCS("get_bake_mode"));
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/energy", PROPERTY_HINT_EXP_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ENERGY );
/*
if (type == VisualServer::LIGHT_OMNI || type == VisualServer::LIGHT_SPOT) {
@ -490,6 +519,8 @@ Light::Light(VisualServer::LightType p_type) {
op=OPERATOR_ADD;
set_project_shadows( false );
set_base(light);
enabled=true;
bake_mode=BAKE_MODE_DISABLED;
}
@ -563,6 +594,7 @@ DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL )
shadow_param[SHADOW_PARAM_PSSM_SPLIT_WEIGHT]=0.5;
shadow_param[SHADOW_PARAM_PSSM_ZOFFSET_SCALE]=2.0;
}

View file

@ -64,6 +64,14 @@ public:
COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR
};
enum BakeMode {
BAKE_MODE_DISABLED,
BAKE_MODE_INDIRECT,
BAKE_MODE_FULL
};
enum Operator {
@ -78,8 +86,10 @@ private:
Color colors[3];
BakeMode bake_mode;
VisualServer::LightType type;
bool shadows;
bool enabled;
Operator op;
// bind helpers
@ -114,6 +124,12 @@ public:
void set_operator(Operator p_op);
Operator get_operator() const;
void set_bake_mode(BakeMode p_bake_mode);
BakeMode get_bake_mode() const;
void set_enabled(bool p_enabled);
bool is_enabled() const;
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
@ -127,6 +143,7 @@ public:
VARIANT_ENUM_CAST( Light::Parameter );
VARIANT_ENUM_CAST( Light::LightColor );
VARIANT_ENUM_CAST( Light::Operator );
VARIANT_ENUM_CAST( Light::BakeMode);
class DirectionalLight : public Light {

View file

@ -479,6 +479,7 @@ void Sprite3D::set_frame(int p_frame) {
if (frame != p_frame)
frame=p_frame;
_queue_update();
}
int Sprite3D::get_frame() const {

View file

@ -5,9 +5,9 @@
#include "scene/2d/animated_sprite.h"
class SpriteBase3D : public VisualInstance {
class SpriteBase3D : public GeometryInstance {
OBJ_TYPE(SpriteBase3D,VisualInstance);
OBJ_TYPE(SpriteBase3D,GeometryInstance);
public:
enum DrawFlags {

View file

@ -31,7 +31,7 @@
#include "servers/visual_server.h"
#include "room_instance.h"
#include "scene/scene_string_names.h"
#include "baked_light_instance.h"
#include "skeleton.h"
AABB VisualInstance::get_transformed_aabb() const {
@ -186,6 +186,61 @@ float GeometryInstance::get_draw_range_end() const {
return draw_end;
}
void GeometryInstance::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_WORLD) {
if (flags[FLAG_USE_BAKED_LIGHT]) {
_find_baked_light();
}
} else if (p_what==NOTIFICATION_EXIT_WORLD) {
if (flags[FLAG_USE_BAKED_LIGHT]) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
}
_baked_light_changed();
}
}
}
void GeometryInstance::_baked_light_changed() {
if (!baked_light_instance)
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
else
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
}
void GeometryInstance::_find_baked_light() {
Node *n=get_parent();
while(n) {
BakedLightInstance *bl=n->cast_to<BakedLightInstance>();
if (bl) {
baked_light_instance=bl;
baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
_baked_light_changed();
return;
}
n=n->get_parent();
}
_baked_light_changed();
}
void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
ERR_FAIL_INDEX(p_flag,FLAG_MAX);
@ -198,8 +253,20 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
_change_notify("geometry/visible");
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
}
if (p_flag==FLAG_USE_BAKED_LIGHT) {
if (is_inside_world()) {
if (!p_value) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
}
_baked_light_changed();
} else {
_find_baked_light();
}
}
}
}
bool GeometryInstance::get_flag(Flags p_flag) const{
@ -224,6 +291,8 @@ void GeometryInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_draw_range_end","mode"), &GeometryInstance::set_draw_range_end);
ObjectTypeDB::bind_method(_MD("get_draw_range_end"), &GeometryInstance::get_draw_range_end);
ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override"));
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/cast_shadow"), _SCS("set_flag"), _SCS("get_flag"),FLAG_CAST_SHADOW);
@ -234,6 +303,7 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE_IN_ALL_ROOMS);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"),FLAG_USE_BAKED_LIGHT);
ADD_SIGNAL( MethodInfo("visibility_changed"));
@ -258,5 +328,7 @@ GeometryInstance::GeometryInstance() {
flags[FLAG_BILLBOARD_FIX_Y]=false;
flags[FLAG_DEPH_SCALE]=false;
flags[FLAG_VISIBLE_IN_ALL_ROOMS]=false;
baked_light_instance=NULL;
}

View file

@ -78,6 +78,8 @@ public:
};
class BakedLightInstance;
class GeometryInstance : public VisualInstance {
OBJ_TYPE( GeometryInstance, VisualInstance );
@ -91,7 +93,7 @@ public:
FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE,
FLAG_VISIBLE_IN_ALL_ROOMS=VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
FLAG_USE_BAKED_LIGHT_VOLUME=VS::INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME,
FLAG_USE_BAKED_LIGHT=VS::INSTANCE_FLAG_USE_BAKED_LIGHT,
FLAG_MAX=VS::INSTANCE_FLAG_MAX,
};
@ -102,8 +104,13 @@ private:
Ref<Material> material_override;
float draw_begin;
float draw_end;
void _find_baked_light();
BakedLightInstance *baked_light_instance;
void _baked_light_changed();
protected:
void _notification(int p_what);
static void _bind_methods();
public:

View file

@ -187,7 +187,7 @@
#include "scene/3d/area.h"
#include "scene/3d/physics_joint.h"
#include "scene/3d/multimesh_instance.h"
#include "scene/3d/baked_light.h"
#include "scene/3d/baked_light_instance.h"
#include "scene/3d/ray_cast.h"
#include "scene/3d/immediate_geometry.h"
#include "scene/3d/sprite_3d.h"
@ -407,7 +407,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PathFollow>();
ObjectTypeDB::register_type<VisibilityNotifier>();
ObjectTypeDB::register_type<VisibilityEnabler>();
ObjectTypeDB::register_type<BakedLight>();
ObjectTypeDB::register_type<BakedLightInstance>();
ObjectTypeDB::register_type<WorldEnvironment>();
//scenariofx
@ -515,6 +515,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<SurfaceTool>();
ObjectTypeDB::register_type<MeshDataTool>();
ObjectTypeDB::register_type<BakedLight>();
OS::get_singleton()->yield(); //may take time to init

View file

@ -0,0 +1,308 @@
#include "baked_light.h"
#include "servers/visual_server.h"
void BakedLight::set_mode(Mode p_mode) {
mode=p_mode;
VS::get_singleton()->baked_light_set_mode(baked_light,(VS::BakedLightMode(p_mode)));
}
BakedLight::Mode BakedLight::get_mode() const{
return mode;
}
void BakedLight::set_octree(const DVector<uint8_t>& p_octree) {
VS::get_singleton()->baked_light_set_octree(baked_light,p_octree);
}
DVector<uint8_t> BakedLight::get_octree() const {
return VS::get_singleton()->baked_light_get_octree(baked_light);
}
void BakedLight::_update_lightmaps() {
VS::get_singleton()->baked_light_clear_lightmaps(baked_light);
for(Map<int,Ref<Texture> >::Element *E=lightmaps.front();E;E=E->next()) {
VS::get_singleton()->baked_light_add_lightmap(baked_light,E->get()->get_rid(),E->key());
}
}
void BakedLight::add_lightmap(const Ref<Texture> p_texture,int p_id) {
ERR_FAIL_COND(!p_texture.is_valid());
ERR_FAIL_COND(p_id<0);
lightmaps[p_id]=p_texture;
VS::get_singleton()->baked_light_add_lightmap(baked_light,p_texture->get_rid(),p_id);
}
void BakedLight::erase_lightmap(int p_id) {
ERR_FAIL_COND(!lightmaps.has(p_id));
lightmaps.erase(p_id);
_update_lightmaps();
}
void BakedLight::get_lightmaps(List<int> *r_lightmaps) {
for(Map<int,Ref<Texture> >::Element *E=lightmaps.front();E;E=E->next()) {
r_lightmaps->push_back(E->key());
}
}
Ref<Texture> BakedLight::get_lightmap_texture(int p_id) {
if (!lightmaps.has(p_id))
return Ref<Texture>();
return lightmaps[p_id];
}
void BakedLight::clear_lightmaps() {
lightmaps.clear();
_update_lightmaps();
}
RID BakedLight::get_rid() const {
return baked_light;
}
Array BakedLight::_get_lightmap_data() const {
Array ret;
ret.resize(lightmaps.size()*2);
int idx=0;
for(Map<int,Ref<Texture> >::Element *E=lightmaps.front();E;E=E->next()) {
ret[idx++]=E->key();
ret[idx++]=E->get();
}
return ret;
}
void BakedLight::_set_lightmap_data(Array p_array){
lightmaps.clear();
for(int i=0;i<p_array.size();i+=2) {
int id = p_array[i];
Ref<Texture> tex = p_array[i+1];
ERR_CONTINUE(id<0);
ERR_CONTINUE(tex.is_null());
lightmaps[id]=tex;
}
_update_lightmaps();
}
void BakedLight::set_cell_subdivision(int p_subdiv) {
cell_subdiv=p_subdiv;
}
int BakedLight::get_cell_subdivision() const{
return cell_subdiv;
}
void BakedLight::set_initial_lattice_subdiv(int p_size){
lattice_subdiv=p_size;
}
int BakedLight::get_initial_lattice_subdiv() const{
return lattice_subdiv;
}
void BakedLight::set_plot_size(float p_size){
plot_size=p_size;
}
float BakedLight::get_plot_size() const{
return plot_size;
}
void BakedLight::set_bounces(int p_size){
bounces=p_size;
}
int BakedLight::get_bounces() const{
return bounces;
}
void BakedLight::set_cell_extra_margin(float p_margin) {
cell_extra_margin=p_margin;
}
float BakedLight::get_cell_extra_margin() const {
return cell_extra_margin;
}
void BakedLight::set_edge_damp(float p_margin) {
edge_damp=p_margin;
}
float BakedLight::get_edge_damp() const {
return edge_damp;
}
void BakedLight::set_normal_damp(float p_margin) {
normal_damp=p_margin;
}
float BakedLight::get_normal_damp() const {
return normal_damp;
}
void BakedLight::set_energy_multiplier(float p_multiplier){
energy_multiply=p_multiplier;
}
float BakedLight::get_energy_multiplier() const{
return energy_multiply;
}
void BakedLight::set_gamma_adjust(float p_adjust){
gamma_adjust=p_adjust;
}
float BakedLight::get_gamma_adjust() const{
return gamma_adjust;
}
void BakedLight::set_bake_flag(BakeFlags p_flags,bool p_enable){
flags[p_flags]=p_enable;
}
bool BakedLight::get_bake_flag(BakeFlags p_flags) const{
return flags[p_flags];
}
void BakedLight::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_mode","mode"),&BakedLight::set_mode);
ObjectTypeDB::bind_method(_MD("get_mode"),&BakedLight::get_mode);
ObjectTypeDB::bind_method(_MD("set_octree","octree"),&BakedLight::set_octree);
ObjectTypeDB::bind_method(_MD("get_octree"),&BakedLight::get_octree);
ObjectTypeDB::bind_method(_MD("add_lightmap","texture:Texture","id"),&BakedLight::add_lightmap);
ObjectTypeDB::bind_method(_MD("erase_lightmap","id"),&BakedLight::erase_lightmap);
ObjectTypeDB::bind_method(_MD("clear_lightmaps"),&BakedLight::clear_lightmaps);
ObjectTypeDB::bind_method(_MD("_set_lightmap_data","lightmap_data"),&BakedLight::_set_lightmap_data);
ObjectTypeDB::bind_method(_MD("_get_lightmap_data"),&BakedLight::_get_lightmap_data);
ObjectTypeDB::bind_method(_MD("set_cell_subdivision","cell_subdivision"),&BakedLight::set_cell_subdivision);
ObjectTypeDB::bind_method(_MD("get_cell_subdivision"),&BakedLight::get_cell_subdivision);
ObjectTypeDB::bind_method(_MD("set_initial_lattice_subdiv","cell_subdivision"),&BakedLight::set_initial_lattice_subdiv);
ObjectTypeDB::bind_method(_MD("get_initial_lattice_subdiv","cell_subdivision"),&BakedLight::get_initial_lattice_subdiv);
ObjectTypeDB::bind_method(_MD("set_plot_size","plot_size"),&BakedLight::set_plot_size);
ObjectTypeDB::bind_method(_MD("get_plot_size"),&BakedLight::get_plot_size);
ObjectTypeDB::bind_method(_MD("set_bounces","bounces"),&BakedLight::set_bounces);
ObjectTypeDB::bind_method(_MD("get_bounces"),&BakedLight::get_bounces);
ObjectTypeDB::bind_method(_MD("set_cell_extra_margin","cell_extra_margin"),&BakedLight::set_cell_extra_margin);
ObjectTypeDB::bind_method(_MD("get_cell_extra_margin"),&BakedLight::get_cell_extra_margin);
ObjectTypeDB::bind_method(_MD("set_edge_damp","edge_damp"),&BakedLight::set_edge_damp);
ObjectTypeDB::bind_method(_MD("get_edge_damp"),&BakedLight::get_edge_damp);
ObjectTypeDB::bind_method(_MD("set_normal_damp","normal_damp"),&BakedLight::set_normal_damp);
ObjectTypeDB::bind_method(_MD("get_normal_damp"),&BakedLight::get_normal_damp);
ObjectTypeDB::bind_method(_MD("set_energy_multiplier","energy_multiplier"),&BakedLight::set_energy_multiplier);
ObjectTypeDB::bind_method(_MD("get_energy_multiplier"),&BakedLight::get_energy_multiplier);
ObjectTypeDB::bind_method(_MD("set_gamma_adjust","gamma_adjust"),&BakedLight::set_gamma_adjust);
ObjectTypeDB::bind_method(_MD("get_gamma_adjust"),&BakedLight::get_gamma_adjust);
ObjectTypeDB::bind_method(_MD("set_bake_flag","flag","enabled"),&BakedLight::set_bake_flag);
ObjectTypeDB::bind_method(_MD("get_bake_flag","flag"),&BakedLight::get_bake_flag);
ADD_PROPERTY( PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Octree,Lightmaps"),_SCS("set_mode"),_SCS("get_mode"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/cell_subdiv",PROPERTY_HINT_RANGE,"4,14,1"),_SCS("set_cell_subdivision"),_SCS("get_cell_subdivision"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/lattice_subdiv",PROPERTY_HINT_RANGE,"1,5,1"),_SCS("set_initial_lattice_subdiv"),_SCS("get_initial_lattice_subdiv"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/light_bounces",PROPERTY_HINT_RANGE,"0,3,1"),_SCS("set_bounces"),_SCS("get_bounces"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/plot_size",PROPERTY_HINT_RANGE,"1.0,16.0,0.01"),_SCS("set_plot_size"),_SCS("get_plot_size"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/energy_mult",PROPERTY_HINT_RANGE,"0.01,4096.0,0.01"),_SCS("set_energy_multiplier"),_SCS("get_energy_multiplier"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/gamma_adjust",PROPERTY_HINT_EXP_EASING),_SCS("set_gamma_adjust"),_SCS("get_gamma_adjust"));
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/diffuse"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_DIFFUSE);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/specular"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_SPECULAR);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/translucent"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_TRANSLUCENT);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/conserve_energy"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_CONSERVE_ENERGY);
ADD_PROPERTY( PropertyInfo(Variant::RAW_ARRAY,"octree",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_octree"),_SCS("get_octree"));
ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"lightmaps",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_lightmap_data"),_SCS("_get_lightmap_data"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/cell_margin",PROPERTY_HINT_RANGE,"0.01,0.8,0.01"),_SCS("set_cell_extra_margin"),_SCS("get_cell_extra_margin"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/edge_damp",PROPERTY_HINT_RANGE,"0.0,8.0,0.1"),_SCS("set_edge_damp"),_SCS("get_edge_damp"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/normal_damp",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_normal_damp"),_SCS("get_normal_damp"));
BIND_CONSTANT( MODE_OCTREE );
BIND_CONSTANT( MODE_LIGHTMAPS );
BIND_CONSTANT( BAKE_DIFFUSE );
BIND_CONSTANT( BAKE_SPECULAR );
BIND_CONSTANT( BAKE_TRANSLUCENT );
BIND_CONSTANT( BAKE_CONSERVE_ENERGY );
BIND_CONSTANT( BAKE_MAX );
}
BakedLight::BakedLight() {
cell_subdiv=8;
lattice_subdiv=4;
plot_size=2.5;
bounces=1;
energy_multiply=1.0;
gamma_adjust=1.0;
cell_extra_margin=0.05;
edge_damp=0.0;
normal_damp=0.0;
flags[BAKE_DIFFUSE]=true;
flags[BAKE_SPECULAR]=false;
flags[BAKE_TRANSLUCENT]=true;
flags[BAKE_CONSERVE_ENERGY]=false;
mode=MODE_OCTREE;
baked_light=VS::get_singleton()->baked_light_create();
}
BakedLight::~BakedLight() {
VS::get_singleton()->free(baked_light);
}

View file

@ -0,0 +1,106 @@
#ifndef BAKED_LIGHT_H
#define BAKED_LIGHT_H
#include "resource.h"
#include "scene/resources/texture.h"
class BakedLight : public Resource {
OBJ_TYPE( BakedLight, Resource);
public:
enum Mode {
MODE_OCTREE,
MODE_LIGHTMAPS
};
enum BakeFlags {
BAKE_DIFFUSE,
BAKE_SPECULAR,
BAKE_TRANSLUCENT,
BAKE_CONSERVE_ENERGY,
BAKE_MAX
};
private:
RID baked_light;
Mode mode;
Map<int,Ref<Texture> > lightmaps;
//bake vars
int cell_subdiv;
int lattice_subdiv;
float plot_size;
float energy_multiply;
float gamma_adjust;
float cell_extra_margin;
float edge_damp;
float normal_damp;
int bounces;
bool flags[BAKE_MAX];
void _update_lightmaps();
Array _get_lightmap_data() const;
void _set_lightmap_data(Array p_array);
static void _bind_methods();
public:
void set_cell_subdivision(int p_subdiv);
int get_cell_subdivision() const;
void set_initial_lattice_subdiv(int p_size);
int get_initial_lattice_subdiv() const;
void set_plot_size(float p_size);
float get_plot_size() const;
void set_bounces(int p_size);
int get_bounces() const;
void set_energy_multiplier(float p_multiplier);
float get_energy_multiplier() const;
void set_gamma_adjust(float p_adjust);
float get_gamma_adjust() const;
void set_cell_extra_margin(float p_margin);
float get_cell_extra_margin() const;
void set_edge_damp(float p_margin);
float get_edge_damp() const;
void set_normal_damp(float p_margin);
float get_normal_damp() const;
void set_bake_flag(BakeFlags p_flags,bool p_enable);
bool get_bake_flag(BakeFlags p_flags) const;
void set_mode(Mode p_mode);
Mode get_mode() const;
void set_octree(const DVector<uint8_t>& p_octree);
DVector<uint8_t> get_octree() const;
void add_lightmap(const Ref<Texture> p_texture,int p_id);
void erase_lightmap(int p_id);
void get_lightmaps(List<int> *r_lightmaps);
Ref<Texture> get_lightmap_texture(int p_id);
void clear_lightmaps();
virtual RID get_rid() const;
BakedLight();
~BakedLight();
};
VARIANT_ENUM_CAST(BakedLight::Mode);
VARIANT_ENUM_CAST(BakedLight::BakeFlags);
#endif // BAKED_LIGHT_H

View file

@ -140,4 +140,8 @@ SceneStringNames::SceneStringNames() {
_im_update = StaticCString::create("_im_update");
_queue_update = StaticCString::create("_queue_update");
baked_light_changed = StaticCString::create("baked_light_changed");
_baked_light_changed = StaticCString::create("_baked_light_changed");
}

View file

@ -148,6 +148,9 @@ public:
StringName _im_update;
StringName _queue_update;
StringName baked_light_changed;
StringName _baked_light_changed;
};

View file

@ -302,6 +302,11 @@ public:
virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible)=0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const=0;
/* BAKED LIGHT */
/* IMMEDIATE API */
virtual RID immediate_create()=0;
@ -490,6 +495,20 @@ public:
typedef Map<StringName,Variant> ParamOverrideMap;
struct BakedLightData {
VS::BakedLightMode mode;
RID octree_texture;
float color_multiplier; //used for both lightmaps and octree
Transform octree_transform;
Map<int,RID> lightmaps;
//cache
float octree_lattice_size;
float octree_lattice_divide;
int octree_steps;
Vector2 octree_tex_pixel_size;
};
struct InstanceData {
@ -498,6 +517,8 @@ public:
RID material_override;
Vector<RID> light_instances;
Vector<float> morph_values;
BakedLightData *baked_light;
Transform *baked_light_octree_xform;
bool mirror :8;
bool depth_scale :8;
bool billboard :8;

View file

@ -31,6 +31,7 @@
#include "globals.h"
#include "default_mouse_cursor.xpm"
#include "sort.h"
#include "io/marshalls.h"
// careful, these may run in different threads than the visual server
BalloonAllocator<> *VisualServerRaster::OctreeAllocator::allocator=NULL;
@ -921,6 +922,7 @@ void VisualServerRaster::room_set_bounds(RID p_room, const BSP_Tree& p_bounds) {
Room *room = room_owner.get(p_room);
ERR_FAIL_COND(!room);
room->bounds=p_bounds;
_dependency_queue_update(p_room,true);
}
@ -1032,6 +1034,138 @@ float VisualServerRaster::portal_get_connect_range(RID p_portal) const {
}
RID VisualServerRaster::baked_light_create() {
BakedLight *baked_light = memnew( BakedLight );
ERR_FAIL_COND_V(!baked_light,RID());
baked_light->data.mode=BAKED_LIGHT_OCTREE;
baked_light->data.octree_lattice_size=0;
baked_light->data.octree_lattice_divide=0;
baked_light->data.octree_steps=1;
return baked_light_owner.make_rid( baked_light );
}
void VisualServerRaster::baked_light_set_mode(RID p_baked_light,BakedLightMode p_mode){
VS_CHANGED;
BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND(!baked_light);
baked_light->data.mode=p_mode;
baked_light->data.color_multiplier=1.0;
_dependency_queue_update(p_baked_light,true);
}
VisualServer::BakedLightMode VisualServerRaster::baked_light_get_mode(RID p_baked_light) const{
const BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND_V(!baked_light,BAKED_LIGHT_OCTREE);
return baked_light->data.mode;
}
void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree){
VS_CHANGED;
BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND(!baked_light);
if (p_octree.size()==0) {
if (baked_light->data.octree_texture.is_valid())
rasterizer->free(baked_light->data.octree_texture);
baked_light->data.octree_texture=RID();
baked_light->octree_aabb=AABB();
baked_light->octree_tex_size=Size2();
} else {
int tex_w;
int tex_h;
bool is16;
{
DVector<uint8_t>::Read r=p_octree.read();
tex_w = decode_uint32(&r[0]);
tex_h = decode_uint32(&r[4]);
print_line("TEX W: "+itos(tex_w)+" TEX H:"+itos(tex_h)+" LEN: "+itos(p_octree.size()));
is16=decode_uint32(&r[8]);
baked_light->data.octree_lattice_size=decode_float(&r[12]);
baked_light->data.octree_lattice_divide=tex_w/4.0;
print_line("LATTICE SIZE: "+rtos(baked_light->data.octree_lattice_size));
print_line("LATTICE DIVIDE: "+rtos(baked_light->data.octree_lattice_divide));
baked_light->data.octree_steps=decode_uint32(&r[16]);
baked_light->data.octree_tex_pixel_size.x=1.0/tex_w;
baked_light->data.octree_tex_pixel_size.y=1.0/tex_h;
baked_light->octree_aabb.pos.x=decode_float(&r[32]);
baked_light->octree_aabb.pos.y=decode_float(&r[36]);
baked_light->octree_aabb.pos.z=decode_float(&r[40]);
baked_light->octree_aabb.size.x=decode_float(&r[44]);
baked_light->octree_aabb.size.y=decode_float(&r[48]);
baked_light->octree_aabb.size.z=decode_float(&r[52]);
}
if (baked_light->data.octree_texture.is_valid()) {
if (tex_w!=baked_light->octree_tex_size.x || tex_h!=baked_light->octree_tex_size.y) {
rasterizer->free(baked_light->data.octree_texture);
baked_light->data.octree_texture=RID();
}
}
if (!baked_light->data.octree_texture.is_valid()) {
baked_light->data.octree_texture=rasterizer->texture_create();
rasterizer->texture_allocate(baked_light->data.octree_texture,tex_w,tex_h,Image::FORMAT_RGBA,TEXTURE_FLAG_FILTER);
}
Image img(tex_w,tex_h,0,Image::FORMAT_RGBA,p_octree);
rasterizer->texture_set_data(baked_light->data.octree_texture,img);
}
_dependency_queue_update(p_baked_light,true);
}
DVector<uint8_t> VisualServerRaster::baked_light_get_octree(RID p_baked_light) const{
BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND_V(!baked_light,DVector<uint8_t>());
if (rasterizer->is_texture(baked_light->data.octree_texture)) {
Image img = rasterizer->texture_get_data(baked_light->data.octree_texture);
return img.get_data();
} else {
return DVector<uint8_t>();
}
}
void VisualServerRaster::baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id){
VS_CHANGED;
BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND(!baked_light);
baked_light->data.lightmaps.insert(p_id,p_texture);
}
void VisualServerRaster::baked_light_clear_lightmaps(RID p_baked_light){
VS_CHANGED;
BakedLight *baked_light = baked_light_owner.get(p_baked_light);
ERR_FAIL_COND(!baked_light);
baked_light->data.lightmaps.clear();
}
/* CAMERA API */
RID VisualServerRaster::camera_create() {
@ -1710,6 +1844,23 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) {
}
if (instance->baked_light_info) {
while(instance->baked_light_info->owned_instances.size()) {
Instance *owned=instance->baked_light_info->owned_instances.front()->get();
owned->baked_light=NULL;
owned->data.baked_light=NULL;
owned->data.baked_light_octree_xform=NULL;
owned->BLE=NULL;
instance->baked_light_info->owned_instances.pop_front();
}
memdelete(instance->baked_light_info);
instance->baked_light_info=NULL;
}
if (instance->scenario && instance->octree_id) {
instance->scenario->octree.erase( instance->octree_id );
instance->octree_id=0;
@ -1796,6 +1947,14 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) {
instance->base_type=INSTANCE_PORTAL;
instance->portal_info = memnew(Instance::PortalInfo);
instance->portal_info->portal=portal_owner.get(p_base);
} else if (baked_light_owner.owns(p_base)) {
instance->base_type=INSTANCE_BAKED_LIGHT;
instance->baked_light_info=memnew(Instance::BakedLightInfo);
instance->baked_light_info->baked_light=baked_light_owner.get(p_base);
//instance->portal_info = memnew(Instance::PortalInfo);
//instance->portal_info->portal=portal_owner.get(p_base);
} else {
ERR_EXPLAIN("Invalid base RID for instance!")
ERR_FAIL();
@ -2365,6 +2524,68 @@ float VisualServerRaster::instance_geometry_get_draw_range_max(RID p_instance) c
}
void VisualServerRaster::instance_geometry_set_baked_light(RID p_instance,RID p_baked_light) {
VS_CHANGED;
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
if (instance->baked_light) {
instance->baked_light->baked_light_info->owned_instances.erase(instance->BLE);
instance->BLE=NULL;
instance->baked_light=NULL;
instance->data.baked_light=NULL;
instance->data.baked_light_octree_xform=NULL;
}
if (!p_baked_light.is_valid())
return;
Instance *bl_instance = instance_owner.get( p_baked_light );
ERR_FAIL_COND( !bl_instance );
ERR_FAIL_COND( bl_instance->base_type!=INSTANCE_BAKED_LIGHT );
instance->baked_light=bl_instance;
instance->BLE=bl_instance->baked_light_info->owned_instances.push_back(instance);
instance->data.baked_light=&bl_instance->baked_light_info->baked_light->data;
instance->data.baked_light_octree_xform=&bl_instance->baked_light_info->affine_inverse;
}
RID VisualServerRaster::instance_geometry_get_baked_light(RID p_instance) const{
const Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance,RID() );
if (instance->baked_light)
instance->baked_light->self;
return RID();
}
void VisualServerRaster::instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id){
VS_CHANGED;
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
instance->lightmap_texture_index=p_tex_id;
}
int VisualServerRaster::instance_geometry_get_baked_light_texture_index(RID p_instance) const{
const Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance,0 );
return instance->lightmap_texture_index;
}
void VisualServerRaster::_update_instance(Instance *p_instance) {
p_instance->version++;
@ -2385,7 +2606,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
}
if (p_instance->base_type&INSTANCE_GEOMETRY_MASK) {
if ((1<<p_instance->base_type)&INSTANCE_GEOMETRY_MASK) {
//make sure lights are updated
InstanceSet::Element *E=p_instance->lights.front();
@ -2395,13 +2616,20 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
E=E->next();
}
}
if (p_instance->base_type == INSTANCE_ROOM) {
} else if (p_instance->base_type == INSTANCE_ROOM) {
p_instance->room_info->affine_inverse=p_instance->data.transform.affine_inverse();
} else if (p_instance->base_type == INSTANCE_BAKED_LIGHT) {
Transform scale;
scale.basis.scale(p_instance->baked_light_info->baked_light->octree_aabb.size);
scale.origin=p_instance->baked_light_info->baked_light->octree_aabb.pos;
//print_line("scale: "+scale);
p_instance->baked_light_info->affine_inverse=(p_instance->data.transform*scale).affine_inverse();
}
p_instance->data.mirror = p_instance->data.transform.basis.determinant() < 0.0;
AABB new_aabb;
@ -2463,7 +2691,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
if (p_instance->base_type == INSTANCE_LIGHT) {
pairable_mask=INSTANCE_GEOMETRY_MASK;
pairable_mask=p_instance->light_info->enabled?INSTANCE_GEOMETRY_MASK:0;
pairable=true;
}
@ -2578,6 +2806,13 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) {
}
} break;
case VisualServer::INSTANCE_BAKED_LIGHT: {
BakedLight *baked_light = baked_light_owner.get( p_instance->base_rid );
ERR_FAIL_COND(!baked_light);
new_aabb=baked_light->octree_aabb;
} break;
default: {}
}
@ -2607,6 +2842,33 @@ void VisualServerRaster::_update_instances() {
}
}
void VisualServerRaster::instance_light_set_enabled(RID p_instance,bool p_enabled) {
VS_CHANGED;
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
ERR_FAIL_COND( instance->base_type!=INSTANCE_LIGHT );
if (p_enabled==instance->light_info->enabled)
return;
instance->light_info->enabled=p_enabled;
if (light_get_type(instance->base_rid)!=VS::LIGHT_DIRECTIONAL && instance->octree_id && instance->scenario)
instance->scenario->octree.set_pairable(instance->octree_id,p_enabled,1<<INSTANCE_LIGHT,p_enabled?INSTANCE_GEOMETRY_MASK:0);
//_instance_queue_update( instance , true );
}
bool VisualServerRaster::instance_light_is_enabled(RID p_instance) const {
const Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance,false );
ERR_FAIL_COND_V( instance->base_type!=INSTANCE_LIGHT,false );
return instance->light_info->enabled;
}
/****** CANVAS *********/
RID VisualServerRaster::canvas_create() {
@ -3330,6 +3592,13 @@ void VisualServerRaster::black_bars_set_margins(int p_left, int p_top, int p_rig
black_margin[MARGIN_BOTTOM]=p_bottom;
}
void VisualServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) {
black_image[MARGIN_LEFT]=p_left;
black_image[MARGIN_TOP]=p_top;
black_image[MARGIN_RIGHT]=p_right;
black_image[MARGIN_BOTTOM]=p_bottom;
}
void VisualServerRaster::_free_attached_instances(RID p_rid,bool p_free_scenario) {
@ -3414,6 +3683,17 @@ void VisualServerRaster::free( RID p_rid ) {
portal_owner.free(p_rid);
memdelete(portal);
} else if (baked_light_owner.owns(p_rid)) {
_free_attached_instances(p_rid);
BakedLight *baked_light = baked_light_owner.get(p_rid);
ERR_FAIL_COND(!baked_light);
if (baked_light->data.octree_texture.is_valid())
rasterizer->free(baked_light->data.octree_texture);
baked_light_owner.free(p_rid);
memdelete(baked_light);
} else if (camera_owner.owns(p_rid)) {
// delete te camera
@ -3464,8 +3744,9 @@ void VisualServerRaster::free( RID p_rid ) {
instance_set_room(p_rid,RID());
instance_set_scenario(p_rid,RID());
instance_geometry_set_baked_light(p_rid,RID());
instance_set_base(p_rid,RID());
instance_owner.free(p_rid);
memdelete(instance);
@ -5101,7 +5382,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
Instance *light = E->get().is_valid()?instance_owner.get(E->get()):NULL;
if (rasterizer->light_has_shadow(light->base_rid)) {
if (light && light->light_info->enabled && rasterizer->light_has_shadow(light->base_rid)) {
//rasterizer->light_instance_set_active_hint(light->light_info->instance);
_light_instance_update_shadow(light,p_scenario,p_camera,cull_range);
}
@ -5190,6 +5471,9 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
Instance *light = E->get().is_valid()?instance_owner.get(E->get()):NULL;
ERR_CONTINUE(!light);
if (!light->light_info->enabled)
continue;
rasterizer->add_light(light->light_info->instance);
light->light_info->last_add_pass=render_pass;
}
@ -5694,9 +5978,16 @@ void VisualServerRaster::_draw_cursors_and_margins() {
rasterizer->canvas_draw_rect(Rect2(cursors[i].pos, size), 0, Rect2(), tex, Color(1, 1, 1, 1));
};
if (black_margin[MARGIN_LEFT])
if (black_image[MARGIN_LEFT].is_valid()) {
Size2 sz(rasterizer->texture_get_width(black_image[MARGIN_LEFT]),rasterizer->texture_get_height(black_image[MARGIN_LEFT]));
rasterizer->canvas_draw_rect(Rect2(0,0,black_margin[MARGIN_LEFT],window_h),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_LEFT],Color(1,1,1));
} else if (black_margin[MARGIN_LEFT])
rasterizer->canvas_draw_rect(Rect2(0,0,black_margin[MARGIN_LEFT],window_h),0,Rect2(0,0,1,1),RID(),Color(0,0,0));
if (black_margin[MARGIN_RIGHT])
if (black_image[MARGIN_RIGHT].is_valid()) {
Size2 sz(rasterizer->texture_get_width(black_image[MARGIN_RIGHT]),rasterizer->texture_get_height(black_image[MARGIN_RIGHT]));
rasterizer->canvas_draw_rect(Rect2(window_w-black_margin[MARGIN_RIGHT],0,black_margin[MARGIN_RIGHT],window_h),0,Rect2(0,0,sz.x,sz.y),black_image[MARGIN_RIGHT],Color(1,1,1));
} else if (black_margin[MARGIN_RIGHT])
rasterizer->canvas_draw_rect(Rect2(window_w-black_margin[MARGIN_RIGHT],0,black_margin[MARGIN_RIGHT],window_h),0,Rect2(0,0,1,1),RID(),Color(0,0,0));
if (black_margin[MARGIN_TOP])
rasterizer->canvas_draw_rect(Rect2(0,0,window_w,black_margin[MARGIN_TOP]),0,Rect2(0,0,1,1),RID(),Color(0,0,0));

View file

@ -87,6 +87,14 @@ class VisualServerRaster : public VisualServer {
Portal() { enabled=true; disable_distance=50; disable_color=Color(); connect_range=0.8; }
};
struct BakedLight {
Rasterizer::BakedLightData data;
AABB octree_aabb;
Size2i octree_tex_size;
};
struct Camera {
@ -149,6 +157,7 @@ class VisualServerRaster : public VisualServer {
float draw_range_begin;
float draw_range_end;
float extra_margin;
int lightmap_texture_index;
Rasterizer::InstanceData data;
@ -158,6 +167,8 @@ class VisualServerRaster : public VisualServer {
Set<Instance*> valid_auto_rooms;
Instance *room;
List<Instance*>::Element *RE;
Instance *baked_light;
List<Instance*>::Element *BLE;
bool exterior;
uint64_t last_render_pass;
@ -205,6 +216,7 @@ class VisualServerRaster : public VisualServer {
uint64_t last_add_pass;
List<RID>::Element *D; // directional light in scenario
InstanceSet affected;
bool enabled;
float dtc; //distance to camera, used for sorting
@ -213,8 +225,16 @@ class VisualServerRaster : public VisualServer {
D=NULL;
light_set_index=-1;
last_add_pass=0;
enabled=true;
}
};
struct BakedLightInfo {
BakedLight *baked_light;
Transform affine_inverse;
List<Instance*> owned_instances;
};
struct ParticlesInfo {
@ -226,6 +246,7 @@ class VisualServerRaster : public VisualServer {
LightInfo *light_info;
ParticlesInfo *particles_info;
PortalInfo * portal_info;
BakedLightInfo * baked_light_info;
Instance() {
@ -244,6 +265,8 @@ class VisualServerRaster : public VisualServer {
data.depth_scale=false;
data.billboard=false;
data.billboard_y=false;
data.baked_light=NULL;
data.baked_light_octree_xform=NULL;
version=1;
room_info=NULL;
room=NULL;
@ -255,6 +278,10 @@ class VisualServerRaster : public VisualServer {
draw_range_end=0;
extra_margin=0;
visible_in_all_rooms=false;
lightmap_texture_index=-1;
baked_light=NULL;
baked_light_info=NULL;
BLE=NULL;
light_cache_dirty=true;
@ -270,6 +297,8 @@ class VisualServerRaster : public VisualServer {
memdelete(room_info);
if (portal_info)
memdelete(portal_info);
if (baked_light_info)
memdelete(baked_light_info);
};
};
@ -570,6 +599,7 @@ class VisualServerRaster : public VisualServer {
bool light_discard_enabled;
bool shadows_enabled;
int black_margin[4];
RID black_image[4];
Vector<Vector3> aabb_random_points;
Vector<Vector3> transformed_aabb_random_points;
@ -596,7 +626,9 @@ class VisualServerRaster : public VisualServer {
mutable RID_Owner<Room> room_owner;
mutable RID_Owner<Portal> portal_owner;
mutable RID_Owner<BakedLight> baked_light_owner;
mutable RID_Owner<Camera> camera_owner;
mutable RID_Owner<Viewport> viewport_owner;
@ -902,8 +934,19 @@ public:
virtual void portal_set_connect_range(RID p_portal, float p_range);
virtual float portal_get_connect_range(RID p_portal) const;
/* BAKED LIGHT */
virtual RID baked_light_create();
virtual void baked_light_set_mode(RID p_baked_light,BakedLightMode p_mode);
virtual BakedLightMode baked_light_get_mode(RID p_baked_light) const;
virtual void baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree);
virtual DVector<uint8_t> baked_light_get_octree(RID p_baked_light) const;
virtual void baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id);
virtual void baked_light_clear_lightmaps(RID p_baked_light);
/* CAMERA API */
virtual RID camera_create();
@ -1036,6 +1079,15 @@ public:
virtual float instance_geometry_get_draw_range_max(RID p_instance) const;
virtual float instance_geometry_get_draw_range_min(RID p_instance) const;
virtual void instance_geometry_set_baked_light(RID p_instance,RID p_baked_light);
virtual RID instance_geometry_get_baked_light(RID p_instance) const;
virtual void instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id);
virtual int instance_geometry_get_baked_light_texture_index(RID p_instance) const;
virtual void instance_light_set_enabled(RID p_instance,bool p_enabled);
virtual bool instance_light_is_enabled(RID p_instance) const;
/* CANVAS (2D) */
virtual RID canvas_create();
@ -1093,6 +1145,7 @@ public:
/* BLACK BARS */
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom);
virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom);
/* FREE */

View file

@ -879,6 +879,17 @@ public:
FUNC1RC(float,portal_get_connect_range,RID);
FUNC0R(RID,baked_light_create);
FUNC2(baked_light_set_mode,RID,BakedLightMode);
FUNC1RC(BakedLightMode,baked_light_get_mode,RID);
FUNC2(baked_light_set_octree,RID,DVector<uint8_t>);
FUNC1RC(DVector<uint8_t>,baked_light_get_octree,RID);
FUNC3(baked_light_add_lightmap,RID,RID,int);
FUNC1(baked_light_clear_lightmaps,RID);
/* CAMERA API */
@ -1014,6 +1025,14 @@ public:
FUNC1RC(float,instance_geometry_get_draw_range_max,RID);
FUNC1RC(float,instance_geometry_get_draw_range_min,RID);
FUNC2(instance_geometry_set_baked_light,RID, RID );
FUNC1RC(RID,instance_geometry_get_baked_light,RID);
FUNC2(instance_geometry_set_baked_light_texture_index,RID, int);
FUNC1RC(int,instance_geometry_get_baked_light_texture_index,RID);
FUNC2(instance_light_set_enabled,RID,bool);
FUNC1RC(bool,instance_light_is_enabled,RID);
/* CANVAS (2D) */
@ -1076,6 +1095,7 @@ public:
/* BLACK BARS */
FUNC4(black_bars_set_margins,int , int , int , int );
FUNC4(black_bars_set_images,RID , RID , RID , RID );
/* FREE */

View file

@ -145,6 +145,7 @@ RID VisualServer::_make_test_cube() {
tangents.push_back( normal_points[m_idx][0] );\
tangents.push_back( 1.0 );\
uvs.push_back( Vector3(uv_points[m_idx*2+0],uv_points[m_idx*2+1],0) );\
print_line(itos( (face_points[m_idx][0]>0?1:0)|(face_points[m_idx][1]>0?2:0)|(face_points[m_idx][2]>0?4:0)));\
vtx_idx++;\
for (int i=0;i<6;i++) {
@ -527,6 +528,7 @@ void VisualServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("cursor_set_pos"),&VisualServer::cursor_set_pos);
ObjectTypeDB::bind_method(_MD("black_bars_set_margins","left","top","right","bottom"),&VisualServer::black_bars_set_margins);
ObjectTypeDB::bind_method(_MD("black_bars_set_images","left","top","right","bottom"),&VisualServer::black_bars_set_images);
ObjectTypeDB::bind_method(_MD("make_sphere_mesh"),&VisualServer::make_sphere_mesh);
ObjectTypeDB::bind_method(_MD("mesh_add_surface_from_planes"),&VisualServer::mesh_add_surface_from_planes);

View file

@ -576,6 +576,23 @@ public:
virtual float portal_get_connect_range(RID p_portal) const =0;
/* BAKED LIGHT API */
virtual RID baked_light_create()=0;
enum BakedLightMode {
BAKED_LIGHT_OCTREE,
BAKED_LIGHT_LIGHTMAPS
};
virtual void baked_light_set_mode(RID p_baked_light,BakedLightMode p_mode)=0;
virtual BakedLightMode baked_light_get_mode(RID p_baked_light) const=0;
virtual void baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree)=0;
virtual DVector<uint8_t> baked_light_get_octree(RID p_baked_light) const=0;
virtual void baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id)=0;
virtual void baked_light_clear_lightmaps(RID p_baked_light)=0;
/* CAMERA API */
@ -792,6 +809,7 @@ public:
INSTANCE_LIGHT,
INSTANCE_ROOM,
INSTANCE_PORTAL,
INSTANCE_BAKED_LIGHT,
INSTANCE_GEOMETRY_MASK=(1<<INSTANCE_MESH)|(1<<INSTANCE_MULTIMESH)|(1<<INSTANCE_IMMEDIATE)|(1<<INSTANCE_PARTICLES)
};
@ -849,7 +867,7 @@ public:
INSTANCE_FLAG_RECEIVE_SHADOWS,
INSTANCE_FLAG_DEPH_SCALE,
INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME,
INSTANCE_FLAG_USE_BAKED_LIGHT,
INSTANCE_FLAG_MAX
};
@ -863,6 +881,14 @@ public:
virtual float instance_geometry_get_draw_range_max(RID p_instance) const=0;
virtual float instance_geometry_get_draw_range_min(RID p_instance) const=0;
virtual void instance_geometry_set_baked_light(RID p_instance,RID p_baked_light)=0;
virtual RID instance_geometry_get_baked_light(RID p_instance) const=0;
virtual void instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id)=0;
virtual int instance_geometry_get_baked_light_texture_index(RID p_instance) const=0;
virtual void instance_light_set_enabled(RID p_instance,bool p_enabled)=0;
virtual bool instance_light_is_enabled(RID p_instance) const=0;
/* CANVAS (2D) */
@ -923,6 +949,7 @@ public:
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom)=0;
virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom)=0;
/* FREE */

View file

@ -704,11 +704,11 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
int flags=0;
if (Globals::get_singleton()->get("texture_import/filter"))
if (Globals::get_singleton()->get("image_loader/filter"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_FILTER;
if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
if (!Globals::get_singleton()->get("image_loader/gen_mipmaps"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS;
if (!Globals::get_singleton()->get("texture_import/repeat"))
if (!Globals::get_singleton()->get("image_loader/repeat"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_REPEAT;
flags|=EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA;
@ -1533,6 +1533,26 @@ void EditorImportExport::load_config() {
}
if (cf->has_section("script")) {
if (cf->has_section_key("script","action")) {
String action = cf->get_value("script","action");
if (action=="compile")
script_action=SCRIPT_ACTION_COMPILE;
else if (action=="encrypt")
script_action=SCRIPT_ACTION_ENCRYPT;
else
script_action=SCRIPT_ACTION_NONE;
}
if (cf->has_section_key("script","encrypt_key")) {
script_key = cf->get_value("script","encrypt_key");
}
}
}
@ -1634,10 +1654,39 @@ void EditorImportExport::save_config() {
cf->set_value("image_group_files","files",igfsave);
}
switch(script_action) {
case SCRIPT_ACTION_NONE: cf->set_value("script","action","none"); break;
case SCRIPT_ACTION_COMPILE: cf->set_value("script","action","compile"); break;
case SCRIPT_ACTION_ENCRYPT: cf->set_value("script","action","encrypt"); break;
}
cf->set_value("script","encrypt_key",script_key);
cf->save("res://export.cfg");
}
void EditorImportExport::script_set_action(ScriptAction p_action) {
script_action=p_action;
}
EditorImportExport::ScriptAction EditorImportExport::script_get_action() const{
return script_action;
}
void EditorImportExport::script_set_encryption_key(const String& p_key){
script_key=p_key;
}
String EditorImportExport::script_get_encryption_key() const{
return script_key;
}
void EditorImportExport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("image_export_group_create"),&EditorImportExport::image_export_group_create);
@ -1649,6 +1698,11 @@ void EditorImportExport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("image_export_group_get_make_atlas"),&EditorImportExport::image_export_group_get_make_atlas);
ObjectTypeDB::bind_method(_MD("image_export_group_get_shrink"),&EditorImportExport::image_export_group_get_shrink);
ObjectTypeDB::bind_method(_MD("image_add_to_export_group"),&EditorImportExport::image_add_to_export_group);
ObjectTypeDB::bind_method(_MD("script_set_action"),&EditorImportExport::script_set_action);
ObjectTypeDB::bind_method(_MD("script_set_encryption_key"),&EditorImportExport::script_set_encryption_key);
ObjectTypeDB::bind_method(_MD("script_get_action"),&EditorImportExport::script_get_action);
ObjectTypeDB::bind_method(_MD("script_get_encryption_key"),&EditorImportExport::script_get_encryption_key);
}
EditorImportExport::EditorImportExport() {
@ -1659,6 +1713,9 @@ EditorImportExport::EditorImportExport() {
image_action_compress_quality=0.7;
image_formats.insert("png");
image_shrink=1;
script_action=SCRIPT_ACTION_COMPILE;
}

View file

@ -227,6 +227,11 @@ public:
IMAGE_ACTION_COMPRESS_RAM,
};
enum ScriptAction {
SCRIPT_ACTION_NONE,
SCRIPT_ACTION_COMPILE,
SCRIPT_ACTION_ENCRYPT
};
protected:
@ -254,6 +259,9 @@ protected:
Map<StringName,StringName> image_group_files;
Vector<String> diff_packs;
ScriptAction script_action;
String script_key;
static EditorImportExport* singleton;
static void _bind_methods();
@ -316,6 +324,11 @@ public:
Set<String>& get_image_formats() { return image_formats; }
void script_set_action(ScriptAction p_action);
ScriptAction script_get_action() const;
void script_set_encryption_key(const String& p_key);
String script_get_encryption_key() const;
void load_config();
void save_config();
@ -324,5 +337,6 @@ public:
};
VARIANT_ENUM_CAST(EditorImportExport::ImageAction);
VARIANT_ENUM_CAST(EditorImportExport::ScriptAction);
#endif // EDITOR_IMPORT_EXPORT_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 567 B

View file

@ -290,6 +290,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
} else {
//mesh since nothing else
node = memnew( MeshInstance );
node->cast_to<MeshInstance>()->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT,true);
}
} break;
case Collada::Node::TYPE_SKELETON: {

View file

@ -732,6 +732,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS))
tex_flags|=Texture::FLAG_MIPMAPS;
print_line("path: "+p_path+" flags: "+itos(tex_flags));
int shrink=1;
if (from->has_option("shrink"))
shrink=from->get_option("shrink");
@ -1073,11 +1074,11 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
int flags=0;
if (Globals::get_singleton()->get("texture_import/filter"))
if (Globals::get_singleton()->get("image_loader/filter"))
flags|=IMAGE_FLAG_FILTER;
if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
if (!Globals::get_singleton()->get("image_loader/gen_mipmaps"))
flags|=IMAGE_FLAG_NO_MIPMAPS;
if (!Globals::get_singleton()->get("texture_import/repeat"))
if (!Globals::get_singleton()->get("image_loader/repeat"))
flags|=IMAGE_FLAG_REPEAT;
flags|=IMAGE_FLAG_FIX_BORDER_ALPHA;
@ -1102,11 +1103,11 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
int flags=0;
if (Globals::get_singleton()->get("texture_import/filter"))
if (Globals::get_singleton()->get("image_loader/filter"))
flags|=IMAGE_FLAG_FILTER;
if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
if (!Globals::get_singleton()->get("image_loader/gen_mipmaps"))
flags|=IMAGE_FLAG_NO_MIPMAPS;
if (!Globals::get_singleton()->get("texture_import/repeat"))
if (!Globals::get_singleton()->get("image_loader/repeat"))
flags|=IMAGE_FLAG_REPEAT;
flags|=IMAGE_FLAG_FIX_BORDER_ALPHA;
@ -1147,10 +1148,13 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
MD5Update(&ctx,&shrink,1);
MD5Final(&ctx);
uint64_t sd=0;
String smd5;
String md5 = String::md5(ctx.digest);
print_line(p_path+" MD5: "+md5+" FLAGS: "+itos(flags));
String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/");

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,316 @@
#ifndef BAKED_LIGHT_BAKER_H
#define BAKED_LIGHT_BAKER_H
#include "scene/3d/baked_light_instance.h"
#include "scene/3d/light.h"
#include "scene/3d/mesh_instance.h"
#include "os/thread.h"
class BakedLightBaker {
public:
enum {
ATTENUATION_CURVE_LEN=256,
OCTANT_POOL_CHUNK=1000000
};
struct OctantLight {
double accum[8][3];
};
struct Octant {
bool leaf;
AABB aabb;
uint16_t texture_x;
uint16_t texture_y;
float normal_accum[8][3];
int parent;
union {
struct {
int next_leaf;
float offset[3];
int bake_neighbour;
bool first_neighbour;
OctantLight *light;
};
int children[8];
};
};
struct OctantHash {
int next;
uint32_t hash;
uint64_t value;
};
struct MeshTexture {
Vector<uint8_t> tex;
int tex_w,tex_h;
_FORCE_INLINE_ void get_color(const Vector2& p_uv,Color& ret) {
if (tex_w && tex_h) {
int x = Math::fast_ftoi(Math::fposmod(p_uv.x,1.0)*tex_w);
int y = Math::fast_ftoi(Math::fposmod(p_uv.y,1.0)*tex_w);
x=CLAMP(x,0,tex_w-1);
y=CLAMP(y,0,tex_h-1);
const uint8_t*ptr = &tex[(y*tex_w+x)*4];
ret.r*=ptr[0]/255.0;
ret.g*=ptr[1]/255.0;
ret.b*=ptr[2]/255.0;
ret.a*=ptr[3]/255.0;
}
}
};
struct Param {
Color color;
MeshTexture*tex;
_FORCE_INLINE_ Color get_color(const Vector2& p_uv) {
Color ret=color;
if (tex)
tex->get_color(p_uv,ret);
return ret;
}
};
struct MeshMaterial {
Param diffuse;
Param specular;
Param emission;
};
struct Triangle {
AABB aabb;
Vector3 vertices[3];
Vector2 uvs[3];
Vector3 normals[3];
MeshMaterial *material;
_FORCE_INLINE_ Vector2 get_uv(const Vector3& p_pos) {
Vector3 v0 = vertices[1] - vertices[0];
Vector3 v1 = vertices[2] - vertices[0];
Vector3 v2 = p_pos - vertices[0];
float d00 = v0.dot( v0);
float d01 = v0.dot( v1);
float d11 = v1.dot( v1);
float d20 = v2.dot( v0);
float d21 = v2.dot( v1);
float denom = (d00 * d11 - d01 * d01);
if (denom==0)
return uvs[0];
float v = (d11 * d20 - d01 * d21) / denom;
float w = (d00 * d21 - d01 * d20) / denom;
float u = 1.0f - v - w;
return uvs[0]*u + uvs[1]*v + uvs[2]*w;
}
_FORCE_INLINE_ void get_uv_and_normal(const Vector3& p_pos,Vector2& r_uv,Vector3& r_normal) {
Vector3 v0 = vertices[1] - vertices[0];
Vector3 v1 = vertices[2] - vertices[0];
Vector3 v2 = p_pos - vertices[0];
float d00 = v0.dot( v0);
float d01 = v0.dot( v1);
float d11 = v1.dot( v1);
float d20 = v2.dot( v0);
float d21 = v2.dot( v1);
float denom = (d00 * d11 - d01 * d01);
if (denom==0) {
r_normal=normals[0];
r_uv=uvs[0];
return;
}
float v = (d11 * d20 - d01 * d21) / denom;
float w = (d00 * d21 - d01 * d20) / denom;
float u = 1.0f - v - w;
r_uv=uvs[0]*u + uvs[1]*v + uvs[2]*w;
r_normal=(normals[0]*u+normals[1]*v+normals[2]*w).normalized();
}
};
struct BVH {
AABB aabb;
Vector3 center;
Triangle *leaf;
BVH*children[2];
};
struct BVHCmpX {
bool operator()(const BVH* p_left, const BVH* p_right) const {
return p_left->center.x < p_right->center.x;
}
};
struct BVHCmpY {
bool operator()(const BVH* p_left, const BVH* p_right) const {
return p_left->center.y < p_right->center.y;
}
};
struct BVHCmpZ {
bool operator()(const BVH* p_left, const BVH* p_right) const {
return p_left->center.z < p_right->center.z;
}
};
struct LightData {
VS::LightType type;
Vector3 pos;
Vector3 up;
Vector3 left;
Vector3 dir;
Color diffuse;
Color specular;
float energy;
float length;
int rays_thrown;
float radius;
float attenuation;
float spot_angle;
float spot_attenuation;
float area;
float constant;
bool bake_direct;
Vector<float> attenuation_table;
};
Vector<LightData> lights;
List<MeshMaterial> materials;
List<MeshTexture> textures;
AABB octree_aabb;
Vector<Octant> octant_pool;
int octant_pool_size;
BVH*bvh;
Vector<Triangle> triangles;
Transform base_inv;
int leaf_list;
int octree_depth;
int cell_count;
uint32_t *ray_stack;
uint32_t *octant_stack;
uint32_t *octantptr_stack;
Map<Vector3,Vector3> endpoint_normal;
BVH **bvh_stack;
float cell_size;
float plot_size; //multiplied by cell size
float octree_extra_margin;
int max_bounces;
uint64_t total_rays;
bool use_diffuse;
bool use_specular;
bool use_translucency;
int baked_octree_texture_w;
int baked_octree_texture_h;
int lattice_size;
float edge_damp;
float normal_damp;
bool paused;
bool baking;
Map<Ref<Material>,MeshMaterial*> mat_map;
Map<Ref<Texture>,MeshTexture*> tex_map;
MeshTexture* _get_mat_tex(const Ref<Texture>& p_tex);
void _add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_mat_override,const Transform& p_xform);
void _parse_geometry(Node* p_node);
BVH* _parse_bvh(BVH** p_children,int p_size,int p_depth,int& max_depth);
void _make_bvh();
void _make_octree();
void _make_octree_texture();
void _octree_insert(int p_octant, Triangle* p_triangle, int p_depth);
void _free_bvh(BVH* p_bvh);
void _fix_lights();
Ref<BakedLight> baked_light;
//void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,int p_octant=0);
void _plot_light(int p_light_index,const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,const Plane& p_plane);
//void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light);
float _throw_ray(int p_light_index,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce=false);
float total_light_area;
uint64_t rays_at_snap_time;
uint64_t snap_time;
int rays_sec;
Thread *thread;
bool bake_thread_exit;
static void _bake_thread_func(void *arg);
void _start_thread();
void _stop_thread();
public:
void throw_rays(int p_amount);
double get_normalization(int p_light_idx) const;
void bake(const Ref<BakedLight>& p_light,Node *p_base);
bool is_baking();
void set_pause(bool p_pause);
bool is_paused();
int get_rays_sec() { return rays_sec; }
void update_octree_image(DVector<uint8_t> &p_image);
Ref<BakedLight> get_baked_light() { return baked_light; }
void clear();
BakedLightBaker();
~BakedLightBaker();
};
#endif // BAKED_LIGHT_BAKER_H

File diff suppressed because it is too large Load diff

View file

@ -3,15 +3,17 @@
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
#include "scene/3d/baked_light.h"
#include "tools/editor/plugins/baked_light_baker.h"
#include "scene/gui/spin_box.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class BakedLightBaker;
class MeshInstance;
class BakedLightEditor : public Control {
@ -20,20 +22,18 @@ class BakedLightEditor : public Control {
float update_timeout;
DVector<Color> colors;
DVector<Vector3> vertices;
Ref<Mesh> mesh;
Ref<FixedMaterial> material;
DVector<uint8_t> octree_texture;
Thread *bake_thread;
bool bake_thread_exit;
MeshInstance *preview;
BakedLightBaker *baker;
AcceptDialog *err_dialog;
MenuButton * options;
BakedLight *node;
HBoxContainer *bake_hbox;
Button *button_bake;
Button *button_reset;
Label *bake_info;
BakedLightInstance *node;
enum Menu {
@ -41,7 +41,9 @@ class BakedLightEditor : public Control {
MENU_OPTION_CLEAR
};
static void _bake_thread_func(void *arg);
void _bake_pressed();
void _clear_pressed();
void _end_baking();
void _menu_option(int);
@ -52,7 +54,7 @@ protected:
void _notification(int p_what);
public:
void edit(BakedLight *p_baked_light);
void edit(BakedLightInstance *p_baked_light);
BakedLightEditor();
~BakedLightEditor();
};

View file

@ -232,6 +232,26 @@ void ProjectExportDialog::_format_toggled() {
}
void ProjectExportDialog::_script_edited(Variant v) {
if (updating_script)
return;
updating_script=true;
EditorNode::get_undo_redo()->create_action("Edit Script Options");
EditorNode::get_undo_redo()->add_do_method(EditorImportExport::get_singleton(),"script_set_action",script_mode->get_selected());
EditorNode::get_undo_redo()->add_undo_method(EditorImportExport::get_singleton(),"script_set_action",EditorImportExport::get_singleton()->script_get_action());
EditorNode::get_undo_redo()->add_do_method(EditorImportExport::get_singleton(),"script_set_encryption_key",script_key->get_text());
EditorNode::get_undo_redo()->add_undo_method(EditorImportExport::get_singleton(),"script_set_encryption_key",EditorImportExport::get_singleton()->script_get_encryption_key());
EditorNode::get_undo_redo()->add_do_method(this,"_update_script");
EditorNode::get_undo_redo()->add_undo_method(this,"_update_script");
EditorNode::get_undo_redo()->add_do_method(this,"_save_export_cfg");
EditorNode::get_undo_redo()->add_undo_method(this,"_save_export_cfg");
EditorNode::get_undo_redo()->commit_action();
updating_script=false;
}
void ProjectExportDialog::_notification(int p_what) {
switch(p_what) {
@ -277,10 +297,16 @@ void ProjectExportDialog::_notification(int p_what) {
image_action->select(EditorImportExport::get_singleton()->get_export_image_action());
image_quality->set_val(EditorImportExport::get_singleton()->get_export_image_quality());
image_shrink->set_val(EditorImportExport::get_singleton()->get_export_image_shrink());
_update_script();
image_quality->connect("value_changed",this,"_quality_edited");
image_shrink->connect("value_changed",this,"_shrink_edited");
image_action->connect("item_selected",this,"_image_export_edited");
script_mode->connect("item_selected",this,"_script_edited");
script_key->connect("text_changed",this,"_script_edited");
for(int i=0;i<formats.size();i++) {
if (EditorImportExport::get_singleton()->get_image_formats().has(formats[i]->get_text(0)))
formats[i]->set_checked(0,true);
@ -651,10 +677,15 @@ bool ProjectExportDialog::_update_group_treef(TreeItem *p_parent,EditorFileSyste
}
void ProjectExportDialog::_update_group_tree() {
if (updating)
return;
group_images->clear();
if (_get_selected_group()=="")
return;
updating=true;
print_line("****UGT");
List<String> img_extensions;
ImageLoader::get_recognized_extensions(&img_extensions);
@ -677,7 +708,7 @@ void ProjectExportDialog::_update_group_tree() {
groupenum+=","+String(E->get());
}
updating=false;
_update_group_treef(NULL,EditorFileSystem::get_singleton()->get_filesystem(),extensions,groupenum,group_index);
@ -690,7 +721,7 @@ void ProjectExportDialog::_group_changed(Variant v) {
return;
if (_get_selected_group()=="")
return;
updating=true;
StringName name = _get_selected_group();
EditorNode::get_undo_redo()->create_action("Change Image Group");
EditorNode::get_undo_redo()->add_do_method(EditorImportExport::get_singleton(),"image_export_group_set_image_action",name,group_image_action->get_selected());
@ -706,6 +737,7 @@ void ProjectExportDialog::_group_changed(Variant v) {
EditorNode::get_undo_redo()->add_do_method(this,"_save_export_cfg");
EditorNode::get_undo_redo()->add_undo_method(this,"_save_export_cfg");
EditorNode::get_undo_redo()->commit_action();
updating=false;
}
void ProjectExportDialog::_group_item_edited() {
@ -926,11 +958,11 @@ void ProjectExportDialog::_group_atlas_preview() {
int flags=0;
if (Globals::get_singleton()->get("texture_import/filter"))
if (Globals::get_singleton()->get("image_loader/filter"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_FILTER;
if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
if (!Globals::get_singleton()->get("image_loader/gen_mipmaps"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS;
if (!Globals::get_singleton()->get("texture_import/repeat"))
if (!Globals::get_singleton()->get("image_loader/repeat"))
flags|=EditorTextureImportPlugin::IMAGE_FLAG_REPEAT;
flags|=EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA;
@ -956,6 +988,17 @@ void ProjectExportDialog::_group_atlas_preview() {
}
void ProjectExportDialog::_update_script() {
if (updating_script)
return;
updating_script=true;
script_mode->select(EditorImportExport::get_singleton()->script_get_action());
script_key->set_text(EditorImportExport::get_singleton()->script_get_encryption_key());
updating_script=false;
}
void ProjectExportDialog::_image_filter_changed(String) {
_update_group_tree();
@ -991,6 +1034,8 @@ void ProjectExportDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_group_atlas_preview"),&ProjectExportDialog::_group_atlas_preview);
ObjectTypeDB::bind_method(_MD("_group_select_all"),&ProjectExportDialog::_group_select_all);
ObjectTypeDB::bind_method(_MD("_group_select_none"),&ProjectExportDialog::_group_select_none);
ObjectTypeDB::bind_method(_MD("_script_edited"),&ProjectExportDialog::_script_edited);
ObjectTypeDB::bind_method(_MD("_update_script"),&ProjectExportDialog::_update_script);
ObjectTypeDB::bind_method(_MD("export_platform"),&ProjectExportDialog::export_platform);
@ -1171,7 +1216,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
group_lossy_quality->set_step(0.1);
group_lossy_quality->set_val(0.7);
group_options->add_margin_child("Lossy Quality:",group_lossy_quality);
group_lossy_quality->connect("value_changed",this,"_group_changed");
group_lossy_quality->connect("value_changed",this,"_quality_edited");
group_atlas = memnew(CheckButton);
group_atlas->set_pressed("Generate Atlas");
@ -1261,6 +1306,18 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
hbc->add_child(button_reload);
*/
script_vbox = memnew( VBoxContainer );
script_vbox->set_name("Script");
sections->add_child(script_vbox);
script_mode = memnew( OptionButton );
script_vbox->add_margin_child("Script Export Mode:",script_mode);
script_mode->add_item("Text");
script_mode->add_item("Compiled");
script_mode->add_item("Encrypted (Provide Key Below)");
script_key = memnew( LineEdit );
script_vbox->add_margin_child("Script Encryption Key (256-bits as hex):",script_key);
updating=false;
@ -1302,6 +1359,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
add_child(pck_export);
button_export = add_button("Export..",!OS::get_singleton()->get_swap_ok_cancel(),"export_pck");
updating_script=false;
}

View file

@ -132,6 +132,12 @@ private:
TextureFrame *atlas_preview_frame;
VBoxContainer *script_vbox;
OptionButton *script_mode;
LineEdit *script_key;
void _export_mode_changed(int p_idx);
void _prop_edited(String what);
@ -166,6 +172,9 @@ private:
void _group_select_none();
void _group_del(Object *item,int p_column, int p_button);
bool updating_script;
void _update_script();
void _script_edited(Variant v);
void _export_action(const String& p_file);
void _export_action_pck(const String& p_file);
void ok_pressed();