mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 06:03:09 +00:00
parent
830947feaf
commit
424a104666
@ -44,9 +44,9 @@ MainLoop * test() {
|
||||
|
||||
/*
|
||||
HashMap<int,int> int_map;
|
||||
|
||||
|
||||
for (int i=0;i<68000;i++) {
|
||||
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
int_map[i]=num;
|
||||
}
|
||||
@ -70,21 +70,21 @@ MainLoop * test() {
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
#if 0
|
||||
Set<int> set;
|
||||
|
||||
|
||||
print_line("Begin Insert");
|
||||
for (int i=0;i<1100;i++) {
|
||||
|
||||
|
||||
int num=i;//(int)Math::random(0,1024);
|
||||
// print_line("inserting "+itos(num));
|
||||
// print_line("inserting "+itos(num));
|
||||
set.insert( num );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i=0;i<400;i++) {
|
||||
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
set.erase(num);
|
||||
}
|
||||
@ -92,11 +92,11 @@ MainLoop * test() {
|
||||
//set.print_tree();
|
||||
|
||||
for(Set<int>::Element *I=set.front();I;I=I->next()) {
|
||||
|
||||
|
||||
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
|
||||
|
||||
}
|
||||
|
||||
|
||||
print_line("depth is "+itos(set.calculate_depth()));
|
||||
print_line("Insert Success");
|
||||
#endif
|
||||
|
@ -44,7 +44,7 @@ class TestMainLoop : public MainLoop {
|
||||
RID light;
|
||||
RID mesh;
|
||||
RID scenario;
|
||||
|
||||
|
||||
#define MULTIMESH_COUNT 1500
|
||||
|
||||
float ofs_x,ofs_y;
|
||||
@ -122,9 +122,9 @@ public:
|
||||
}
|
||||
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||
|
||||
|
||||
ofs_x+=p_event.mouse_motion.relative_y/200.0;
|
||||
ofs_y+=p_event.mouse_motion.relative_x/200.0;
|
||||
}
|
||||
@ -142,16 +142,16 @@ public:
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void init() {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
@ -163,13 +163,13 @@ public:
|
||||
_update_qh();
|
||||
|
||||
instance = vs->instance_create2(mesh,scenario);
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
|
||||
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
vs->viewport_set_scenario( viewport, scenario );
|
||||
|
||||
@ -179,7 +179,7 @@ public:
|
||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
|
||||
light = vs->instance_create2( lightaux,scenario );
|
||||
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
|
||||
|
||||
|
||||
ofs_x=0;
|
||||
ofs_y=0;
|
||||
quit=false;
|
||||
@ -190,20 +190,20 @@ public:
|
||||
}
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
Transform tr_camera;
|
||||
tr_camera.rotate( Vector3(0,1,0), ofs_y );
|
||||
tr_camera.rotate( Vector3(1,0,0),ofs_x );
|
||||
tr_camera.translate(0,0,10);
|
||||
|
||||
|
||||
vs->camera_set_transform( camera, tr_camera );
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -81,7 +81,7 @@ static String _parser_expr(const GDParser::Node *p_expr) {
|
||||
|
||||
case GDParser::Node::TYPE_IDENTIFIER: {
|
||||
|
||||
const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
|
||||
const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
|
||||
txt=id_node->name;
|
||||
} break;
|
||||
case GDParser::Node::TYPE_CONSTANT: {
|
||||
|
@ -62,16 +62,16 @@ class TestMainLoop : public SceneTree {
|
||||
|
||||
|
||||
Control *control;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit();
|
||||
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
|
||||
SceneTree::init();
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ public:
|
||||
|
||||
Ref<Theme> t = memnew( Theme );
|
||||
frame->set_theme(t);
|
||||
|
||||
|
||||
get_root()->add_child( frame );
|
||||
|
||||
Label *label = memnew( Label );
|
||||
@ -198,21 +198,21 @@ public:
|
||||
//root->add_child( control );
|
||||
|
||||
|
||||
|
||||
|
||||
LineEdit *line_edit = memnew( LineEdit );
|
||||
|
||||
|
||||
line_edit->set_pos( Point2( 30,190 ) );
|
||||
line_edit->set_size( Point2( 180,1 ) );
|
||||
|
||||
|
||||
frame->add_child(line_edit);
|
||||
|
||||
|
||||
HScrollBar *hscroll = memnew( HScrollBar );
|
||||
|
||||
|
||||
hscroll->set_pos( Point2( 30,290 ) );
|
||||
hscroll->set_size( Point2( 180,1 ) );
|
||||
hscroll->set_max(10);
|
||||
hscroll->set_page(4);
|
||||
|
||||
|
||||
frame->add_child(hscroll);
|
||||
|
||||
|
||||
@ -234,36 +234,36 @@ public:
|
||||
hscroll->share(progress);
|
||||
|
||||
MenuButton *menu_button = memnew( MenuButton );
|
||||
|
||||
|
||||
menu_button->set_text("I'm a menu!");
|
||||
menu_button->set_pos( Point2( 30,380 ) );
|
||||
menu_button->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(menu_button);
|
||||
|
||||
|
||||
frame->add_child(menu_button);
|
||||
|
||||
PopupMenu *popup = menu_button->get_popup();
|
||||
|
||||
|
||||
popup->add_item("Hello, testing");
|
||||
popup->add_item("My Dearest");
|
||||
popup->add_separator();
|
||||
popup->add_item("Popup");
|
||||
popup->add_check_item("Check Popup");
|
||||
popup->set_item_checked(4,true);
|
||||
|
||||
popup->set_item_checked(4,true);
|
||||
|
||||
OptionButton *options = memnew( OptionButton );
|
||||
|
||||
|
||||
options->add_item("Hello, testing");
|
||||
options->add_item("My Dearest");
|
||||
|
||||
|
||||
options->set_pos( Point2( 230,180 ) );
|
||||
options->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(options);
|
||||
|
||||
frame->add_child(options);
|
||||
|
||||
/*
|
||||
Tree * tree = memnew( Tree );
|
||||
tree->set_columns(2);
|
||||
|
||||
|
||||
tree->set_pos( Point2( 230,210 ) );
|
||||
tree->set_size( Point2( 150,250 ) );
|
||||
|
||||
@ -286,7 +286,7 @@ public:
|
||||
item->set_editable(0,true);
|
||||
item->set_text(0,"Have,Many,Several,Options!");
|
||||
item->set_range(0,2);
|
||||
|
||||
|
||||
frame->add_child(tree);
|
||||
*/
|
||||
|
||||
@ -365,11 +365,11 @@ public:
|
||||
tabc->add_child(ctl);
|
||||
|
||||
frame->add_child(tabc);
|
||||
|
||||
|
||||
tabc->set_pos( Point2( 400,210 ) );
|
||||
tabc->set_size( Point2( 180,250 ) );
|
||||
|
||||
|
||||
|
||||
Ref<ImageTexture> text = memnew( ImageTexture );
|
||||
text->load("test_data/concave.png");
|
||||
|
||||
@ -387,13 +387,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
}
|
||||
|
||||
|
@ -47,37 +47,37 @@ namespace TestIO {
|
||||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
|
||||
|
||||
|
||||
bool quit;
|
||||
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ const char ** tests_get_names() {
|
||||
"physics",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
return test_names;
|
||||
}
|
||||
|
||||
@ -72,22 +72,22 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
|
||||
|
||||
if (p_test=="string") {
|
||||
|
||||
|
||||
return TestString::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="containers") {
|
||||
|
||||
|
||||
return TestContainers::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="math") {
|
||||
|
||||
|
||||
return TestMath::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="physics") {
|
||||
|
||||
|
||||
return TestPhysics::test();
|
||||
}
|
||||
|
||||
@ -97,15 +97,15 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
}
|
||||
|
||||
if (p_test=="misc") {
|
||||
|
||||
|
||||
return TestMisc::test();
|
||||
}
|
||||
|
||||
if (p_test=="render") {
|
||||
|
||||
|
||||
return TestRender::test();
|
||||
}
|
||||
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (p_test=="gui") {
|
||||
|
||||
@ -119,17 +119,17 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
}
|
||||
|
||||
if (p_test=="io") {
|
||||
|
||||
|
||||
return TestIO::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="particles") {
|
||||
|
||||
return TestParticles::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="multimesh") {
|
||||
|
||||
|
||||
return TestMultiMesh::test();
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||
#ifdef PYTHON_ENABLED
|
||||
|
||||
if (p_test=="python") {
|
||||
|
||||
|
||||
return TestPython::test();
|
||||
}
|
||||
#endif
|
||||
|
@ -70,7 +70,7 @@ fix: 0, 0, 49.949951, 50
|
||||
v0: 0, 0, 100, 100
|
||||
v1: 0, 0, 100, 100
|
||||
fix: 0, 0, 100, 100
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
@ -43,38 +43,38 @@ class TestMainLoop : public MainLoop {
|
||||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
particles = vs->particles_create();
|
||||
vs->particles_set_amount(particles,1000);
|
||||
|
||||
|
||||
instance = vs->instance_create2(particles,scenario);
|
||||
|
||||
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
@ -89,7 +89,7 @@ public:
|
||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
light = vs->instance_create2( lightaux, scenario );
|
||||
|
||||
|
||||
ofs=0;
|
||||
quit=false;
|
||||
}
|
||||
@ -99,14 +99,14 @@ public:
|
||||
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
// VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
ofs+=p_time;
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ class TestPhysicsMainLoop : public MainLoop {
|
||||
};
|
||||
|
||||
RID test_cube;
|
||||
|
||||
|
||||
RID plane;
|
||||
RID sphere;
|
||||
RID light;
|
||||
@ -74,13 +74,13 @@ class TestPhysicsMainLoop : public MainLoop {
|
||||
//t.basis.scale( Vector3(1.0,0.5,0.2) );
|
||||
vs->instance_set_transform(p_visual_instance,t);
|
||||
}
|
||||
|
||||
|
||||
bool quit;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
|
||||
}
|
||||
|
||||
@ -90,11 +90,11 @@ protected:
|
||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
|
||||
RID body = ps->body_create(p_body,!p_active_default);
|
||||
RID body = ps->body_create(p_body,!p_active_default);
|
||||
ps->body_set_space(body,space);
|
||||
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
|
||||
//todo set space
|
||||
ps->body_add_shape(body,type_shape_map[p_shape]);
|
||||
ps->body_add_shape(body,type_shape_map[p_shape]);
|
||||
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
|
||||
|
||||
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
|
||||
@ -289,7 +289,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||
|
||||
ofs_y-=p_event.mouse_motion.relative_y/200.0;
|
||||
@ -329,7 +329,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
@ -388,53 +388,53 @@ public:
|
||||
/* Make Trimesh */
|
||||
quit=false;
|
||||
return;
|
||||
|
||||
|
||||
#if 0
|
||||
#define GRID_SIZE 5
|
||||
|
||||
|
||||
float grid[GRID_SIZE][GRID_SIZE];
|
||||
|
||||
|
||||
for (int i=0;i<GRID_SIZE;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<GRID_SIZE;j++) {
|
||||
|
||||
|
||||
grid[j][i]=Math::random(0.0, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector<Vector3> faces;
|
||||
|
||||
|
||||
for (int i=1;i<GRID_SIZE;i++) {
|
||||
|
||||
|
||||
for (int j=1;j<GRID_SIZE;j++) {
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAKE_VERTEX(m_x,m_z)\
|
||||
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
|
||||
|
||||
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i,j);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
|
||||
MAKE_VERTEX(i-1,j-1);
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
faces.clear();
|
||||
faces.clear();
|
||||
faces.push_back( Vector3(0,0,-5) );
|
||||
faces.push_back( Vector3(1,0,-1) );
|
||||
faces.push_back( Vector3(-1,-0,-1) );
|
||||
*/
|
||||
|
||||
|
||||
RID trimesh_shape = ps->shape_create();
|
||||
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
|
||||
faces=ps->shape_get_shape(trimesh_shape, 0);
|
||||
Vector<Vector3> normals; // for drawing
|
||||
for (int i=0;i<faces.size()/3;i++) {
|
||||
|
||||
|
||||
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
@ -448,11 +448,11 @@ public:
|
||||
RID trimesh_mat = vs->fixed_material_create();
|
||||
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
|
||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
||||
|
||||
|
||||
RID triins = vs->instance_create2(trimesh_mesh);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
|
||||
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
|
||||
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
||||
@ -483,7 +483,7 @@ public:
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_joint() {
|
||||
@ -599,7 +599,7 @@ public:
|
||||
PhysicsServer::ShapeType type=shape_idx[i%4];
|
||||
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
|
||||
|
||||
Transform t;
|
||||
Transform t;
|
||||
|
||||
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
|
||||
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
|
||||
|
@ -47,7 +47,7 @@ void test() {
|
||||
PyRun_SimpleString("b=Moch();\n");
|
||||
PyRun_SimpleString("b.mooch();\n");
|
||||
PyRun_SimpleString("b.meis();\n");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -49,16 +49,16 @@ class TestMainLoop : public MainLoop {
|
||||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
protected:
|
||||
@ -66,13 +66,13 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
|
||||
quit=true;
|
||||
}
|
||||
|
||||
virtual void init() {
|
||||
|
||||
|
||||
|
||||
print_line("INITIALIZING TEST RENDER");
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
@ -150,26 +150,26 @@ public:
|
||||
};
|
||||
|
||||
for (int i=0;i<object_count;i++) {
|
||||
|
||||
|
||||
InstanceInfo ii;
|
||||
|
||||
|
||||
|
||||
|
||||
ii.instance = vs->instance_create2( test_cube, scenario );
|
||||
|
||||
|
||||
|
||||
|
||||
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
|
||||
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
|
||||
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
|
||||
vs->instance_set_transform( ii.instance, ii.base );
|
||||
|
||||
vs->instance_set_transform( ii.instance, ii.base );
|
||||
|
||||
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
|
||||
|
||||
|
||||
instances.push_back(ii);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
|
||||
viewport = vs->viewport_create();
|
||||
@ -226,9 +226,9 @@ public:
|
||||
ofs+=p_time*0.05;
|
||||
|
||||
//return quit;
|
||||
|
||||
|
||||
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
|
||||
|
||||
|
||||
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
|
||||
vs->instance_set_transform( E->get().instance, pre * E->get().base );
|
||||
/*
|
||||
@ -238,7 +238,7 @@ public:
|
||||
instances.erase(E );
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ MainLoop* test() {
|
||||
|
||||
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
|
||||
|
||||
if (!fa) {
|
||||
if (!fa) {
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
|
@ -38,145 +38,145 @@
|
||||
namespace TestString {
|
||||
|
||||
bool test_1() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
|
||||
|
||||
|
||||
String s = "Hello";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Hello\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Hello")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_2() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
|
||||
|
||||
|
||||
String s = "Dolly";
|
||||
String t = s;
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Dolly\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
|
||||
return (wcscmp(t.c_str(),L"Dolly")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_3() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
|
||||
|
||||
|
||||
String s("Sheep");
|
||||
String t(s);
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Sheep\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
|
||||
return (wcscmp(t.c_str(),L"Sheep")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_4() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
|
||||
|
||||
|
||||
String s(L"Give me");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Give me\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Give me")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_5() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
|
||||
|
||||
|
||||
String s(L"Wool");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Wool\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Wool")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_6() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
|
||||
if (! ( s=="Test Compare" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s==L"Test Compare" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s==String("Test Compare") ) )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_7() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
|
||||
if (! ( s!="Peanut" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s!=L"Coconut" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s!=String("Butter") ) )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_8() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Bees";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
|
||||
|
||||
|
||||
if ( ! (s < "Elephant") )
|
||||
return false;
|
||||
|
||||
|
||||
if ( s < L"Amber" )
|
||||
return false;
|
||||
|
||||
|
||||
if ( s < String("Beatrix") )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_9() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s;
|
||||
|
||||
|
||||
s+="Have";
|
||||
s+=' ';
|
||||
s+='a';
|
||||
@ -184,279 +184,279 @@ bool test_9() {
|
||||
s = s + L"Nice";
|
||||
s = s + " ";
|
||||
s = s + String("Day");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
|
||||
|
||||
|
||||
return (s == "Have a Nice Day");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_10() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
|
||||
|
||||
|
||||
if (! String("").empty())
|
||||
return false;
|
||||
|
||||
|
||||
if (String("Mellon").size() != 7)
|
||||
return false;
|
||||
|
||||
if (String("Oranges").length() != 7)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_11() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
|
||||
|
||||
|
||||
String a="Kugar Sane";
|
||||
|
||||
|
||||
a[0]='S';
|
||||
a[6]='C';
|
||||
|
||||
|
||||
if (a != "Sugar Cane")
|
||||
return false;
|
||||
|
||||
|
||||
if (a[1]!='u')
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_12() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 12: case functions\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String a="MoMoNgA";
|
||||
|
||||
|
||||
if (a.to_upper() != "MOMONGA")
|
||||
return false;
|
||||
|
||||
|
||||
if (a.nocasecmp_to("momonga")!=0)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_13() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
|
||||
|
||||
|
||||
/* how can i embed UTF in here? */
|
||||
|
||||
|
||||
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
|
||||
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
|
||||
String s=ustr;
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
|
||||
s.parse_utf8( s.utf8().get_data() );
|
||||
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (s==ustr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_14() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
|
||||
|
||||
|
||||
String s = L"Primero Leche";
|
||||
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
|
||||
|
||||
|
||||
String t=s.ascii().get_data();
|
||||
return (s==t);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_15() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 15: substr\n");
|
||||
|
||||
|
||||
String s="Killer Baby";
|
||||
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
|
||||
|
||||
|
||||
return (s.substr(3,4)=="ler ");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_16() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 16: find\n");
|
||||
|
||||
|
||||
String s="Pretty Woman";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.find("tty")!=3)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.find("Revenge of the Monster Truck")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_17() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 17: find no case\n");
|
||||
|
||||
|
||||
String s="Pretty Whale";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_18() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 18: find no case\n");
|
||||
|
||||
|
||||
String s="Pretty Whale";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_19() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
|
||||
|
||||
|
||||
String s="Happy Birthday, Anna!";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
|
||||
|
||||
s=s.replace("Birthday","Halloween");
|
||||
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
|
||||
|
||||
|
||||
return (s=="Happy Halloween, Anna!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_20() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
|
||||
|
||||
|
||||
String s="Who is Frederic?";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
s=s.insert( s.find("?")," Chopin" );
|
||||
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
|
||||
|
||||
|
||||
return (s=="Who is Frederic Chopin?");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_21() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tPi is %f\n",33.141593);
|
||||
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
|
||||
|
||||
|
||||
return String::num(3.141593)=="3.141593";
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_22() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
|
||||
|
||||
|
||||
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
|
||||
static const int num[4]={ 1237461283, -22, 0, -1123412 };
|
||||
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
|
||||
|
||||
|
||||
if (String(nums[i]).to_int()!=num[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_23() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
|
||||
|
||||
|
||||
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
|
||||
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
|
||||
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
|
||||
|
||||
|
||||
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_24() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
|
||||
|
||||
|
||||
String s="Mars,Jupiter,Saturn,Uranus";
|
||||
|
||||
|
||||
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
|
||||
|
||||
|
||||
for (int i=0;i<s.get_slice_count(",");i++) {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
|
||||
|
||||
|
||||
|
||||
|
||||
if (s.get_slice(",",i)!=slices[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_25() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
|
||||
|
||||
|
||||
String s="Josephine is such a cute girl!";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\tRemoving \"cute\"\n");
|
||||
|
||||
|
||||
s.erase(s.find("cute "),String("cute ").length());
|
||||
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
|
||||
|
||||
|
||||
|
||||
|
||||
return (s=="Josephine is such a girl!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_26() {
|
||||
@ -516,7 +516,7 @@ bool test_28() {
|
||||
String format, output;
|
||||
Array args;
|
||||
bool error;
|
||||
|
||||
|
||||
// %%
|
||||
format = "fish %% frog";
|
||||
args.clear();
|
||||
@ -846,7 +846,7 @@ bool test_28() {
|
||||
typedef bool (*TestFunc)(void);
|
||||
|
||||
TestFunc test_funcs[] = {
|
||||
|
||||
|
||||
test_1,
|
||||
test_2,
|
||||
test_3,
|
||||
@ -876,18 +876,18 @@ TestFunc test_funcs[] = {
|
||||
test_27,
|
||||
test_28,
|
||||
0
|
||||
|
||||
|
||||
};
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
/** A character length != wchar_t may be forced, so the tests wont work */
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
|
||||
|
||||
|
||||
int count=0;
|
||||
int passed=0;
|
||||
|
||||
|
||||
while(true) {
|
||||
if (!test_funcs[count])
|
||||
break;
|
||||
@ -895,17 +895,17 @@ MainLoop* test() {
|
||||
if (pass)
|
||||
passed++;
|
||||
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
|
||||
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\n\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
OS::get_singleton()->print("***TOTALS!***\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
|
||||
|
||||
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -75,11 +75,11 @@ float Color::get_h() const {
|
||||
h = 2 + ( b - r ) / delta; // between cyan & yellow
|
||||
else
|
||||
h = 4 + ( r - g ) / delta; // between magenta & cyan
|
||||
|
||||
|
||||
h/=6.0;
|
||||
if (h<0)
|
||||
h+=1.0;
|
||||
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
p_h *=6.0;
|
||||
p_h = Math::fmod(p_h,6);
|
||||
i = Math::floor( p_h );
|
||||
|
||||
|
||||
f = p_h - i;
|
||||
p = p_v * ( 1 - p_s );
|
||||
q = p_v * ( 1 - p_s * f );
|
||||
@ -136,7 +136,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
g = p_v;
|
||||
b = p;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
r = p;
|
||||
g = p_v;
|
||||
b = t;
|
||||
@ -162,8 +162,8 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
void Color::invert() {
|
||||
|
||||
r=1.0-r;
|
||||
g=1.0-g;
|
||||
b=1.0-b;
|
||||
g=1.0-g;
|
||||
b=1.0-b;
|
||||
}
|
||||
void Color::contrast() {
|
||||
|
||||
@ -368,7 +368,7 @@ String Color::to_html(bool p_alpha) const {
|
||||
|
||||
float Color::gray() const {
|
||||
|
||||
return (r+g+b)/3.0;
|
||||
return (r+g+b)/3.0;
|
||||
}
|
||||
|
||||
Color::operator String() const {
|
||||
|
18
core/color.h
18
core/color.h
@ -37,13 +37,13 @@
|
||||
struct Color {
|
||||
|
||||
union {
|
||||
|
||||
|
||||
struct {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
};
|
||||
float components[4];
|
||||
};
|
||||
|
||||
@ -58,28 +58,28 @@ struct Color {
|
||||
float get_v() const;
|
||||
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
|
||||
|
||||
_FORCE_INLINE_ float& operator[](int idx) {
|
||||
_FORCE_INLINE_ float& operator[](int idx) {
|
||||
return components[idx];
|
||||
}
|
||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||
return components[idx];
|
||||
}
|
||||
|
||||
|
||||
void invert();
|
||||
void contrast();
|
||||
Color inverted() const;
|
||||
Color contrasted() const;
|
||||
|
||||
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
|
||||
|
||||
|
||||
Color res=*this;
|
||||
|
||||
|
||||
res.r+= (p_t * (p_b.r-r));
|
||||
res.g+= (p_t * (p_b.g-g));
|
||||
res.b+= (p_t * (p_b.b-b));
|
||||
res.a+= (p_t * (p_b.a-a));
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color blend(const Color& p_over) const {
|
||||
|
@ -76,7 +76,7 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
|
||||
CommandQueueMT::CommandQueueMT(bool p_sync){
|
||||
|
||||
read_ptr=0;
|
||||
write_ptr=0;
|
||||
write_ptr=0;
|
||||
mutex = Mutex::create();
|
||||
|
||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||
|
@ -47,69 +47,69 @@ class CommandQueueMT {
|
||||
};
|
||||
|
||||
struct CommandBase {
|
||||
|
||||
|
||||
virtual void call()=0;
|
||||
virtual ~CommandBase() {};
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M>
|
||||
struct Command0 : public CommandBase {
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(); }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1>
|
||||
struct Command1 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1); }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class P2>
|
||||
struct Command2 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3>
|
||||
struct Command3 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4>
|
||||
struct Command4 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3,p4); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5>
|
||||
struct Command5 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -117,13 +117,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6>
|
||||
struct Command6 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -132,13 +132,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
typename GetSimpleTypeT<P6>::type_t p6;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7>
|
||||
struct Command7 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -148,12 +148,12 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
typename GetSimpleTypeT<P6>::type_t p6;
|
||||
typename GetSimpleTypeT<P7>::type_t p7;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
|
||||
};
|
||||
|
||||
|
||||
/* comands that return */
|
||||
|
||||
|
||||
template<class T,class M,class R>
|
||||
struct CommandRet0 : public CommandBase {
|
||||
|
||||
@ -161,38 +161,38 @@ class CommandQueueMT {
|
||||
M method;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class R>
|
||||
struct CommandRet1 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class P2,class R>
|
||||
struct CommandRet2 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class R>
|
||||
struct CommandRet3 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -200,13 +200,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class R>
|
||||
struct CommandRet4 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -215,13 +215,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R>
|
||||
struct CommandRet5 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -231,13 +231,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R>
|
||||
struct CommandRet6 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -248,13 +248,13 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P6>::type_t p6;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R>
|
||||
struct CommandRet7 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
@ -266,9 +266,9 @@ class CommandQueueMT {
|
||||
typename GetSimpleTypeT<P7>::type_t p7;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
};
|
||||
|
||||
/** commands that don't return but sync */
|
||||
|
||||
@ -392,7 +392,7 @@ class CommandQueueMT {
|
||||
|
||||
/***** BASE *******/
|
||||
|
||||
enum {
|
||||
enum {
|
||||
COMMAND_MEM_SIZE_KB=256,
|
||||
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
|
||||
SYNC_SEMAPHORES=8
|
||||
@ -405,30 +405,30 @@ class CommandQueueMT {
|
||||
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
||||
Mutex *mutex;
|
||||
Semaphore *sync;
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
T* allocate() {
|
||||
|
||||
|
||||
// alloc size is size+T+safeguard
|
||||
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
|
||||
|
||||
|
||||
tryagain:
|
||||
|
||||
|
||||
if (write_ptr < read_ptr) {
|
||||
// behind read_ptr, check that there is room
|
||||
if ( (read_ptr-write_ptr) <= alloc_size )
|
||||
return NULL;
|
||||
} else if (write_ptr >= read_ptr) {
|
||||
// ahead of read_ptr, check that there is room
|
||||
|
||||
|
||||
|
||||
|
||||
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
|
||||
// no room at the end, wrap down;
|
||||
|
||||
|
||||
if (read_ptr==0) // dont want write_ptr to become read_ptr
|
||||
return NULL;
|
||||
|
||||
|
||||
// if this happens, it's a bug
|
||||
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
|
||||
// zero means, wrap to begining
|
||||
@ -447,147 +447,147 @@ class CommandQueueMT {
|
||||
T* cmd = memnew_placement( &command_mem[write_ptr], T );
|
||||
write_ptr+=sizeof(T);
|
||||
return cmd;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T* allocate_and_lock() {
|
||||
|
||||
|
||||
lock();
|
||||
T* ret;
|
||||
|
||||
|
||||
while ( (ret=allocate<T>())==NULL ) {
|
||||
|
||||
|
||||
unlock();
|
||||
// sleep a little until fetch happened and some room is made
|
||||
// sleep a little until fetch happened and some room is made
|
||||
wait_for_flush();
|
||||
lock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool flush_one() {
|
||||
|
||||
|
||||
tryagain:
|
||||
|
||||
|
||||
// tried to read an empty queue
|
||||
if (read_ptr == write_ptr )
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
|
||||
|
||||
|
||||
if (size==0) {
|
||||
//end of ringbuffer, wrap
|
||||
read_ptr=0;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
|
||||
read_ptr+=sizeof(uint32_t);
|
||||
|
||||
|
||||
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
|
||||
|
||||
|
||||
cmd->call();
|
||||
cmd->~CommandBase();
|
||||
|
||||
read_ptr+=size;
|
||||
|
||||
read_ptr+=size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
void wait_for_flush();
|
||||
SyncSemaphore* _alloc_sync_sem();
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/* NORMAL PUSH COMMANDS */
|
||||
|
||||
|
||||
template<class T, class M>
|
||||
void push( T * p_instance, M p_method ) {
|
||||
|
||||
|
||||
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1>
|
||||
void push( T * p_instance, M p_method, P1 p1 ) {
|
||||
|
||||
|
||||
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
|
||||
|
||||
|
||||
Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
|
||||
|
||||
|
||||
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
cmd->p3=p3;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
|
||||
|
||||
|
||||
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
cmd->p3=p3;
|
||||
cmd->p4=p4;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
|
||||
|
||||
|
||||
Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -595,17 +595,17 @@ public:
|
||||
cmd->p3=p3;
|
||||
cmd->p4=p4;
|
||||
cmd->p5=p5;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
|
||||
|
||||
|
||||
Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -614,17 +614,17 @@ public:
|
||||
cmd->p4=p4;
|
||||
cmd->p5=p5;
|
||||
cmd->p6=p6;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
|
||||
|
||||
|
||||
Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -634,19 +634,19 @@ public:
|
||||
cmd->p5=p5;
|
||||
cmd->p6=p6;
|
||||
cmd->p7=p7;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
/*** PUSH AND RET COMMANDS ***/
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T, class M,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, R* r_ret) {
|
||||
|
||||
|
||||
CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->ret=r_ret;
|
||||
@ -654,34 +654,34 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
|
||||
|
||||
|
||||
CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->ret=r_ret;
|
||||
SyncSemaphore *ss=_alloc_sync_sem();
|
||||
cmd->sync=ss;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
|
||||
|
||||
|
||||
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -691,16 +691,16 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
|
||||
|
||||
|
||||
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -711,16 +711,16 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
|
||||
|
||||
|
||||
CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -732,16 +732,16 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
|
||||
|
||||
|
||||
CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -754,16 +754,16 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
|
||||
|
||||
|
||||
CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -777,16 +777,16 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R>
|
||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
|
||||
|
||||
|
||||
CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
@ -801,7 +801,7 @@ public:
|
||||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
@ -975,12 +975,12 @@ public:
|
||||
ERR_FAIL_COND(!sync);
|
||||
sync->wait();
|
||||
lock();
|
||||
flush_one();
|
||||
flush_one();
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
void flush_all() {
|
||||
|
||||
|
||||
//ERR_FAIL_COND(sync);
|
||||
lock();
|
||||
while (true) {
|
||||
@ -990,10 +990,10 @@ public:
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
CommandQueueMT(bool p_sync);
|
||||
~CommandQueueMT();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
198
core/dvector.h
198
core/dvector.h
@ -43,18 +43,18 @@ template<class T>
|
||||
class DVector {
|
||||
|
||||
mutable MID mem;
|
||||
|
||||
|
||||
|
||||
|
||||
void copy_on_write() {
|
||||
|
||||
|
||||
if (!mem.is_valid())
|
||||
return;
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
MID_Lock lock( mem );
|
||||
|
||||
|
||||
|
||||
if ( *(int*)lock.data() == 1 ) {
|
||||
// one reference, means no refcount changes
|
||||
@ -62,114 +62,114 @@ class DVector {
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID new_mem= dynalloc( mem.get_size() );
|
||||
|
||||
|
||||
if (!new_mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
|
||||
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
|
||||
}
|
||||
|
||||
|
||||
MID_Lock dst_lock( new_mem );
|
||||
|
||||
|
||||
int *rc = (int*)dst_lock.data();
|
||||
|
||||
|
||||
*rc=1;
|
||||
|
||||
|
||||
T * dst = (T*)(rc + 1 );
|
||||
|
||||
|
||||
T * src =(T*) ((int*)lock.data() + 1 );
|
||||
|
||||
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
|
||||
memnew_placement( &dst[i], T(src[i]) );
|
||||
}
|
||||
|
||||
|
||||
(*(int*)lock.data())--;
|
||||
|
||||
|
||||
// unlock all
|
||||
dst_lock=MID_Lock();
|
||||
lock=MID_Lock();
|
||||
|
||||
|
||||
mem=new_mem;
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void reference( const DVector& p_dvector ) {
|
||||
|
||||
|
||||
unreference();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
if (!p_dvector.mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID_Lock lock(p_dvector.mem);
|
||||
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)++;
|
||||
|
||||
|
||||
lock = MID_Lock();
|
||||
mem=p_dvector.mem;
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void unreference() {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
if (!mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)--;
|
||||
|
||||
|
||||
if (*rc==0) {
|
||||
// no one else using it, destruct
|
||||
|
||||
|
||||
T * t= (T*)(rc+1);
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
lock = MID_Lock();
|
||||
|
||||
|
||||
mem = MID ();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
class Read {
|
||||
@ -177,10 +177,10 @@ public:
|
||||
MID_Lock lock;
|
||||
const T * mem;
|
||||
public:
|
||||
|
||||
|
||||
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
|
||||
_FORCE_INLINE_ const T *ptr() const { return mem; }
|
||||
|
||||
|
||||
Read() { mem=NULL; }
|
||||
};
|
||||
|
||||
@ -189,32 +189,32 @@ public:
|
||||
MID_Lock lock;
|
||||
T * mem;
|
||||
public:
|
||||
|
||||
|
||||
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
|
||||
_FORCE_INLINE_ T *ptr() { return mem; }
|
||||
|
||||
|
||||
Write() { mem=NULL; }
|
||||
};
|
||||
|
||||
|
||||
Read read() const {
|
||||
|
||||
|
||||
Read r;
|
||||
if (mem.is_valid()) {
|
||||
if (mem.is_valid()) {
|
||||
r.lock = MID_Lock( mem );
|
||||
r.mem = (const T*)((int*)r.lock.data()+1);
|
||||
}
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
Write write() {
|
||||
|
||||
|
||||
Write w;
|
||||
if (mem.is_valid()) {
|
||||
copy_on_write();
|
||||
w.lock = MID_Lock( mem );
|
||||
w.mem = (T*)((int*)w.lock.data()+1);
|
||||
}
|
||||
return w;
|
||||
return w;
|
||||
}
|
||||
|
||||
template<class MC>
|
||||
@ -280,12 +280,12 @@ public:
|
||||
|
||||
|
||||
bool is_locked() const { return mem.is_locked(); }
|
||||
|
||||
|
||||
inline const T operator[](int p_index) const;
|
||||
|
||||
Error resize(int p_size);
|
||||
|
||||
|
||||
|
||||
|
||||
void operator=(const DVector& p_dvector) { reference(p_dvector); }
|
||||
DVector() {}
|
||||
DVector(const DVector& p_dvector) { reference(p_dvector); }
|
||||
@ -308,7 +308,7 @@ T DVector<T>::get(int p_index) const {
|
||||
template<class T>
|
||||
void DVector<T>::set(int p_index, const T& p_val) {
|
||||
|
||||
if (p_index<0 || p_index>=size()) {
|
||||
if (p_index<0 || p_index>=size()) {
|
||||
ERR_FAIL_COND(p_index<0 || p_index>=size());
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ const T DVector<T>::operator[](int p_index) const {
|
||||
}
|
||||
|
||||
Read r = read();
|
||||
|
||||
|
||||
return r[p_index];
|
||||
}
|
||||
|
||||
@ -344,83 +344,83 @@ Error DVector<T>::resize(int p_size) {
|
||||
dvector_lock->lock();
|
||||
|
||||
bool same = p_size==size();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
|
||||
|
||||
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
|
||||
|
||||
if (same)
|
||||
return OK;
|
||||
|
||||
if (p_size == 0 ) {
|
||||
|
||||
|
||||
unreference();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
copy_on_write(); // make it unique
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
|
||||
|
||||
|
||||
if (p_size > size() ) {
|
||||
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
|
||||
MID_Lock lock;
|
||||
|
||||
|
||||
if (oldsize==0) {
|
||||
|
||||
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
|
||||
lock=MID_Lock(mem);
|
||||
int *rc = ((int*)lock.data());
|
||||
*rc=1;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||
|
||||
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
|
||||
}
|
||||
|
||||
lock=MID_Lock(mem);
|
||||
|
||||
lock=MID_Lock(mem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
T *t = (T*)((int*)lock.data() + 1);
|
||||
|
||||
|
||||
for (int i=oldsize;i<p_size;i++) {
|
||||
|
||||
|
||||
memnew_placement(&t[i], T );
|
||||
}
|
||||
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
} else {
|
||||
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
|
||||
|
||||
|
||||
T *t = (T*)((int*)lock.data() + 1);
|
||||
|
||||
|
||||
for (int i=p_size;i<oldsize;i++) {
|
||||
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
|
||||
|
||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
|
||||
|
||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -33,12 +33,12 @@
|
||||
/**
|
||||
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
|
||||
* inside the code. It is recommended to always return processable data, so in case of an error, the
|
||||
* engine can stay working well.
|
||||
* engine can stay working well.
|
||||
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
|
||||
* to fail or crash.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Pointer to the error macro priting function. Reassign to any function to have errors printed
|
||||
*/
|
||||
|
||||
@ -136,7 +136,7 @@ extern bool _err_error_exists;
|
||||
return m_retval; \
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the function will exit.
|
||||
*/
|
||||
|
||||
@ -146,7 +146,7 @@ extern bool _err_error_exists;
|
||||
return; \
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the function will exit.
|
||||
* This function returns an error value, if returning Error, please select the most
|
||||
* appropriate error condition from error_macros.h
|
||||
@ -158,7 +158,7 @@ extern bool _err_error_exists;
|
||||
return m_retval; \
|
||||
}else _err_error_exists=false; } \
|
||||
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the loop will skip to the next iteration.
|
||||
*/
|
||||
|
||||
@ -168,7 +168,7 @@ extern bool _err_error_exists;
|
||||
continue;\
|
||||
} else _err_error_exists=false;} \
|
||||
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||
* the loop will break
|
||||
*/
|
||||
|
||||
|
@ -43,118 +43,118 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
|
||||
args=2;
|
||||
else if (p_arg1.get_type()!=Variant::NIL)
|
||||
args=1;
|
||||
else
|
||||
else
|
||||
args=0;
|
||||
|
||||
|
||||
room_needed+=sizeof(Variant)*args;
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
||||
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
|
||||
ev->args=args;
|
||||
ev->instance_ID=p_instance_ID;
|
||||
ev->method=p_method;
|
||||
|
||||
|
||||
buffer_end+=sizeof(Event);
|
||||
|
||||
|
||||
if (args>=1) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg1;
|
||||
}
|
||||
|
||||
if (args>=2) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg2;
|
||||
}
|
||||
|
||||
if (args>=3) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg3;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (args>=4) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg4;
|
||||
}
|
||||
|
||||
if (args>=5) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg5;
|
||||
}
|
||||
|
||||
|
||||
if (buffer_max_used>buffer_end);
|
||||
buffer_max_used=buffer_end;
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void EventQueue::flush_events() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
Object *obj = ObjectDB::get_instance(event->instance_ID);
|
||||
|
||||
if (obj) {
|
||||
|
||||
if (obj) {
|
||||
// events don't expect a return value
|
||||
obj->call( event->method,
|
||||
obj->call( event->method,
|
||||
(event->args>=1) ? args[0] : Variant(),
|
||||
(event->args>=2) ? args[1] : Variant(),
|
||||
(event->args>=3) ? args[2] : Variant(),
|
||||
(event->args>=4) ? args[3] : Variant(),
|
||||
(event->args>=5) ? args[4] : Variant() );
|
||||
}
|
||||
|
||||
|
||||
if (event->args>=1) args[0].~Variant();
|
||||
if (event->args>=2) args[1].~Variant();
|
||||
if (event->args>=3) args[2].~Variant();
|
||||
if (event->args>=4) args[3].~Variant();
|
||||
if (event->args>=5) args[4].~Variant();
|
||||
event->~Event();
|
||||
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
|
||||
buffer_end=0; // reset buffer
|
||||
}
|
||||
|
||||
EventQueue::EventQueue(uint32_t p_buffer_size) {
|
||||
|
||||
|
||||
|
||||
buffer_end=0;
|
||||
buffer_max_used=0;
|
||||
buffer_size=p_buffer_size;
|
||||
event_buffer = memnew_arr( uint8_t, buffer_size );
|
||||
|
||||
|
||||
}
|
||||
EventQueue::~EventQueue() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
for (int i=0;i<event->args;i++)
|
||||
args[i].~Variant();
|
||||
event->~Event();
|
||||
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr(event_buffer);
|
||||
event_buffer=NULL;
|
||||
}
|
||||
|
@ -36,18 +36,18 @@
|
||||
class EventQueue {
|
||||
|
||||
enum {
|
||||
|
||||
|
||||
DEFAULT_EVENT_QUEUE_SIZE_KB=256
|
||||
};
|
||||
|
||||
struct Event {
|
||||
|
||||
|
||||
uint32_t instance_ID;
|
||||
StringName method;
|
||||
int args;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t *event_buffer;
|
||||
uint32_t buffer_end;
|
||||
uint32_t buffer_max_used;
|
||||
@ -57,7 +57,7 @@ public:
|
||||
|
||||
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
|
||||
void flush_events();
|
||||
|
||||
|
||||
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
|
||||
~EventQueue();
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
Globals *Globals::singleton=NULL;
|
||||
|
||||
Globals *Globals::get_singleton() {
|
||||
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ bool Globals::is_persisting(const String& p_name) const {
|
||||
|
||||
|
||||
String Globals::globalize_path(const String& p_path) const {
|
||||
|
||||
|
||||
if (p_path.begins_with("res://")) {
|
||||
|
||||
if (resource_path != "") {
|
||||
@ -125,7 +125,7 @@ String Globals::globalize_path(const String& p_path) const {
|
||||
bool Globals::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
if (p_value.get_type()==Variant::NIL)
|
||||
props.erase(p_name);
|
||||
else {
|
||||
@ -174,7 +174,7 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
return false;
|
||||
r_ret=props[p_name].variant;
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct _VCSort {
|
||||
@ -188,13 +188,13 @@ struct _VCSort {
|
||||
};
|
||||
|
||||
void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Set<_VCSort> vclist;
|
||||
|
||||
|
||||
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
|
||||
|
||||
|
||||
const VariantContainer *v=&E->get();
|
||||
|
||||
if (v->hide_from_editor)
|
||||
@ -250,7 +250,7 @@ bool Globals::_load_resource_pack(const String& p_pack) {
|
||||
Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||
|
||||
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point
|
||||
|
||||
|
||||
//_load_settings(p_path+"/override.cfg");
|
||||
|
||||
if (p_main_pack!="") {
|
||||
@ -292,7 +292,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (FileAccessNetworkClient::get_singleton()) {
|
||||
|
||||
@ -332,7 +332,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||
resource_path = p_path;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
d->change_dir(p_path);
|
||||
|
||||
String candidate = d->get_current_dir();
|
||||
@ -395,7 +395,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||
}
|
||||
|
||||
bool Globals::has(String p_var) const {
|
||||
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return props.has(p_var);
|
||||
@ -1410,7 +1410,7 @@ void Globals::_bind_methods() {
|
||||
}
|
||||
|
||||
Globals::Globals() {
|
||||
|
||||
|
||||
|
||||
singleton=this;
|
||||
last_order=0;
|
||||
@ -1531,7 +1531,7 @@ Globals::Globals() {
|
||||
|
||||
|
||||
Globals::~Globals() {
|
||||
|
||||
|
||||
singleton=NULL;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
class Globals : public Object {
|
||||
|
||||
|
||||
OBJ_TYPE( Globals, Object );
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
@ -77,13 +77,13 @@ protected:
|
||||
bool using_datapack;
|
||||
List<String> input_presets;
|
||||
|
||||
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
|
||||
static Globals *singleton;
|
||||
|
||||
|
||||
Error _load_settings(const String p_path);
|
||||
Error _load_settings_binary(const String p_path);
|
||||
|
||||
@ -101,7 +101,7 @@ protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
|
||||
bool has(String p_var) const;
|
||||
String localize_path(const String& p_path) const;
|
||||
String globalize_path(const String& p_path) const;
|
||||
@ -110,13 +110,13 @@ public:
|
||||
bool is_persisting(const String& p_name) const;
|
||||
|
||||
String get_resource_path() const;
|
||||
|
||||
|
||||
static Globals *get_singleton();
|
||||
|
||||
void clear(const String& p_name);
|
||||
int get_order(const String& p_name) const;
|
||||
void set_order(const String& p_name, int p_order);
|
||||
|
||||
|
||||
Error setup(const String& p_path, const String &p_main_pack);
|
||||
|
||||
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
|
||||
@ -141,7 +141,7 @@ public:
|
||||
|
||||
void set_registering_order(bool p_registering);
|
||||
|
||||
Globals();
|
||||
Globals();
|
||||
~Globals();
|
||||
|
||||
};
|
||||
|
330
core/hash_map.h
330
core/hash_map.h
@ -38,7 +38,7 @@
|
||||
|
||||
class HashMapHahserDefault {
|
||||
public:
|
||||
|
||||
|
||||
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
|
||||
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
|
||||
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
|
||||
@ -66,8 +66,8 @@ public:
|
||||
|
||||
/**
|
||||
* @class HashMap
|
||||
* @author Juan Linietsky <reduzio@gmail.com>
|
||||
*
|
||||
* @author Juan Linietsky <reduzio@gmail.com>
|
||||
*
|
||||
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
|
||||
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
|
||||
* your own.
|
||||
@ -77,213 +77,213 @@ public:
|
||||
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
|
||||
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
|
||||
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
|
||||
class HashMap {
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
struct Pair {
|
||||
|
||||
|
||||
TKey key;
|
||||
TData data;
|
||||
|
||||
|
||||
Pair() {}
|
||||
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
|
||||
|
||||
uint32_t hash;
|
||||
Entry *next;
|
||||
Pair pair;
|
||||
|
||||
|
||||
Entry() { next=0; }
|
||||
};
|
||||
|
||||
|
||||
Entry **hash_table;
|
||||
uint8_t hash_table_power;
|
||||
uint32_t elements;
|
||||
|
||||
|
||||
void make_hash_table() {
|
||||
|
||||
|
||||
ERR_FAIL_COND( hash_table );
|
||||
|
||||
|
||||
|
||||
|
||||
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
|
||||
|
||||
|
||||
hash_table_power = MIN_HASH_TABLE_POWER;
|
||||
elements=0;
|
||||
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
|
||||
hash_table[i]=0;
|
||||
}
|
||||
|
||||
|
||||
void erase_hash_table() {
|
||||
|
||||
|
||||
ERR_FAIL_COND(elements);
|
||||
|
||||
|
||||
memdelete_arr( hash_table );
|
||||
hash_table=0;
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
void check_hash_table() {
|
||||
|
||||
int new_hash_table_power=-1;
|
||||
|
||||
|
||||
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
|
||||
/* rehash up */
|
||||
new_hash_table_power=hash_table_power+1;
|
||||
|
||||
|
||||
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
|
||||
|
||||
|
||||
new_hash_table_power++;
|
||||
}
|
||||
|
||||
|
||||
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
|
||||
|
||||
|
||||
/* rehash down */
|
||||
new_hash_table_power=hash_table_power-1;
|
||||
|
||||
|
||||
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
|
||||
|
||||
|
||||
new_hash_table_power--;
|
||||
}
|
||||
|
||||
|
||||
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
|
||||
new_hash_table_power=MIN_HASH_TABLE_POWER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (new_hash_table_power==-1)
|
||||
return;
|
||||
|
||||
|
||||
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
|
||||
if (!new_hash_table) {
|
||||
|
||||
|
||||
ERR_PRINT("Out of Memory");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<(1<<new_hash_table_power);i++) {
|
||||
|
||||
|
||||
new_hash_table[i]=0;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
while( hash_table[i] ) {
|
||||
|
||||
|
||||
Entry *se=hash_table[i];
|
||||
hash_table[i]=se->next;
|
||||
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
|
||||
se->next=new_hash_table[new_pos];
|
||||
new_hash_table[new_pos]=se;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (hash_table)
|
||||
memdelete_arr( hash_table );
|
||||
hash_table=new_hash_table;
|
||||
hash_table_power=new_hash_table_power;
|
||||
hash_table_power=new_hash_table_power;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* I want to have only one function.. */
|
||||
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
|
||||
|
||||
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
|
||||
|
||||
Entry *e = hash_table[index];
|
||||
|
||||
|
||||
while (e) {
|
||||
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && e->pair.key == p_key ) {
|
||||
|
||||
|
||||
/* the pair exists in this hashtable, so just update data */
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Entry * create_entry(const TKey& p_key) {
|
||||
|
||||
|
||||
/* if entry doesn't exist, create it */
|
||||
Entry *e = memnew( Entry );
|
||||
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
e->next = hash_table[index];
|
||||
e->next = hash_table[index];
|
||||
e->hash = hash;
|
||||
e->pair.key=p_key;
|
||||
|
||||
|
||||
hash_table[index]=e;
|
||||
elements++;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void copy_from(const HashMap& p_t) {
|
||||
|
||||
|
||||
if (&p_t==this)
|
||||
return; /* much less bother with that */
|
||||
|
||||
|
||||
clear();
|
||||
|
||||
|
||||
if (!p_t.hash_table || p_t.hash_table_power==0)
|
||||
return; /* not copying from empty table */
|
||||
|
||||
|
||||
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
|
||||
hash_table_power=p_t.hash_table_power;
|
||||
elements=p_t.elements;
|
||||
|
||||
|
||||
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
|
||||
|
||||
|
||||
hash_table[i]=NULL;
|
||||
/* elements will be in the reverse order, but it doesn't matter */
|
||||
|
||||
|
||||
const Entry *e = p_t.hash_table[i];
|
||||
|
||||
|
||||
while(e) {
|
||||
|
||||
|
||||
Entry *le = memnew( Entry ); /* local entry */
|
||||
|
||||
|
||||
*le=*e; /* copy data */
|
||||
|
||||
|
||||
/* add to list and reassign pointers */
|
||||
le->next=hash_table[i];
|
||||
hash_table[i]=le;
|
||||
|
||||
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
void set( const TKey& p_key, const TData& p_data ) {
|
||||
|
||||
|
||||
set( Pair( p_key, p_data ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void set( const Pair& p_pair ) {
|
||||
|
||||
Entry *e=NULL;
|
||||
@ -291,63 +291,63 @@ public:
|
||||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
e = const_cast<Entry*>( get_entry(p_pair.key) );
|
||||
|
||||
|
||||
/* if we made it up to here, the pair doesn't exist, create and assign */
|
||||
|
||||
|
||||
if (!e) {
|
||||
|
||||
|
||||
e=create_entry(p_pair.key);
|
||||
if (!e)
|
||||
return;
|
||||
check_hash_table(); // perform mantenience routine
|
||||
}
|
||||
|
||||
|
||||
e->pair.data = p_pair.data;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool has( const TKey& p_key ) const {
|
||||
|
||||
|
||||
return getptr(p_key)!=NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a key from data, return a const reference.
|
||||
* Get a key from data, return a const reference.
|
||||
* WARNING: this doesn't check errors, use either getptr and check NULL, or check
|
||||
* first with has(key)
|
||||
*/
|
||||
|
||||
|
||||
const TData& get( const TKey& p_key ) const {
|
||||
|
||||
|
||||
const TData* res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res,*res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
|
||||
TData& get( const TKey& p_key ) {
|
||||
|
||||
|
||||
TData* res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res,*res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as get, except it can return NULL when item was not found.
|
||||
* This is mainly used for speed purposes.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
|
||||
|
||||
|
||||
if (!hash_table)
|
||||
return NULL;
|
||||
|
||||
|
||||
Entry *e=const_cast<Entry*>(get_entry(p_key ));
|
||||
|
||||
|
||||
if (e)
|
||||
return &e->pair.data;
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
@ -427,108 +427,108 @@ public:
|
||||
/**
|
||||
* Erase an item, return true if erasing was succesful
|
||||
*/
|
||||
|
||||
|
||||
bool erase( const TKey& p_key ) {
|
||||
|
||||
|
||||
if (!hash_table)
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
|
||||
|
||||
|
||||
|
||||
Entry *e = hash_table[index];
|
||||
Entry *p=NULL;
|
||||
while (e) {
|
||||
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && e->pair.key == p_key ) {
|
||||
|
||||
|
||||
if (p) {
|
||||
|
||||
|
||||
p->next=e->next;
|
||||
} else {
|
||||
} else {
|
||||
//begin of list
|
||||
hash_table[index]=e->next;
|
||||
}
|
||||
|
||||
|
||||
memdelete(e);
|
||||
elements--;
|
||||
|
||||
|
||||
if (elements==0)
|
||||
erase_hash_table();
|
||||
else
|
||||
check_hash_table();
|
||||
check_hash_table();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
p=e;
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline const TData& operator[](const TKey& p_key) const { //constref
|
||||
|
||||
|
||||
return get(p_key);
|
||||
}
|
||||
inline TData& operator[](const TKey& p_key ) { //assignment
|
||||
|
||||
|
||||
Entry *e=NULL;
|
||||
if (!hash_table)
|
||||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
e = const_cast<Entry*>( get_entry(p_key) );
|
||||
|
||||
|
||||
/* if we made it up to here, the pair doesn't exist, create */
|
||||
if (!e) {
|
||||
|
||||
|
||||
e=create_entry(p_key);
|
||||
if (!e)
|
||||
return *(TData*)NULL; /* panic! */
|
||||
check_hash_table(); // perform mantenience routine
|
||||
}
|
||||
|
||||
|
||||
return e->pair.data;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next key to p_key, and the first key if p_key is null.
|
||||
|
||||
/**
|
||||
* Get the next key to p_key, and the first key if p_key is null.
|
||||
* Returns a pointer to the next key if found, NULL otherwise.
|
||||
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* const TKey *k=NULL;
|
||||
*
|
||||
*
|
||||
* while( (k=table.next(k)) ) {
|
||||
*
|
||||
*
|
||||
* print( *k );
|
||||
* }
|
||||
*
|
||||
*
|
||||
*/
|
||||
const TKey* next(const TKey* p_key) const {
|
||||
|
||||
|
||||
if (!hash_table) return NULL;
|
||||
|
||||
|
||||
if (!p_key) { /* get the first key */
|
||||
|
||||
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
}
|
||||
|
||||
} else { /* get the next key */
|
||||
|
||||
|
||||
const Entry *e = get_entry( *p_key );
|
||||
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
|
||||
|
||||
|
||||
if (e->next) {
|
||||
/* if there is a "next" in the list, return that */
|
||||
return &e->next->pair.key;
|
||||
@ -537,60 +537,60 @@ public:
|
||||
uint32_t index = e->hash&((1<<hash_table_power)-1);
|
||||
index++;
|
||||
for (int i=index;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* nothing found, was at end */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return NULL; /* nothing found */
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int size() const {
|
||||
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
|
||||
inline bool empty() const {
|
||||
|
||||
|
||||
return elements==0;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
|
||||
|
||||
/* clean up */
|
||||
if (hash_table) {
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
while (hash_table[i]) {
|
||||
|
||||
|
||||
Entry *e=hash_table[i];
|
||||
hash_table[i]=e->next;
|
||||
memdelete( e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr( hash_table );
|
||||
}
|
||||
|
||||
|
||||
hash_table=0;
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void operator=(const HashMap& p_table) {
|
||||
|
||||
|
||||
copy_from(p_table);
|
||||
}
|
||||
|
||||
HashMap() {
|
||||
|
||||
HashMap() {
|
||||
hash_table=NULL;
|
||||
elements=0;
|
||||
hash_table_power=0;
|
||||
@ -609,18 +609,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
HashMap(const HashMap& p_table) {
|
||||
|
||||
HashMap(const HashMap& p_table) {
|
||||
|
||||
hash_table=NULL;
|
||||
elements=0;
|
||||
hash_table_power=0;
|
||||
|
||||
|
||||
copy_from(p_table);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
~HashMap() {
|
||||
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
|
||||
const unsigned char* chr=(const unsigned char*)p_cstr;
|
||||
uint32_t hash = 5381;
|
||||
uint32_t c;
|
||||
|
||||
|
||||
while ((c = *chr++))
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ static inline uint32_t make_uint32_t(T p_in) {
|
||||
T t;
|
||||
uint32_t _u32;
|
||||
} _u;
|
||||
_u._u32=0;
|
||||
_u._u32=0;
|
||||
_u.t=p_in;
|
||||
return _u._u32;
|
||||
}
|
||||
@ -106,7 +106,7 @@ static inline uint64_t make_uint64_t(T p_in) {
|
||||
uint64_t _u64;
|
||||
} _u;
|
||||
_u._u64=0; // in case p_in is smaller
|
||||
|
||||
|
||||
_u.t=p_in;
|
||||
return _u._u64;
|
||||
}
|
||||
|
120
core/image.cpp
120
core/image.cpp
@ -382,7 +382,7 @@ void Image::convert( Format p_new_format ){
|
||||
|
||||
|
||||
Image new_img(width,height,0,p_new_format);
|
||||
|
||||
|
||||
int len=data.size();
|
||||
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
@ -413,7 +413,7 @@ void Image::convert( Format p_new_format ){
|
||||
w = DVector<uint8_t>::Write();
|
||||
|
||||
bool gen_mipmaps=mipmaps>0;
|
||||
|
||||
|
||||
*this=new_img;
|
||||
|
||||
if (gen_mipmaps)
|
||||
@ -643,13 +643,13 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) {
|
||||
ERR_FAIL_COND(p_height<=0);
|
||||
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||
|
||||
|
||||
|
||||
if (p_width==width && p_height==height)
|
||||
return;
|
||||
|
||||
|
||||
Image dst( p_width, p_height, 0, format );
|
||||
|
||||
|
||||
if (format==FORMAT_INDEXED)
|
||||
p_interpolation=INTERPOLATE_NEAREST;
|
||||
|
||||
@ -714,34 +714,34 @@ void Image::crop( int p_width, int p_height ) {
|
||||
ERR_FAIL_COND(p_height<=0);
|
||||
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||
|
||||
|
||||
/* to save memory, cropping should be done in-place, however, since this function
|
||||
will most likely either not be used much, or in critical areas, for now it wont, because
|
||||
it's a waste of time. */
|
||||
|
||||
if (p_width==width && p_height==height)
|
||||
return;
|
||||
|
||||
|
||||
Image dst( p_width, p_height,0, format );
|
||||
|
||||
|
||||
|
||||
for (int y=0;y<p_height;y++) {
|
||||
|
||||
|
||||
for (int x=0;x<p_width;x++) {
|
||||
|
||||
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
|
||||
dst.put_pixel(x,y,col);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mipmaps>0)
|
||||
dst.generate_mipmaps();
|
||||
*this=dst;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Image::flip_y() {
|
||||
|
||||
|
||||
if (!_can_modify(format)) {
|
||||
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
|
||||
ERR_FAIL();
|
||||
@ -756,12 +756,12 @@ void Image::flip_y() {
|
||||
|
||||
|
||||
for (int y=0;y<(height/2);y++) {
|
||||
|
||||
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
Color up = get_pixel(x,y);
|
||||
Color down = get_pixel(x,height-y-1);
|
||||
|
||||
|
||||
put_pixel(x,y,down);
|
||||
put_pixel(x,height-y-1,up);
|
||||
}
|
||||
@ -783,12 +783,12 @@ void Image::flip_x() {
|
||||
clear_mipmaps();;
|
||||
|
||||
for (int y=0;y<(height/2);y++) {
|
||||
|
||||
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
|
||||
Color up = get_pixel(x,y);
|
||||
Color down = get_pixel(width-x-1,y);
|
||||
|
||||
|
||||
put_pixel(x,y,down);
|
||||
put_pixel(width-x-1,y,up);
|
||||
}
|
||||
@ -1040,26 +1040,26 @@ void Image::make_normalmap(float p_height_scale) {
|
||||
}
|
||||
|
||||
ERR_FAIL_COND( empty() );
|
||||
|
||||
|
||||
Image normalmap(width,height,0, FORMAT_RGB);
|
||||
/*
|
||||
for (int y=0;y<height;y++) {
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
|
||||
float center=get_pixel(x,y).gray()/255.0;
|
||||
float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center;
|
||||
float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center;
|
||||
float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center;
|
||||
float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center;
|
||||
|
||||
|
||||
|
||||
|
||||
// uhm, how do i do this? ....
|
||||
|
||||
|
||||
Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) );
|
||||
|
||||
|
||||
normalmap.put_pixel( x, y, result );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
*this=normalmap;
|
||||
@ -1071,14 +1071,14 @@ bool Image::empty() const {
|
||||
}
|
||||
|
||||
DVector<uint8_t> Image::get_data() const {
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) {
|
||||
|
||||
|
||||
int mm=0;
|
||||
int mm=0;
|
||||
int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0);
|
||||
data.resize( size );
|
||||
{
|
||||
@ -1095,7 +1095,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format
|
||||
}
|
||||
|
||||
void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) {
|
||||
|
||||
|
||||
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
|
||||
ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT);
|
||||
|
||||
@ -1108,48 +1108,48 @@ void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, co
|
||||
ERR_FAIL_COND(p_data.size()!=size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
height=p_height;
|
||||
width=p_width;
|
||||
format=p_format;
|
||||
data=p_data;
|
||||
data=p_data;
|
||||
mipmaps=p_mipmaps;
|
||||
}
|
||||
|
||||
|
||||
void Image::create( const char ** p_xpm ) {
|
||||
|
||||
|
||||
|
||||
int size_width,size_height;
|
||||
int pixelchars=0;
|
||||
mipmaps=0;
|
||||
bool has_alpha=false;
|
||||
|
||||
|
||||
enum Status {
|
||||
READING_HEADER,
|
||||
READING_COLORS,
|
||||
READING_PIXELS,
|
||||
DONE
|
||||
};
|
||||
|
||||
|
||||
Status status = READING_HEADER;
|
||||
int line=0;
|
||||
|
||||
|
||||
HashMap<String,Color> colormap;
|
||||
int colormap_size;
|
||||
|
||||
|
||||
while (status!=DONE) {
|
||||
|
||||
|
||||
const char * line_ptr = p_xpm[line];
|
||||
|
||||
|
||||
|
||||
|
||||
switch (status) {
|
||||
|
||||
|
||||
case READING_HEADER: {
|
||||
|
||||
|
||||
String line_str=line_ptr;
|
||||
line_str.replace("\t"," ");
|
||||
|
||||
|
||||
size_width=line_str.get_slicec(' ',0).to_int();
|
||||
size_height=line_str.get_slicec(' ',1).to_int();
|
||||
colormap_size=line_str.get_slicec(' ',2).to_int();
|
||||
@ -1161,10 +1161,10 @@ void Image::create( const char ** p_xpm ) {
|
||||
status=READING_COLORS;
|
||||
} break;
|
||||
case READING_COLORS: {
|
||||
|
||||
|
||||
String colorstring;
|
||||
for (int i=0;i<pixelchars;i++) {
|
||||
|
||||
|
||||
colorstring+=*line_ptr;
|
||||
line_ptr++;
|
||||
}
|
||||
@ -1175,25 +1175,25 @@ void Image::create( const char ** p_xpm ) {
|
||||
line_ptr++;
|
||||
}
|
||||
if (*line_ptr=='c') {
|
||||
|
||||
|
||||
line_ptr++;
|
||||
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
|
||||
if (*line_ptr==0)
|
||||
break;
|
||||
line_ptr++;
|
||||
}
|
||||
|
||||
|
||||
if (*line_ptr=='#') {
|
||||
line_ptr++;
|
||||
uint8_t col_r;
|
||||
uint8_t col_g;
|
||||
uint8_t col_b;
|
||||
// uint8_t col_a=255;
|
||||
|
||||
|
||||
for (int i=0;i<6;i++) {
|
||||
|
||||
|
||||
char v = line_ptr[i];
|
||||
|
||||
|
||||
if (v>='0' && v<='9')
|
||||
v-='0';
|
||||
else if (v>='A' && v<='F')
|
||||
@ -1202,7 +1202,7 @@ void Image::create( const char ** p_xpm ) {
|
||||
v=(v-'a')+10;
|
||||
else
|
||||
break;
|
||||
|
||||
|
||||
switch(i) {
|
||||
case 0: col_r=v<<4; break;
|
||||
case 1: col_r|=v; break;
|
||||
@ -1211,48 +1211,48 @@ void Image::create( const char ** p_xpm ) {
|
||||
case 4: col_b=v<<4; break;
|
||||
case 5: col_b|=v; break;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// magenta mask
|
||||
if (col_r==255 && col_g==0 && col_b==255) {
|
||||
|
||||
|
||||
colormap[colorstring]=Color(0,0,0,0);
|
||||
has_alpha=true;
|
||||
} else {
|
||||
|
||||
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (line==colormap_size) {
|
||||
|
||||
|
||||
status=READING_PIXELS;
|
||||
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
|
||||
}
|
||||
} break;
|
||||
case READING_PIXELS: {
|
||||
|
||||
|
||||
int y=line-colormap_size-1;
|
||||
for (int x=0;x<size_width;x++) {
|
||||
|
||||
|
||||
char pixelstr[6]={0,0,0,0,0,0};
|
||||
for (int i=0;i<pixelchars;i++)
|
||||
pixelstr[i]=line_ptr[x*pixelchars+i];
|
||||
|
||||
|
||||
Color *colorptr = colormap.getptr(pixelstr);
|
||||
ERR_FAIL_COND(!colorptr);
|
||||
put_pixel(x,y,*colorptr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (y==(size_height-1))
|
||||
status=DONE;
|
||||
} break;
|
||||
default:{}
|
||||
}
|
||||
|
||||
|
||||
line++;
|
||||
}
|
||||
}
|
||||
@ -2022,7 +2022,7 @@ Image Image::compressed(int p_mode) {
|
||||
};
|
||||
|
||||
Image::Image(const char **p_xpm) {
|
||||
|
||||
|
||||
width=0;
|
||||
height=0;
|
||||
mipmaps=0;
|
||||
|
52
core/image.h
52
core/image.h
@ -46,7 +46,7 @@ typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
|
||||
|
||||
class Image {
|
||||
|
||||
enum {
|
||||
enum {
|
||||
MAX_WIDTH=16384, // force a limit somehow
|
||||
MAX_HEIGHT=16384// force a limit somehow
|
||||
};
|
||||
@ -55,12 +55,12 @@ public:
|
||||
static SavePNGFunc save_png_func;
|
||||
|
||||
enum Format {
|
||||
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
|
||||
FORMAT_INTENSITY, ///< one byte per pixel, 0-255
|
||||
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
|
||||
FORMAT_RGB, ///< one byte R, one byte G, one byte B
|
||||
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
|
||||
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
|
||||
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
|
||||
FORMAT_INTENSITY, ///< one byte per pixel, 0-255
|
||||
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
|
||||
FORMAT_RGB, ///< one byte R, one byte G, one byte B
|
||||
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
|
||||
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
|
||||
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
|
||||
FORMAT_YUV_422,
|
||||
FORMAT_YUV_444,
|
||||
@ -89,7 +89,7 @@ public:
|
||||
|
||||
static const char* format_names[FORMAT_MAX];
|
||||
enum Interpolation {
|
||||
|
||||
|
||||
INTERPOLATE_NEAREST,
|
||||
INTERPOLATE_BILINEAR,
|
||||
INTERPOLATE_CUBIC,
|
||||
@ -186,7 +186,7 @@ private:
|
||||
DVector<uint8_t> data;
|
||||
int width,height,mipmaps;
|
||||
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
|
||||
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
|
||||
@ -207,7 +207,7 @@ public:
|
||||
int get_width() const; ///< Get image width
|
||||
int get_height() const; ///< Get image height
|
||||
int get_mipmaps() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
|
||||
* value.
|
||||
@ -217,7 +217,7 @@ public:
|
||||
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
|
||||
*/
|
||||
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
|
||||
|
||||
|
||||
/**
|
||||
* Convert the image to another format, as close as it can be done.
|
||||
*/
|
||||
@ -230,7 +230,7 @@ public:
|
||||
ret.convert((Format)p_new_format);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the current image format.
|
||||
*/
|
||||
@ -243,7 +243,7 @@ public:
|
||||
/**
|
||||
* Resize the image, using the prefered interpolation method.
|
||||
* Indexed-Color images always use INTERPOLATE_NEAREST.
|
||||
*/
|
||||
*/
|
||||
|
||||
void resize_to_po2(bool p_square=false);
|
||||
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
|
||||
@ -252,22 +252,22 @@ public:
|
||||
* Crop the image to a specific size, if larger, then the image is filled by black
|
||||
*/
|
||||
void crop( int p_width, int p_height );
|
||||
|
||||
|
||||
|
||||
|
||||
void flip_x();
|
||||
void flip_y();
|
||||
/**
|
||||
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
|
||||
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
|
||||
*/
|
||||
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
|
||||
|
||||
void clear_mipmaps();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate a normal map from a grayscale image
|
||||
*/
|
||||
|
||||
|
||||
void make_normalmap(float p_height_scale=1.0);
|
||||
|
||||
/**
|
||||
@ -276,26 +276,26 @@ public:
|
||||
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
||||
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
||||
|
||||
void create( const char ** p_xpm );
|
||||
void create( const char ** p_xpm );
|
||||
/**
|
||||
* returns true when the image is empty (0,0) in size
|
||||
*/
|
||||
bool empty() const;
|
||||
|
||||
|
||||
DVector<uint8_t> get_data() const;
|
||||
|
||||
|
||||
Error load(const String& p_path);
|
||||
Error save_png(const String& p_path);
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* create an empty image
|
||||
*/
|
||||
Image();
|
||||
/**
|
||||
/**
|
||||
* create an empty image of a specific size and format
|
||||
*/
|
||||
Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
||||
/**
|
||||
/**
|
||||
* import an image of a specific size and format from a pointer
|
||||
*/
|
||||
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
||||
@ -313,7 +313,7 @@ public:
|
||||
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
|
||||
void set_pallete(const DVector<uint8_t>& p_data);
|
||||
|
||||
|
||||
|
||||
static int get_format_pixel_size(Format p_format);
|
||||
static int get_format_pixel_rshift(Format p_format);
|
||||
static int get_format_pallete_size(Format p_format);
|
||||
|
@ -38,7 +38,7 @@ void InputMap::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
|
||||
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
|
||||
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
|
||||
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
|
||||
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
/*
|
||||
* Byte-oriented AES-256 implementation.
|
||||
* All lookup tables replaced with 'on the fly' calculations.
|
||||
* All lookup tables replaced with 'on the fly' calculations.
|
||||
*
|
||||
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
|
||||
* Other contributors: Hal Finney
|
||||
@ -24,14 +24,14 @@
|
||||
#include "typedefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[32];
|
||||
uint8_t enckey[32];
|
||||
uint8_t key[32];
|
||||
uint8_t enckey[32];
|
||||
uint8_t deckey[32];
|
||||
} aes256_context;
|
||||
} aes256_context;
|
||||
|
||||
|
||||
void aes256_init(aes256_context *, uint8_t * /* key */);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
@ -40,11 +40,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
@ -56,9 +56,9 @@ extern "C" {
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
@ -67,14 +67,14 @@ int fastlz_compress(const void* input, int length, void* output);
|
||||
more than what is specified in maxout.
|
||||
*/
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
@ -82,14 +82,14 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
only level 1 and level 2 are supported.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
|
@ -33,17 +33,17 @@
|
||||
#include "error_macros.h"
|
||||
|
||||
Error FileAccessBuffered::set_error(Error p_error) const {
|
||||
|
||||
|
||||
return (last_error = p_error);
|
||||
};
|
||||
|
||||
void FileAccessBuffered::set_cache_size(int p_size) {
|
||||
|
||||
|
||||
cache_size = p_size;
|
||||
};
|
||||
|
||||
int FileAccessBuffered::get_cache_size() {
|
||||
|
||||
|
||||
return cache_size;
|
||||
};
|
||||
|
||||
@ -66,27 +66,27 @@ int FileAccessBuffered::cache_data_left() const {
|
||||
};
|
||||
|
||||
void FileAccessBuffered::seek(size_t p_position) {
|
||||
|
||||
|
||||
file.offset = p_position;
|
||||
};
|
||||
|
||||
void FileAccessBuffered::seek_end(int64_t p_position) {
|
||||
|
||||
|
||||
file.offset = file.size + p_position;
|
||||
};
|
||||
|
||||
size_t FileAccessBuffered::get_pos() const {
|
||||
|
||||
|
||||
return file.offset;
|
||||
};
|
||||
|
||||
size_t FileAccessBuffered::get_len() const {
|
||||
|
||||
|
||||
return file.size;
|
||||
};
|
||||
|
||||
bool FileAccessBuffered::eof_reached() const {
|
||||
|
||||
|
||||
return file.offset > file.size;
|
||||
};
|
||||
|
||||
@ -165,12 +165,12 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
|
||||
};
|
||||
|
||||
bool FileAccessBuffered::is_open() const {
|
||||
|
||||
|
||||
return file.open;
|
||||
};
|
||||
|
||||
Error FileAccessBuffered::get_error() const {
|
||||
|
||||
|
||||
return last_error;
|
||||
};
|
||||
|
||||
@ -180,5 +180,5 @@ FileAccessBuffered::FileAccessBuffered() {
|
||||
};
|
||||
|
||||
FileAccessBuffered::~FileAccessBuffered(){
|
||||
|
||||
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ protected:
|
||||
String name;
|
||||
int access_flags;
|
||||
} file;
|
||||
|
||||
|
||||
mutable struct Cache {
|
||||
|
||||
|
||||
Vector<uint8_t> buffer;
|
||||
int offset;
|
||||
} cache;
|
||||
@ -71,7 +71,7 @@ protected:
|
||||
|
||||
void set_cache_size(int p_size);
|
||||
int get_cache_size();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual size_t get_pos() const; ///< get position in the file
|
||||
|
@ -217,7 +217,7 @@ Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const Str
|
||||
return ERR_CANT_CONNECT;
|
||||
}
|
||||
|
||||
CharString cs = p_password.utf8();
|
||||
CharString cs = p_password.utf8();
|
||||
put_32(cs.length());
|
||||
client->put_data((const uint8_t*)cs.ptr(),cs.length());
|
||||
|
||||
|
@ -309,7 +309,7 @@ Error HTTPClient::poll(){
|
||||
String header = responses[i].strip_edges();
|
||||
String s = header.to_lower();
|
||||
if (s.length()==0)
|
||||
continue;
|
||||
continue;
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
|
||||
body_left=body_size;
|
||||
|
@ -30,16 +30,16 @@
|
||||
|
||||
#include "print_string.h"
|
||||
bool ImageFormatLoader::recognize(const String& p_extension) const {
|
||||
|
||||
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
get_recognized_extensions(&extensions);
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -55,12 +55,12 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String extension = p_file.extension();
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
Error err = loader[i]->load_image(p_image,f);
|
||||
@ -73,25 +73,25 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
print_line("NO LOADER?");
|
||||
|
||||
if (!p_custom)
|
||||
memdelete(f);
|
||||
|
||||
memdelete(f);
|
||||
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
|
||||
}
|
||||
|
||||
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
loader[i]->get_recognized_extensions(p_extensions);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageLoader::recognize(const String& p_extension) {
|
||||
|
@ -41,11 +41,11 @@
|
||||
/**
|
||||
* @class ImageScanLineLoader
|
||||
* @author Juan Linietsky <reduzio@gmail.com>
|
||||
*
|
||||
|
||||
*
|
||||
|
||||
*/
|
||||
class ImageLoader;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @class ImageLoader
|
||||
@ -60,8 +60,8 @@ protected:
|
||||
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
||||
bool recognize(const String& p_extension) const;
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
virtual ~ImageFormatLoader() {}
|
||||
};
|
||||
@ -79,11 +79,11 @@ protected:
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
|
||||
static void get_recognized_extensions(List<String> *p_extensions) ;
|
||||
static bool recognize(const String& p_extension) ;
|
||||
|
||||
|
||||
static void add_image_format_loader(ImageFormatLoader *p_loader);
|
||||
|
||||
};
|
||||
|
@ -49,7 +49,7 @@ struct _IP_ResolverPrivate {
|
||||
response = IP_Address();
|
||||
hostname="";
|
||||
};
|
||||
|
||||
|
||||
QueueItem() {
|
||||
clear();
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
||||
str.parse_utf8((const char*)buf,strlen);
|
||||
r_variant=str;
|
||||
|
||||
if (r_len) {
|
||||
if (r_len) {
|
||||
if (strlen%4)
|
||||
(*r_len)+=4-strlen%4;
|
||||
(*r_len)+=4+strlen;
|
||||
@ -294,7 +294,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
||||
} break;
|
||||
case Variant::NODE_PATH: {
|
||||
|
||||
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
|
||||
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
|
||||
uint32_t strlen = decode_uint32(buf);
|
||||
|
||||
if (strlen&0x80000000) {
|
||||
@ -1077,7 +1077,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
|
||||
|
||||
r_len+=data.size()+5*4+pad;
|
||||
|
||||
} break;
|
||||
} break;
|
||||
/*case Variant::RESOURCE: {
|
||||
|
||||
ERR_EXPLAIN("Can't marshallize resources");
|
||||
@ -1238,7 +1238,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
|
||||
DVector<uint8_t> data = p_variant;
|
||||
int datalen=data.size();
|
||||
int datasize=sizeof(uint8_t);
|
||||
|
||||
|
||||
if (buf) {
|
||||
encode_uint32(datalen,buf);
|
||||
buf+=4;
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Miscelaneous helpers for marshalling data types, and encoding
|
||||
* in an endian independent way
|
||||
*/
|
||||
|
||||
|
||||
|
||||
union MarshallFloat {
|
||||
|
||||
@ -54,22 +54,22 @@ union MarshallDouble {
|
||||
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
return sizeof( uint16_t );
|
||||
}
|
||||
|
||||
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
return sizeof( uint32_t );
|
||||
}
|
||||
|
||||
@ -85,11 +85,11 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
|
||||
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
return sizeof(uint64_t);
|
||||
}
|
||||
|
||||
@ -100,25 +100,25 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
|
||||
encode_uint64( md.l, p_arr );
|
||||
|
||||
return sizeof(uint64_t);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
||||
|
||||
int len=0;
|
||||
|
||||
|
||||
while (*p_string) {
|
||||
|
||||
if (p_data) {
|
||||
|
||||
|
||||
*p_data=(uint8_t)*p_string;
|
||||
p_data++;
|
||||
}
|
||||
p_string++;
|
||||
len++;
|
||||
};
|
||||
|
||||
|
||||
if (p_data) *p_data = 0;
|
||||
return len+1;
|
||||
}
|
||||
@ -126,35 +126,35 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
||||
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
|
||||
|
||||
uint16_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
|
||||
|
||||
uint16_t b = *p_arr;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
||||
|
||||
uint32_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
uint32_t b = *p_arr;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static inline float decode_float(const uint8_t *p_arr) {
|
||||
|
||||
|
||||
MarshallFloat mf;
|
||||
mf.i = decode_uint32(p_arr);
|
||||
return mf.f;
|
||||
@ -163,15 +163,15 @@ static inline float decode_float(const uint8_t *p_arr) {
|
||||
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
|
||||
|
||||
uint64_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
uint64_t b = (*p_arr)&0xFF;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
@ -180,10 +180,10 @@ int PacketPeerStream::get_available_packet_count() const {
|
||||
ring_buffer.copy(lbuf,ofs,4);
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
remaining-=4;
|
||||
ofs+=4;
|
||||
ofs+=4;
|
||||
if (len>remaining)
|
||||
break;
|
||||
remaining-=len;
|
||||
remaining-=len;
|
||||
ofs+=len;
|
||||
count++;
|
||||
}
|
||||
@ -201,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
|
||||
uint8_t lbuf[4];
|
||||
ring_buffer.copy(lbuf,0,4);
|
||||
remaining-=4;
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
|
||||
|
||||
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
|
||||
|
@ -378,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
||||
} break;
|
||||
case OBJECT_INTERNAL_RESOURCE: {
|
||||
uint32_t index=f->get_32();
|
||||
String path = res_path+"::"+itos(index);
|
||||
String path = res_path+"::"+itos(index);
|
||||
RES res = ResourceLoader::load(path);
|
||||
if (res.is_null()) {
|
||||
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
|
||||
@ -2100,7 +2100,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
||||
p.value=E->get()->get(F->get().name);
|
||||
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
|
||||
continue;
|
||||
p.pi=F->get();
|
||||
p.pi=F->get();
|
||||
|
||||
rd.properties.push_back(p);
|
||||
|
||||
|
@ -1818,7 +1818,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
|
||||
|
||||
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
||||
|
||||
error=OK;
|
||||
error=OK;
|
||||
|
||||
lines=1;
|
||||
f=p_f;
|
||||
|
@ -49,16 +49,16 @@ Error ResourceInteractiveLoader::wait() {
|
||||
|
||||
|
||||
bool ResourceFormatLoader::recognize(const String& p_extension) const {
|
||||
|
||||
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
get_recognized_extensions(&extensions);
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -184,9 +184,9 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
|
||||
|
||||
String extension=remapped_path.extension();
|
||||
bool found=false;
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||
@ -356,7 +356,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
||||
}
|
||||
|
||||
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
|
||||
loader[loader_count++]=p_format_loader;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
virtual Ref<Resource> get_resource()=0;
|
||||
virtual Error poll()=0;
|
||||
virtual int get_stage() const=0;
|
||||
virtual int get_stage_count() const=0;
|
||||
virtual int get_stage_count() const=0;
|
||||
virtual Error wait();
|
||||
|
||||
ResourceInteractiveLoader() {}
|
||||
@ -76,12 +76,12 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
|
||||
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
|
||||
|
||||
|
||||
class ResourceLoader {
|
||||
|
||||
class ResourceLoader {
|
||||
|
||||
enum {
|
||||
MAX_LOADERS=64
|
||||
};
|
||||
|
||||
|
||||
static ResourceFormatLoader *loader[MAX_LOADERS];
|
||||
static int loader_count;
|
||||
static bool timestamp_on_load;
|
||||
@ -96,7 +96,7 @@ class ResourceLoader {
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
|
||||
|
@ -39,30 +39,30 @@ bool ResourceSaver::timestamp_on_save=false;
|
||||
ResourceSavedCallback ResourceSaver::save_callback=0;
|
||||
|
||||
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
|
||||
String extension=p_path.extension();
|
||||
Error err=ERR_FILE_UNRECOGNIZED;
|
||||
|
||||
for (int i=0;i<saver_count;i++) {
|
||||
|
||||
|
||||
if (!saver[i]->recognize(p_resource))
|
||||
continue;
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
bool recognized=false;
|
||||
saver[i]->get_recognized_extensions(p_resource,&extensions);
|
||||
|
||||
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(extension.extension())==0)
|
||||
recognized=true;
|
||||
}
|
||||
|
||||
if (!recognized)
|
||||
continue;
|
||||
|
||||
|
||||
String old_path=p_resource->get_path();
|
||||
|
||||
|
||||
|
||||
String local_path=Globals::get_singleton()->localize_path(p_path);
|
||||
|
||||
@ -92,10 +92,10 @@ Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_
|
||||
|
||||
return OK;
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -108,16 +108,16 @@ void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
|
||||
|
||||
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<saver_count;i++) {
|
||||
|
||||
|
||||
saver[i]->get_recognized_extensions(p_resource,p_extensions);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
|
||||
saver[saver_count++]=p_format_saver;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
class ResourceFormatSaver {
|
||||
public:
|
||||
|
||||
|
||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
|
||||
virtual bool recognize(const RES& p_resource) const=0;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
|
||||
@ -52,12 +52,12 @@ public:
|
||||
|
||||
typedef void (*ResourceSavedCallback)(const String& p_path);
|
||||
|
||||
class ResourceSaver {
|
||||
|
||||
class ResourceSaver {
|
||||
|
||||
enum {
|
||||
MAX_SAVERS=64
|
||||
};
|
||||
|
||||
|
||||
static ResourceFormatSaver *saver[MAX_SAVERS];
|
||||
static int saver_count;
|
||||
static bool timestamp_on_save;
|
||||
@ -86,7 +86,7 @@ public:
|
||||
static void set_save_callback(ResourceSavedCallback p_callback);
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
52
core/list.h
52
core/list.h
@ -245,7 +245,7 @@ public:
|
||||
_data->first=n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
@ -285,7 +285,7 @@ public:
|
||||
_data->last=n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
@ -363,30 +363,30 @@ public:
|
||||
}
|
||||
|
||||
void swap(Element* p_A, Element *p_B) {
|
||||
|
||||
|
||||
ERR_FAIL_COND(!p_A || !p_B);
|
||||
ERR_FAIL_COND(p_A->data!=_data);
|
||||
ERR_FAIL_COND(p_B->data!=_data);
|
||||
|
||||
|
||||
Element* A_prev=p_A->prev_ptr;
|
||||
Element* A_next=p_A->next_ptr;
|
||||
|
||||
|
||||
p_A->next_ptr=p_B->next_ptr;
|
||||
p_A->prev_ptr=p_B->prev_ptr;
|
||||
|
||||
|
||||
p_B->next_ptr=A_next;
|
||||
p_B->prev_ptr=A_prev;
|
||||
|
||||
p_B->prev_ptr=A_prev;
|
||||
|
||||
if (p_A->prev_ptr)
|
||||
p_A->prev_ptr->next_ptr=p_A;
|
||||
if (p_A->next_ptr)
|
||||
p_A->next_ptr->prev_ptr=p_A;
|
||||
|
||||
p_A->next_ptr->prev_ptr=p_A;
|
||||
|
||||
if (p_B->prev_ptr)
|
||||
p_B->prev_ptr->next_ptr=p_B;
|
||||
if (p_B->next_ptr)
|
||||
p_B->next_ptr->prev_ptr=p_B;
|
||||
|
||||
p_B->next_ptr->prev_ptr=p_B;
|
||||
|
||||
}
|
||||
/**
|
||||
* copy the list
|
||||
@ -552,10 +552,10 @@ public:
|
||||
*/
|
||||
|
||||
void sort() {
|
||||
|
||||
|
||||
sort_custom< Comparator<T> >();
|
||||
}
|
||||
|
||||
|
||||
template<class C>
|
||||
void sort_custom_inplace() {
|
||||
|
||||
@ -565,44 +565,44 @@ public:
|
||||
Element *from=front();
|
||||
Element *current=from;
|
||||
Element *to=from;
|
||||
|
||||
|
||||
while(current) {
|
||||
|
||||
|
||||
Element *next=current->next_ptr;
|
||||
|
||||
|
||||
//disconnect
|
||||
current->next_ptr=NULL;
|
||||
|
||||
|
||||
if (from!=current) {
|
||||
|
||||
|
||||
current->prev_ptr=NULL;
|
||||
current->next_ptr=from;
|
||||
|
||||
|
||||
Element *find=from;
|
||||
C less;
|
||||
while( find && less(find->value,current->value) ) {
|
||||
|
||||
|
||||
current->prev_ptr=find;
|
||||
current->next_ptr=find->next_ptr;
|
||||
find=find->next_ptr;
|
||||
}
|
||||
|
||||
|
||||
if (current->prev_ptr)
|
||||
current->prev_ptr->next_ptr=current;
|
||||
else
|
||||
from=current;
|
||||
|
||||
|
||||
if (current->next_ptr)
|
||||
current->next_ptr->prev_ptr=current;
|
||||
else
|
||||
to=current;
|
||||
} else {
|
||||
|
||||
|
||||
current->prev_ptr=NULL;
|
||||
current->next_ptr=NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
current=next;
|
||||
}
|
||||
_data->first=from;
|
||||
|
284
core/map.h
284
core/map.h
@ -39,12 +39,12 @@
|
||||
|
||||
template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
|
||||
class Map {
|
||||
|
||||
enum Color {
|
||||
|
||||
enum Color {
|
||||
RED,
|
||||
BLACK
|
||||
};
|
||||
struct _Data;
|
||||
struct _Data;
|
||||
public:
|
||||
|
||||
class Element {
|
||||
@ -66,34 +66,34 @@ public:
|
||||
public:
|
||||
|
||||
const Element *next() const {
|
||||
|
||||
|
||||
return _next;
|
||||
}
|
||||
Element *next() {
|
||||
|
||||
|
||||
return _next;
|
||||
}
|
||||
const Element *prev() const {
|
||||
|
||||
|
||||
return _prev;
|
||||
}
|
||||
Element *prev() {
|
||||
|
||||
|
||||
return _prev;
|
||||
}
|
||||
const K& key() const {
|
||||
const K& key() const {
|
||||
return _key;
|
||||
};
|
||||
V& value() {
|
||||
V& value() {
|
||||
return _value;
|
||||
};
|
||||
const V& value() const {
|
||||
const V& value() const {
|
||||
return _value;
|
||||
};
|
||||
V& get() {
|
||||
V& get() {
|
||||
return _value;
|
||||
};
|
||||
const V& get() const {
|
||||
const V& get() const {
|
||||
return _value;
|
||||
};
|
||||
Element() {
|
||||
@ -106,15 +106,15 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
struct _Data {
|
||||
|
||||
|
||||
Element* _root;
|
||||
Element* _nil;
|
||||
int size_cache;
|
||||
|
||||
|
||||
_FORCE_INLINE_ _Data() {
|
||||
#ifdef GLOBALNIL_DISABLED
|
||||
_nil = memnew_allocator( Element, A );
|
||||
@ -126,7 +126,7 @@ private:
|
||||
_root=NULL;
|
||||
size_cache=0;
|
||||
}
|
||||
|
||||
|
||||
void _create_root() {
|
||||
|
||||
_root = memnew_allocator( Element,A );
|
||||
@ -145,23 +145,23 @@ private:
|
||||
~_Data() {
|
||||
|
||||
_free_root();
|
||||
|
||||
|
||||
#ifdef GLOBALNIL_DISABLED
|
||||
memdelete_allocator<Element,A>(_nil);
|
||||
#endif
|
||||
// memdelete_allocator<Element,A>(_root);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_Data _data;
|
||||
|
||||
|
||||
inline void _set_color(Element *p_node, int p_color) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
|
||||
p_node->color=p_color;
|
||||
}
|
||||
inline void _rotate_left(Element *p_node) {
|
||||
|
||||
|
||||
Element *r=p_node->right;
|
||||
p_node->right=r->left;
|
||||
if (r->left != _data._nil )
|
||||
@ -171,14 +171,14 @@ private:
|
||||
p_node->parent->left=r;
|
||||
else
|
||||
p_node->parent->right=r;
|
||||
|
||||
|
||||
r->left=p_node;
|
||||
p_node->parent=r;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline void _rotate_right(Element *p_node) {
|
||||
|
||||
|
||||
Element *l=p_node->left;
|
||||
p_node->left=l->right;
|
||||
if (l->right != _data._nil)
|
||||
@ -188,25 +188,25 @@ private:
|
||||
p_node->parent->right=l;
|
||||
else
|
||||
p_node->parent->left=l;
|
||||
|
||||
|
||||
l->right=p_node;
|
||||
p_node->parent=l;
|
||||
|
||||
|
||||
}
|
||||
|
||||
inline Element* _successor(Element *p_node) const {
|
||||
|
||||
|
||||
inline Element* _successor(Element *p_node) const {
|
||||
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
if (node->right != _data._nil) {
|
||||
|
||||
|
||||
node=node->right;
|
||||
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
|
||||
node=node->left;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
|
||||
|
||||
while(node == node->parent->right) {
|
||||
node=node->parent;
|
||||
}
|
||||
@ -215,44 +215,44 @@ private:
|
||||
return node->parent;
|
||||
}
|
||||
}
|
||||
|
||||
inline Element* _predecessor(Element *p_node) const {
|
||||
|
||||
inline Element* _predecessor(Element *p_node) const {
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
if (node->left != _data._nil) {
|
||||
|
||||
|
||||
node=node->left;
|
||||
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
|
||||
node=node->right;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
|
||||
|
||||
while(node == node->parent->left) {
|
||||
if (node->parent == _data._root)
|
||||
return NULL;
|
||||
return NULL;
|
||||
node=node->parent;
|
||||
}
|
||||
return node->parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Element *_find(const K& p_key) const {
|
||||
|
||||
|
||||
Element *node = _data._root->left;
|
||||
C less;
|
||||
|
||||
C less;
|
||||
|
||||
while(node!=_data._nil) {
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
node=node->left;
|
||||
else if (less(node->_key,p_key))
|
||||
node=node->right;
|
||||
else
|
||||
break; // found
|
||||
}
|
||||
|
||||
|
||||
return (node!=_data._nil)?node:NULL;
|
||||
}
|
||||
|
||||
@ -289,73 +289,73 @@ private:
|
||||
}
|
||||
|
||||
Element *_insert(const K& p_key, bool& r_exists) {
|
||||
|
||||
|
||||
Element *new_parent=_data._root;
|
||||
Element *node = _data._root->left;
|
||||
C less;
|
||||
|
||||
C less;
|
||||
|
||||
while (node!=_data._nil) {
|
||||
|
||||
|
||||
new_parent=node;
|
||||
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
node=node->left;
|
||||
else if (less(node->_key,p_key))
|
||||
node=node->right;
|
||||
else {
|
||||
else {
|
||||
r_exists=true;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Element *new_node = memnew_allocator( Element, A );
|
||||
|
||||
|
||||
|
||||
new_node->parent=new_parent;
|
||||
new_node->right=_data._nil;
|
||||
new_node->left=_data._nil;
|
||||
new_node->_key=p_key;
|
||||
//new_node->data=_data;
|
||||
if (new_parent==_data._root || less(p_key,new_parent->_key)) {
|
||||
|
||||
|
||||
new_parent->left=new_node;
|
||||
} else {
|
||||
new_parent->right=new_node;
|
||||
}
|
||||
|
||||
|
||||
r_exists=false;
|
||||
|
||||
|
||||
new_node->_next=_successor(new_node);
|
||||
new_node->_prev=_predecessor(new_node);
|
||||
if (new_node->_next)
|
||||
new_node->_next->_prev=new_node;
|
||||
if (new_node->_prev)
|
||||
new_node->_prev->_next=new_node;
|
||||
|
||||
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
|
||||
Element * _insert_rb(const K& p_key, const V& p_value) {
|
||||
|
||||
|
||||
bool exists=false;
|
||||
Element *new_node = _insert(p_key,exists);
|
||||
|
||||
|
||||
if (new_node) {
|
||||
new_node->_value=p_value;
|
||||
}
|
||||
if (exists)
|
||||
return new_node;
|
||||
|
||||
|
||||
Element *node=new_node;
|
||||
_data.size_cache++;
|
||||
|
||||
while(node->parent->color==RED) {
|
||||
|
||||
while(node->parent->color==RED) {
|
||||
|
||||
if (node->parent == node->parent->parent->left) {
|
||||
|
||||
|
||||
Element *aux=node->parent->parent->right;
|
||||
|
||||
|
||||
if (aux->color==RED) {
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux,BLACK);
|
||||
@ -369,10 +369,10 @@ private:
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(node->parent->parent,RED);
|
||||
_rotate_right(node->parent->parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
Element *aux=node->parent->parent->left;
|
||||
|
||||
|
||||
if (aux->color==RED) {
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux,BLACK);
|
||||
@ -386,19 +386,19 @@ private:
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(node->parent->parent,RED);
|
||||
_rotate_left(node->parent->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_set_color(_data._root->left,BLACK);
|
||||
return new_node;
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
|
||||
void _erase_fix(Element *p_node) {
|
||||
|
||||
|
||||
Element *root = _data._root->left;
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
|
||||
|
||||
while( (node->color==BLACK) && (root != node)) {
|
||||
if (node == node->parent->left) {
|
||||
Element *aux=node->parent->right;
|
||||
@ -408,7 +408,7 @@ private:
|
||||
_rotate_left(node->parent);
|
||||
aux=node->parent->right;
|
||||
}
|
||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||
_set_color(aux,RED);
|
||||
node=node->parent;
|
||||
} else {
|
||||
@ -432,7 +432,7 @@ private:
|
||||
_rotate_right(node->parent);
|
||||
aux=node->parent->left;
|
||||
}
|
||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||
_set_color(aux,RED);
|
||||
node=node->parent;
|
||||
} else {
|
||||
@ -446,24 +446,24 @@ private:
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux->left,BLACK);
|
||||
_rotate_right(node->parent);
|
||||
node=root;
|
||||
node=root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_set_color(node,BLACK);
|
||||
|
||||
|
||||
ERR_FAIL_COND(_data._nil->color!=BLACK);
|
||||
}
|
||||
|
||||
|
||||
void _erase(Element *p_node) {
|
||||
|
||||
|
||||
|
||||
|
||||
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
|
||||
if (!rp)
|
||||
rp=_data._nil;
|
||||
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
|
||||
|
||||
|
||||
if (_data._root == (node->parent=rp->parent) ) {
|
||||
_data._root->left=node;
|
||||
} else {
|
||||
@ -473,47 +473,47 @@ private:
|
||||
rp->parent->right=node;
|
||||
}
|
||||
}
|
||||
|
||||
if (rp != p_node) {
|
||||
|
||||
|
||||
if (rp != p_node) {
|
||||
|
||||
ERR_FAIL_COND( rp == _data._nil );
|
||||
|
||||
|
||||
if (rp->color==BLACK)
|
||||
_erase_fix(node);
|
||||
|
||||
|
||||
|
||||
|
||||
rp->left=p_node->left;
|
||||
rp->right=p_node->right;
|
||||
rp->parent=p_node->parent;
|
||||
rp->color=p_node->color;
|
||||
p_node->left->parent=rp;
|
||||
p_node->right->parent=rp;
|
||||
|
||||
|
||||
if (p_node == p_node->parent->left) {
|
||||
p_node->parent->left=rp;
|
||||
p_node->parent->left=rp;
|
||||
} else {
|
||||
p_node->parent->right=rp;
|
||||
}
|
||||
} else {
|
||||
if (p_node->color==BLACK)
|
||||
if (p_node->color==BLACK)
|
||||
_erase_fix(node);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (p_node->_next)
|
||||
p_node->_next->_prev=p_node->_prev;
|
||||
if (p_node->_prev)
|
||||
p_node->_prev->_next=p_node->_next;
|
||||
|
||||
|
||||
memdelete_allocator<Element,A>(p_node);
|
||||
_data.size_cache--;
|
||||
ERR_FAIL_COND( _data._nil->color==RED );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void _calculate_depth(Element *p_element,int &max_d,int d) const {
|
||||
|
||||
|
||||
if (p_element==_data._nil) {
|
||||
return;
|
||||
}
|
||||
@ -522,23 +522,23 @@ private:
|
||||
if (d>max_d)
|
||||
max_d=d;
|
||||
}
|
||||
|
||||
|
||||
void _cleanup_tree(Element *p_element) {
|
||||
|
||||
|
||||
if (p_element==_data._nil)
|
||||
return;
|
||||
|
||||
|
||||
_cleanup_tree(p_element->left);
|
||||
_cleanup_tree(p_element->right);
|
||||
memdelete_allocator<Element,A>( p_element );
|
||||
}
|
||||
|
||||
|
||||
void _copy_from( const Map& p_map) {
|
||||
|
||||
|
||||
clear();
|
||||
// not the fastest way, but safeset to write.
|
||||
for(Element *I=p_map.front();I;I=I->next()) {
|
||||
|
||||
|
||||
insert(I->key(),I->value());
|
||||
}
|
||||
}
|
||||
@ -554,7 +554,7 @@ public:
|
||||
}
|
||||
|
||||
Element *find(const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
Element *res=_find(p_key);
|
||||
@ -578,15 +578,15 @@ public:
|
||||
}
|
||||
|
||||
Element *insert(const K& p_key,const V& p_value) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
_data._create_root();
|
||||
return _insert_rb(p_key,p_value);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void erase(Element* p_element) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return;
|
||||
_erase(p_element);
|
||||
@ -595,72 +595,72 @@ public:
|
||||
}
|
||||
|
||||
bool erase(const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return false;
|
||||
Element *e=find(p_key);
|
||||
if (!e)
|
||||
return false;
|
||||
_erase(e);
|
||||
_erase(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool has(const K& p_key) const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return false;
|
||||
return find(p_key) != NULL;
|
||||
}
|
||||
|
||||
|
||||
const V& operator[](const K& p_key) const {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
|
||||
const Element *e=find(p_key);
|
||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||
return e->_value;
|
||||
}
|
||||
V& operator[](const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
_data._create_root();
|
||||
|
||||
Element *e=find(p_key);
|
||||
if (!e)
|
||||
e=insert(p_key,V());
|
||||
|
||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||
|
||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||
return e->_value;
|
||||
}
|
||||
|
||||
|
||||
Element *front() const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
|
||||
Element *e=_data._root->left;
|
||||
if (e==_data._nil)
|
||||
return NULL;
|
||||
|
||||
|
||||
while(e->left!=_data._nil)
|
||||
e=e->left;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
Element *back() const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
Element *e=_data._root->left;
|
||||
if (e==_data._nil)
|
||||
return NULL;
|
||||
|
||||
|
||||
while(e->right!=_data._nil)
|
||||
e=e->right;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
inline bool empty() const { return _data.size_cache==0; }
|
||||
inline int size() const { return _data.size_cache; }
|
||||
int calculate_depth() const {
|
||||
@ -671,9 +671,9 @@ public:
|
||||
_calculate_depth(_data._root->left,max_d,0);
|
||||
return max_d;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return;
|
||||
_cleanup_tree(_data._root->left);
|
||||
@ -682,25 +682,25 @@ public:
|
||||
_data._nil->parent=_data._nil;
|
||||
_data._free_root();
|
||||
}
|
||||
|
||||
|
||||
void operator=(const Map& p_map) {
|
||||
|
||||
|
||||
_copy_from( p_map );
|
||||
}
|
||||
|
||||
|
||||
Map(const Map& p_map) {
|
||||
|
||||
|
||||
_copy_from( p_map );
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Map() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
~Map() {
|
||||
|
||||
clear();
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -47,21 +47,21 @@ public:
|
||||
|
||||
float get_area() const; /// get area
|
||||
_FORCE_INLINE_ bool has_no_area() const {
|
||||
|
||||
|
||||
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool has_no_surface() const {
|
||||
|
||||
|
||||
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
|
||||
}
|
||||
|
||||
|
||||
const Vector3& get_pos() const { return pos; }
|
||||
void set_pos(const Vector3& p_pos) { pos=p_pos; }
|
||||
const Vector3& get_size() const { return size; }
|
||||
void set_size(const Vector3& p_size) { size=p_size; }
|
||||
|
||||
|
||||
|
||||
bool operator==(const AABB& p_rval) const;
|
||||
bool operator!=(const AABB& p_rval) const;
|
||||
|
||||
@ -265,7 +265,7 @@ bool AABB::has_point(const Vector3& p_point) const {
|
||||
return false;
|
||||
if (p_point.z>pos.z+size.z)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -297,11 +297,11 @@ void AABB::project_range_in_plane(const Plane& p_plane,float &r_min,float& r_max
|
||||
|
||||
Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 );
|
||||
Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z );
|
||||
|
||||
|
||||
float length = p_plane.normal.abs().dot(half_extents);
|
||||
float distance = p_plane.distance_to( center );
|
||||
r_min = distance - length;
|
||||
r_max = distance + length;
|
||||
r_max = distance + length;
|
||||
}
|
||||
|
||||
inline real_t AABB::get_longest_axis_size() const {
|
||||
|
@ -66,12 +66,12 @@ Vector<Plane> BSP_Tree::get_planes() const {
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
|
||||
AABB BSP_Tree::get_aabb() const {
|
||||
|
||||
return aabb;
|
||||
}
|
||||
|
||||
|
||||
int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const {
|
||||
|
||||
|
||||
@ -245,22 +245,22 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
||||
if (!aabb.has_point(p_point)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int node_count=nodes.size();
|
||||
|
||||
|
||||
if (node_count==0) // no nodes!
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
const Node *nodesptr=&nodes[0];
|
||||
const Plane *planesptr=&planes[0];
|
||||
int plane_count=planes.size();
|
||||
|
||||
|
||||
int idx=node_count-1;
|
||||
int steps=0;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
if (idx==OVER_LEAF) {
|
||||
return false;
|
||||
}
|
||||
@ -268,28 +268,28 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint16_t plane=nodesptr[ idx ].plane;
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
|
||||
ERR_FAIL_INDEX_V( plane, plane_count, false );
|
||||
#endif
|
||||
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
|
||||
|
||||
idx = over ? nodes[ idx ].over : nodes[ idx ].under;
|
||||
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
|
||||
#endif
|
||||
|
||||
|
||||
steps++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
|
||||
|
||||
int ic = p_indices.size();
|
||||
@ -304,7 +304,7 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||
|
||||
const Face3& f=p_faces[ indices[i] ];
|
||||
Plane p = f.get_plane();
|
||||
|
||||
|
||||
int num_over=0,num_under=0,num_spanning=0;
|
||||
|
||||
for(int j=0;j<ic;j++) {
|
||||
@ -335,17 +335,17 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||
num_over++;
|
||||
else
|
||||
num_under++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//double split_cost = num_spanning / (double) face_count;
|
||||
double relation = Math::abs(num_over-num_under) / (double) ic;
|
||||
|
||||
|
||||
// being honest, i never found a way to add split cost to the mix in a meaninguful way
|
||||
// in this engine, also, will likely be ignored anyway
|
||||
|
||||
|
||||
double plane_cost = /*split_cost +*/ relation;
|
||||
|
||||
//printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
|
||||
@ -360,10 +360,10 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||
return best_plane;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
|
||||
|
||||
// should not reach here
|
||||
@ -387,7 +387,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||
|
||||
if (i==divisor_idx)
|
||||
continue;
|
||||
|
||||
|
||||
const Face3& f=p_faces[ indices[i] ];
|
||||
|
||||
//if (f.get_plane().is_almost_like(divisor_plane))
|
||||
@ -416,7 +416,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF;
|
||||
|
||||
if (faces_over.size()>0) { //have facess above?
|
||||
@ -434,13 +434,13 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||
}
|
||||
|
||||
/* Create the node */
|
||||
|
||||
|
||||
// find existing divisor plane
|
||||
int divisor_plane_idx=-1;
|
||||
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<p_planes.size();i++) {
|
||||
|
||||
|
||||
if (p_planes[i].is_almost_like( divisor_plane )) {
|
||||
divisor_plane_idx=i;
|
||||
break;
|
||||
@ -448,22 +448,22 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||
}
|
||||
|
||||
if (divisor_plane_idx==-1) {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
|
||||
divisor_plane_idx=p_planes.size();
|
||||
p_planes.push_back( divisor_plane );
|
||||
}
|
||||
|
||||
|
||||
BSP_Tree::Node node;
|
||||
node.plane=divisor_plane_idx;
|
||||
node.under=under_idx;
|
||||
node.over=over_idx;
|
||||
|
||||
|
||||
p_nodes.push_back(node);
|
||||
|
||||
|
||||
return p_nodes.size()-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BSP_Tree::operator Variant() const {
|
||||
|
||||
@ -563,7 +563,7 @@ BSP_Tree::BSP_Tree(const Variant& p_variant) {
|
||||
BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||
|
||||
// compute aabb
|
||||
|
||||
|
||||
int face_count=p_faces.size();
|
||||
DVector<Face3>::Read faces_r=p_faces.read();
|
||||
const Face3 *facesptr = faces_r.ptr();
|
||||
@ -574,26 +574,26 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||
Vector<int> indices;
|
||||
|
||||
for (int i=0;i<face_count;i++) {
|
||||
|
||||
|
||||
const Face3& f=facesptr[i];
|
||||
|
||||
|
||||
if (f.is_degenerate())
|
||||
continue;
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
|
||||
if (first) {
|
||||
|
||||
|
||||
aabb.pos=f.vertex[0];
|
||||
first=false;
|
||||
} else {
|
||||
|
||||
|
||||
aabb.expand_to(f.vertex[j]);
|
||||
}
|
||||
}
|
||||
|
||||
indices.push_back(i);
|
||||
|
||||
|
||||
}
|
||||
|
||||
ERR_FAIL_COND( aabb.has_no_area() );
|
||||
@ -609,7 +609,7 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
error_radius=p_error_radius;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class BSP_Tree {
|
||||
public:
|
||||
|
||||
enum {
|
||||
|
||||
|
||||
UNDER_LEAF=0xFFFF,
|
||||
OVER_LEAF=0xFFFE,
|
||||
MAX_NODES=0xFFFE,
|
||||
@ -51,22 +51,22 @@ public:
|
||||
};
|
||||
|
||||
struct Node {
|
||||
|
||||
|
||||
uint16_t plane;
|
||||
uint16_t under;
|
||||
uint16_t over;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
// thanks to the properties of Vector,
|
||||
|
||||
private:
|
||||
// thanks to the properties of Vector,
|
||||
// this class can be assigned and passed around between threads
|
||||
// with no cost.
|
||||
|
||||
|
||||
Vector<Node> nodes;
|
||||
Vector<Plane> planes;
|
||||
AABB aabb;
|
||||
float error_radius;
|
||||
float error_radius;
|
||||
|
||||
int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const;
|
||||
|
||||
@ -79,8 +79,8 @@ public:
|
||||
Vector<Node> get_nodes() const;
|
||||
Vector<Plane> get_planes() const;
|
||||
AABB get_aabb() const;
|
||||
|
||||
bool point_is_inside(const Vector3& p_point) const;
|
||||
|
||||
bool point_is_inside(const Vector3& p_point) const;
|
||||
int get_points_inside(const Vector3* p_points, int p_point_count) const;
|
||||
template<class T>
|
||||
bool convex_is_inside(const T& p_convex) const;
|
||||
@ -91,8 +91,8 @@ public:
|
||||
|
||||
BSP_Tree();
|
||||
BSP_Tree(const Variant& p_variant);
|
||||
BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
|
||||
BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
|
||||
BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
|
||||
BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
|
||||
~BSP_Tree();
|
||||
|
||||
};
|
||||
|
@ -33,9 +33,9 @@
|
||||
void CameraMatrix::set_identity() {
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<4;j++) {
|
||||
|
||||
|
||||
matrix[i][j]=(i==j)?1:0;
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ void CameraMatrix::set_perspective(float p_fovy_degrees, float p_aspect, float p
|
||||
matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
|
||||
matrix[2][3] = -1;
|
||||
matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
|
||||
matrix[3][3] = 0;
|
||||
matrix[3][3] = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -155,95 +155,95 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa
|
||||
|
||||
|
||||
float CameraMatrix::get_z_far() const {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
|
||||
matrix[ 7] - matrix[ 6],
|
||||
matrix[11] - matrix[10],
|
||||
matrix[15] - matrix[14]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
||||
return new_plane.d;
|
||||
}
|
||||
float CameraMatrix::get_z_near() const {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
Plane new_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]);
|
||||
|
||||
|
||||
new_plane.normalize();
|
||||
return new_plane.d;
|
||||
}
|
||||
|
||||
void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
///////--- Near Plane ---///////
|
||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
///////--- Right Plane ---///////
|
||||
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
||||
matrix[ 7] - matrix[ 4],
|
||||
matrix[11] - matrix[ 8],
|
||||
- matrix[15] + matrix[12]).normalized();
|
||||
|
||||
|
||||
Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
|
||||
matrix[ 7] - matrix[ 5],
|
||||
matrix[11] - matrix[ 9],
|
||||
-matrix[15] + matrix[13]).normalized();
|
||||
|
||||
|
||||
Vector3 res;
|
||||
near_plane.intersect_3(right_plane,top_plane,&res);
|
||||
|
||||
|
||||
r_width=res.x;
|
||||
r_height=res.y;
|
||||
}
|
||||
|
||||
bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
///////--- Near Plane ---///////
|
||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
///////--- Far Plane ---///////
|
||||
Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
|
||||
matrix[ 6] - matrix[ 7],
|
||||
matrix[10] - matrix[11],
|
||||
matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
|
||||
///////--- Right Plane ---///////
|
||||
Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
|
||||
matrix[ 4] - matrix[ 7],
|
||||
matrix[8] - matrix[ 11],
|
||||
- matrix[15] + matrix[12]).normalized();
|
||||
|
||||
///////--- Top Plane ---///////
|
||||
|
||||
///////--- Top Plane ---///////
|
||||
Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
|
||||
matrix[ 5] - matrix[ 7],
|
||||
matrix[9] - matrix[ 11],
|
||||
-matrix[15] + matrix[13]).normalized();
|
||||
|
||||
|
||||
Vector3 near_endpoint;
|
||||
Vector3 far_endpoint;
|
||||
|
||||
|
||||
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
|
||||
ERR_FAIL_COND_V(!res,false);
|
||||
|
||||
|
||||
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
|
||||
ERR_FAIL_COND_V(!res,false);
|
||||
|
||||
|
||||
p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
||||
p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) );
|
||||
p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
||||
@ -252,7 +252,7 @@ bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8point
|
||||
p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
||||
p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) );
|
||||
p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -263,10 +263,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
* http://www.markmorley.com/opengl/frustumculling.html
|
||||
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
|
||||
*/
|
||||
|
||||
|
||||
Vector<Plane> planes;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
Plane new_plane;
|
||||
|
||||
@ -275,7 +275,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
matrix[15] + matrix[14]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
@ -298,7 +298,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
matrix[ 7] + matrix[ 4],
|
||||
matrix[11] + matrix[ 8],
|
||||
matrix[15] + matrix[12]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
@ -310,8 +310,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
matrix[ 7] - matrix[ 5],
|
||||
matrix[11] - matrix[ 9],
|
||||
matrix[15] - matrix[13]);
|
||||
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
@ -324,10 +324,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
matrix[11] - matrix[ 8],
|
||||
matrix[15] - matrix[12]);
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
||||
planes.push_back( p_transform.xform(new_plane) );
|
||||
|
||||
|
||||
@ -337,12 +337,12 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||
matrix[11] + matrix[ 9],
|
||||
matrix[15] + matrix[13]);
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
planes.push_back( p_transform.xform(new_plane) );
|
||||
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ CameraMatrix CameraMatrix::inverse() const {
|
||||
}
|
||||
|
||||
void CameraMatrix::invert() {
|
||||
|
||||
|
||||
int i,j,k;
|
||||
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
|
||||
float pvt_val; /* Value of current pivot element */
|
||||
@ -448,7 +448,7 @@ void CameraMatrix::invert() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
CameraMatrix::CameraMatrix() {
|
||||
@ -475,31 +475,31 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix& p_matrix) const {
|
||||
void CameraMatrix::set_light_bias() {
|
||||
|
||||
float *m=&matrix[0][0];
|
||||
|
||||
m[0]=0.5,
|
||||
m[1]=0.0,
|
||||
m[2]=0.0,
|
||||
|
||||
m[0]=0.5,
|
||||
m[1]=0.0,
|
||||
m[2]=0.0,
|
||||
m[3]=0.0,
|
||||
m[4]=0.0,
|
||||
m[5]=0.5,
|
||||
m[6]=0.0,
|
||||
m[4]=0.0,
|
||||
m[5]=0.5,
|
||||
m[6]=0.0,
|
||||
m[7]=0.0,
|
||||
m[8]=0.0,
|
||||
m[9]=0.0,
|
||||
m[10]=0.5,
|
||||
m[8]=0.0,
|
||||
m[9]=0.0,
|
||||
m[10]=0.5,
|
||||
m[11]=0.0,
|
||||
m[12]=0.5,
|
||||
m[13]=0.5,
|
||||
m[14]=0.5,
|
||||
m[15]=1.0;
|
||||
|
||||
m[12]=0.5,
|
||||
m[13]=0.5,
|
||||
m[14]=0.5,
|
||||
m[15]=1.0;
|
||||
|
||||
}
|
||||
|
||||
CameraMatrix::operator String() const {
|
||||
|
||||
String str;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
|
||||
|
||||
return str;
|
||||
@ -513,7 +513,7 @@ float CameraMatrix::get_aspect() const {
|
||||
}
|
||||
|
||||
float CameraMatrix::get_fov() const {
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
||||
matrix[ 7] - matrix[ 4],
|
||||
@ -588,7 +588,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
||||
|
||||
const Transform &tr = p_transform;
|
||||
float *m=&matrix[0][0];
|
||||
|
||||
|
||||
m[0]=tr.basis.elements[0][0];
|
||||
m[1]=tr.basis.elements[1][0];
|
||||
m[2]=tr.basis.elements[2][0];
|
||||
@ -604,7 +604,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
||||
m[12]=tr.origin.x;
|
||||
m[13]=tr.origin.y;
|
||||
m[14]=tr.origin.z;
|
||||
m[15]=1.0;
|
||||
m[15]=1.0;
|
||||
}
|
||||
|
||||
CameraMatrix::~CameraMatrix()
|
||||
|
@ -48,8 +48,8 @@ struct CameraMatrix {
|
||||
};
|
||||
|
||||
float matrix[4][4];
|
||||
|
||||
|
||||
|
||||
|
||||
void set_identity();
|
||||
void set_zero();
|
||||
void set_light_bias();
|
||||
@ -67,12 +67,12 @@ struct CameraMatrix {
|
||||
float get_z_near() const;
|
||||
float get_aspect() const;
|
||||
float get_fov() const;
|
||||
|
||||
|
||||
Vector<Plane> get_projection_planes(const Transform& p_transform) const;
|
||||
|
||||
|
||||
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
|
||||
void get_viewport_size(float& r_width, float& r_height) const;
|
||||
|
||||
|
||||
void invert();
|
||||
CameraMatrix inverse() const;
|
||||
|
||||
@ -80,15 +80,15 @@ struct CameraMatrix {
|
||||
|
||||
Plane xform4(const Plane& p_vec4);
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
void scale_translate_to_fit(const AABB& p_aabb);
|
||||
void make_scale(const Vector3 &p_scale);
|
||||
operator Transform() const;
|
||||
|
||||
CameraMatrix();
|
||||
CameraMatrix(const Transform& p_transform);
|
||||
CameraMatrix();
|
||||
CameraMatrix(const Transform& p_transform);
|
||||
~CameraMatrix();
|
||||
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
* @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
|
||||
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
|
||||
*/
|
||||
|
||||
|
||||
int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const;
|
||||
|
||||
Plane get_plane(ClockDirection p_dir=CLOCKWISE) const;
|
||||
@ -77,7 +77,7 @@ public:
|
||||
|
||||
void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const;
|
||||
void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
|
||||
|
||||
|
||||
AABB get_aabb() const {
|
||||
|
||||
AABB aabb( vertex[0], Vector3() );
|
||||
|
@ -211,7 +211,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||
int len = p_array.size();
|
||||
|
||||
DVector<Face3>::Read r=p_array.read();
|
||||
|
||||
|
||||
const Face3* arrayptr = r.ptr();
|
||||
|
||||
DVector< _FaceClassify> fc;
|
||||
@ -219,7 +219,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||
fc.resize( len );
|
||||
|
||||
DVector< _FaceClassify >::Write fcw=fc.write();
|
||||
|
||||
|
||||
_FaceClassify * _fcptr = fcw.ptr();
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
@ -278,7 +278,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||
/*** GEOMETRY WRAPPER ***/
|
||||
|
||||
enum _CellFlags {
|
||||
|
||||
|
||||
_CELL_SOLID=1,
|
||||
_CELL_EXTERIOR=2,
|
||||
_CELL_STEP_MASK=0x1C,
|
||||
@ -299,7 +299,7 @@ enum _CellFlags {
|
||||
_CELL_PREV_Z_POS=5<<5,
|
||||
_CELL_PREV_Z_NEG=6<<5,
|
||||
_CELL_PREV_FIRST=7<<5,
|
||||
|
||||
|
||||
};
|
||||
|
||||
static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
|
||||
@ -316,9 +316,9 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
|
||||
p_cell_status[x][y][z]=_CELL_SOLID;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int div_x=len_x>1?2:1;
|
||||
int div_y=len_y>1?2:1;
|
||||
int div_z=len_z>1?2:1;
|
||||
@ -343,14 +343,14 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
|
||||
int new_len_z;
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
|
||||
|
||||
_SPLIT(i,div_x,x,len_x,new_x,new_len_x);
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
_SPLIT(j,div_y,y,len_y,new_y,new_len_y);
|
||||
|
||||
|
||||
for (int k=0;k<div_z;k++) {
|
||||
|
||||
_SPLIT(k,div_z,z,len_z,new_z,new_len_z);
|
||||
@ -365,39 +365,39 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||
|
||||
if (p_cell_status[x][y][z]&3)
|
||||
return; // nothing to do, already used and/or visited
|
||||
|
||||
|
||||
p_cell_status[x][y][z]=_CELL_PREV_FIRST;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
uint8_t &c = p_cell_status[x][y][z];
|
||||
|
||||
|
||||
//printf("at %i,%i,%i\n",x,y,z);
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
|
||||
/* Haven't been in here, mark as outside */
|
||||
p_cell_status[x][y][z]|=_CELL_EXTERIOR;
|
||||
//printf("not marked as anything, marking exterior\n");
|
||||
}
|
||||
|
||||
|
||||
//printf("cell step is %i\n",(c&_CELL_STEP_MASK));
|
||||
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
|
||||
/* if not done, increase step */
|
||||
c+=1<<2;
|
||||
//printf("incrementing cell step\n");
|
||||
}
|
||||
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
|
||||
/* Go back */
|
||||
//printf("done, going back a cell\n");
|
||||
|
||||
|
||||
switch(c&_CELL_PREV_MASK) {
|
||||
case _CELL_PREV_FIRST: {
|
||||
//printf("at end, finished marking\n");
|
||||
//printf("at end, finished marking\n");
|
||||
return;
|
||||
} break;
|
||||
case _CELL_PREV_Y_POS: {
|
||||
case _CELL_PREV_Y_POS: {
|
||||
y++;
|
||||
ERR_FAIL_COND(y>=len_y);
|
||||
} break;
|
||||
@ -427,16 +427,16 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//printf("attempting new cell!\n");
|
||||
|
||||
|
||||
int next_x=x,next_y=y,next_z=z;
|
||||
uint8_t prev=0;
|
||||
|
||||
|
||||
switch(c&_CELL_STEP_MASK) {
|
||||
|
||||
|
||||
case _CELL_STEP_Y_POS: {
|
||||
|
||||
|
||||
next_y++;
|
||||
prev=_CELL_PREV_Y_NEG;
|
||||
} break;
|
||||
@ -454,32 +454,32 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||
} break;
|
||||
case _CELL_STEP_Z_POS: {
|
||||
next_z++;
|
||||
prev=_CELL_PREV_Z_NEG;
|
||||
prev=_CELL_PREV_Z_NEG;
|
||||
} break;
|
||||
case _CELL_STEP_Z_NEG: {
|
||||
next_z--;
|
||||
prev=_CELL_PREV_Z_POS;
|
||||
prev=_CELL_PREV_Z_POS;
|
||||
} break;
|
||||
default: ERR_FAIL();
|
||||
|
||||
default: ERR_FAIL();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//printf("testing if new cell will be ok...!\n");
|
||||
|
||||
|
||||
if (next_x<0 || next_x>=len_x)
|
||||
continue;
|
||||
if (next_y<0 || next_y>=len_y)
|
||||
continue;
|
||||
if (next_z<0 || next_z>=len_z)
|
||||
continue;
|
||||
|
||||
|
||||
//printf("testing if new cell is traversable\n");
|
||||
|
||||
|
||||
if (p_cell_status[next_x][next_y][next_z]&3)
|
||||
continue;
|
||||
|
||||
|
||||
//printf("move to it\n");
|
||||
|
||||
|
||||
x=next_x;
|
||||
y=next_y;
|
||||
z=next_z;
|
||||
@ -488,14 +488,14 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||
}
|
||||
|
||||
static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
|
||||
|
||||
|
||||
ERR_FAIL_INDEX(x,len_x);
|
||||
ERR_FAIL_INDEX(y,len_y);
|
||||
ERR_FAIL_INDEX(z,len_z);
|
||||
|
||||
|
||||
if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
/* static const Vector3 vertices[8]={
|
||||
Vector3(0,0,0),
|
||||
Vector3(0,0,1),
|
||||
@ -510,73 +510,73 @@ static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int l
|
||||
#define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
|
||||
|
||||
static const uint8_t indices[6][4]={
|
||||
{7,6,4,5},
|
||||
{7,6,4,5},
|
||||
{7,3,2,6},
|
||||
{7,5,1,3},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{7,5,1,3},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,4,6,2},
|
||||
|
||||
};
|
||||
/*
|
||||
/*
|
||||
|
||||
{0,1,2,3},
|
||||
{0,1,4,5},
|
||||
{0,1,2,3},
|
||||
{0,1,4,5},
|
||||
{0,2,4,6},
|
||||
{4,5,6,7},
|
||||
{4,5,6,7},
|
||||
{2,3,7,6},
|
||||
{1,3,5,7},
|
||||
{1,3,5,7},
|
||||
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,4,6,2},
|
||||
{7,6,4,5},
|
||||
{7,6,4,5},
|
||||
{7,3,2,6},
|
||||
{7,5,1,3},
|
||||
{7,5,1,3},
|
||||
*/
|
||||
|
||||
|
||||
for (int i=0;i<6;i++) {
|
||||
|
||||
|
||||
Vector3 face_points[4];
|
||||
int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
|
||||
int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
|
||||
int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
|
||||
|
||||
|
||||
bool plot=false;
|
||||
|
||||
|
||||
if (disp_x<0 || disp_x>=len_x)
|
||||
plot=true;
|
||||
if (disp_y<0 || disp_y>=len_y)
|
||||
plot=true;
|
||||
if (disp_z<0 || disp_z>=len_z)
|
||||
plot=true;
|
||||
|
||||
|
||||
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
|
||||
plot=true;
|
||||
|
||||
|
||||
if (!plot)
|
||||
continue;
|
||||
|
||||
|
||||
for (int j=0;j<4;j++)
|
||||
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
face_points[0],
|
||||
face_points[1],
|
||||
face_points[2]
|
||||
)
|
||||
);
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
face_points[2],
|
||||
face_points[3],
|
||||
face_points[0]
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||
global_aabb.merge_with( faces[i].get_aabb() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
global_aabb.grow_by(0.01); // avoid numerical error
|
||||
|
||||
// determine amount of cells in grid axis
|
||||
@ -649,7 +649,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||
|
||||
// plot faces into cells
|
||||
print_line("Wrapper (1/6): Plotting Faces");
|
||||
|
||||
|
||||
for (int i=0;i<face_count;i++) {
|
||||
|
||||
Face3 f=faces[i];
|
||||
@ -666,68 +666,68 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||
print_line("Wrapper (2/6) Flood Filling");
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
|
||||
_mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
|
||||
_mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<div_z;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
|
||||
_mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
|
||||
_mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<div_z;j++) {
|
||||
|
||||
|
||||
_mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
|
||||
_mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build faces for the inside-outside cell divisors
|
||||
|
||||
|
||||
print_line("Wrapper (3/6): Building Faces");
|
||||
|
||||
DVector<Face3> wrapped_faces;
|
||||
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
|
||||
for (int k=0;k<div_z;k++) {
|
||||
|
||||
_build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
|
||||
|
||||
_build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print_line("Wrapper (4/6): Transforming Back Vertices");
|
||||
|
||||
// transform face vertices to global coords
|
||||
|
||||
|
||||
int wrapped_faces_count=wrapped_faces.size();
|
||||
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
|
||||
Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
|
||||
|
||||
|
||||
for(int i=0;i<wrapped_faces_count;i++) {
|
||||
|
||||
|
||||
for(int j=0;j<3;j++) {
|
||||
|
||||
|
||||
Vector3& v = wrapped_faces_ptr[i].vertex[j];
|
||||
v=v*voxelsize;
|
||||
v+=global_aabb.pos;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up grid
|
||||
|
||||
// clean up grid
|
||||
print_line("Wrapper (5/6): Grid Cleanup");
|
||||
|
||||
for(int i=0;i<div_x;i++) {
|
||||
@ -736,14 +736,14 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||
|
||||
memdelete_arr( cell_status[i][j] );
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr( cell_status[i] );
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr(cell_status);
|
||||
if (p_error)
|
||||
*p_error=voxelsize.length();
|
||||
|
||||
|
||||
print_line("Wrapper (6/6): Finished.");
|
||||
return wrapped_faces;
|
||||
}
|
||||
@ -751,67 +751,67 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||
|
||||
MeshData mesh;
|
||||
|
||||
|
||||
|
||||
|
||||
#define SUBPLANE_SIZE 1024.0
|
||||
|
||||
|
||||
float subplane_size = 1024.0; // should compute this from the actual plane
|
||||
for (int i=0;i<p_planes.size();i++) {
|
||||
|
||||
|
||||
Plane p =p_planes[i];
|
||||
|
||||
|
||||
Vector3 ref=Vector3(0.0,1.0,0.0);
|
||||
|
||||
|
||||
if (ABS(p.normal.dot(ref))>0.95)
|
||||
ref=Vector3(0.0,0.0,1.0); // change axis
|
||||
|
||||
|
||||
Vector3 right = p.normal.cross(ref).normalized();
|
||||
Vector3 up = p.normal.cross( right ).normalized();
|
||||
|
||||
|
||||
Vector< Vector3 > vertices;
|
||||
|
||||
|
||||
Vector3 center = p.get_any_point();
|
||||
// make a quad clockwise
|
||||
vertices.push_back( center - up * subplane_size + right * subplane_size );
|
||||
vertices.push_back( center - up * subplane_size - right * subplane_size );
|
||||
vertices.push_back( center + up * subplane_size - right * subplane_size );
|
||||
vertices.push_back( center + up * subplane_size + right * subplane_size );
|
||||
|
||||
|
||||
for (int j=0;j<p_planes.size();j++) {
|
||||
|
||||
if (j==i)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
Vector< Vector3 > new_vertices;
|
||||
Plane clip=p_planes[j];
|
||||
|
||||
|
||||
if (clip.normal.dot(p.normal)>0.95)
|
||||
continue;
|
||||
|
||||
|
||||
if (vertices.size()<3)
|
||||
break;
|
||||
|
||||
|
||||
for(int k=0;k<vertices.size();k++) {
|
||||
|
||||
|
||||
int k_n=(k+1)%vertices.size();
|
||||
|
||||
|
||||
Vector3 edge0_A=vertices[k];
|
||||
Vector3 edge1_A=vertices[k_n];
|
||||
|
||||
|
||||
real_t dist0 = clip.distance_to(edge0_A);
|
||||
real_t dist1 = clip.distance_to(edge1_A);
|
||||
|
||||
|
||||
if ( dist0 <= 0 ) { // behind plane
|
||||
|
||||
new_vertices.push_back(vertices[k]);
|
||||
|
||||
|
||||
if ( dist0 <= 0 ) { // behind plane
|
||||
|
||||
new_vertices.push_back(vertices[k]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// check for different sides and non coplanar
|
||||
if ( (dist0*dist1) < 0) {
|
||||
|
||||
if ( (dist0*dist1) < 0) {
|
||||
|
||||
// calculate intersection
|
||||
Vector3 rel = edge1_A - edge0_A;
|
||||
|
||||
@ -822,55 +822,55 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||
real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
|
||||
Vector3 inters = edge0_A+rel*dist;
|
||||
new_vertices.push_back(inters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vertices=new_vertices;
|
||||
}
|
||||
|
||||
|
||||
if (vertices.size()<3)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
|
||||
//result is a clockwise face
|
||||
|
||||
|
||||
MeshData::Face face;
|
||||
|
||||
|
||||
// add face indices
|
||||
for (int j=0;j<vertices.size();j++) {
|
||||
|
||||
|
||||
|
||||
|
||||
int idx=-1;
|
||||
for (int k=0;k<mesh.vertices.size();k++) {
|
||||
|
||||
|
||||
if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
|
||||
|
||||
|
||||
idx=k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (idx==-1) {
|
||||
|
||||
|
||||
idx=mesh.vertices.size();
|
||||
mesh.vertices.push_back(vertices[j]);
|
||||
}
|
||||
|
||||
|
||||
face.indices.push_back(idx);
|
||||
}
|
||||
face.plane=p;
|
||||
mesh.faces.push_back(face);
|
||||
|
||||
|
||||
//add edge
|
||||
|
||||
|
||||
for(int j=0;j<face.indices.size();j++) {
|
||||
|
||||
|
||||
int a=face.indices[j];
|
||||
int b=face.indices[(j+1)%face.indices.size()];
|
||||
|
||||
|
||||
bool found=false;
|
||||
for(int k=0;k<mesh.edges.size();k++) {
|
||||
|
||||
|
||||
if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
|
||||
found=true;
|
||||
break;
|
||||
@ -878,9 +878,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||
if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
MeshData::Edge edge;
|
||||
@ -888,8 +888,8 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||
edge.b=b;
|
||||
mesh.edges.push_back(edge);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return mesh;
|
||||
@ -899,36 +899,36 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||
DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
|
||||
|
||||
DVector<Plane> planes;
|
||||
|
||||
|
||||
planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
|
||||
planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
|
||||
planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
|
||||
planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
|
||||
planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
|
||||
planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
|
||||
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
|
||||
|
||||
DVector<Plane> planes;
|
||||
|
||||
|
||||
for (int i=0;i<p_sides;i++) {
|
||||
|
||||
|
||||
Vector3 normal;
|
||||
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
||||
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
||||
|
||||
|
||||
planes.push_back( Plane( normal, p_radius ) );
|
||||
}
|
||||
|
||||
|
||||
Vector3 axis;
|
||||
axis[p_axis]=1.0;
|
||||
|
||||
|
||||
planes.push_back( Plane( axis, p_height*0.5 ) );
|
||||
planes.push_back( Plane( -axis, p_height*0.5 ) );
|
||||
|
||||
|
||||
return planes;
|
||||
|
||||
}
|
||||
@ -972,34 +972,34 @@ DVector<Plane> Geometry::build_sphere_planes(float p_radius, int p_lats,int p_lo
|
||||
DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
|
||||
|
||||
DVector<Plane> planes;
|
||||
|
||||
|
||||
Vector3 axis;
|
||||
axis[p_axis]=1.0;
|
||||
|
||||
Vector3 axis_neg;
|
||||
|
||||
Vector3 axis_neg;
|
||||
axis_neg[(p_axis+1)%3]=1.0;
|
||||
axis_neg[(p_axis+2)%3]=1.0;
|
||||
axis_neg[p_axis]=-1.0;
|
||||
|
||||
|
||||
for (int i=0;i<p_sides;i++) {
|
||||
|
||||
|
||||
Vector3 normal;
|
||||
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
||||
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
||||
|
||||
|
||||
planes.push_back( Plane( normal, p_radius ) );
|
||||
|
||||
|
||||
for (int j=1;j<=p_lats;j++) {
|
||||
|
||||
|
||||
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
|
||||
Vector3 pos = axis*p_height*0.5 + angle*p_radius;
|
||||
planes.push_back( Plane( pos, angle ) );
|
||||
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return planes;
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
class Geometry {
|
||||
Geometry();
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -201,37 +201,37 @@ public:
|
||||
real_t a =e1.dot(h);
|
||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||
return false;
|
||||
|
||||
|
||||
real_t f=1.0/a;
|
||||
|
||||
|
||||
Vector3 s=p_from-p_v0;
|
||||
real_t u = f * s.dot(h);
|
||||
|
||||
|
||||
if ( u< 0.0 || u > 1.0)
|
||||
return false;
|
||||
|
||||
|
||||
Vector3 q=s.cross(e1);
|
||||
|
||||
|
||||
real_t v = f * p_dir.dot(q);
|
||||
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
return false;
|
||||
|
||||
// at this stage we can compute t to find out where
|
||||
|
||||
// at this stage we can compute t to find out where
|
||||
// the intersection point is on the line
|
||||
real_t t = f * e2.dot(q);
|
||||
|
||||
|
||||
if (t > 0.00001) {// ray intersection
|
||||
if (r_res)
|
||||
*r_res=p_from+p_dir*t;
|
||||
return true;
|
||||
} else // this means that there is a line intersection
|
||||
} else // this means that there is a line intersection
|
||||
// but not a ray intersection
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) {
|
||||
|
||||
|
||||
Vector3 rel=p_to-p_from;
|
||||
Vector3 e1=p_v1-p_v0;
|
||||
Vector3 e2=p_v2-p_v0;
|
||||
@ -239,34 +239,34 @@ public:
|
||||
real_t a =e1.dot(h);
|
||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||
return false;
|
||||
|
||||
|
||||
real_t f=1.0/a;
|
||||
|
||||
|
||||
Vector3 s=p_from-p_v0;
|
||||
real_t u = f * s.dot(h);
|
||||
|
||||
|
||||
if ( u< 0.0 || u > 1.0)
|
||||
return false;
|
||||
|
||||
|
||||
Vector3 q=s.cross(e1);
|
||||
|
||||
|
||||
real_t v = f * rel.dot(q);
|
||||
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
return false;
|
||||
|
||||
// at this stage we can compute t to find out where
|
||||
|
||||
// at this stage we can compute t to find out where
|
||||
// the intersection point is on the line
|
||||
real_t t = f * e2.dot(q);
|
||||
|
||||
|
||||
if (t > CMP_EPSILON && t<=1.0) {// ray intersection
|
||||
if (r_res)
|
||||
*r_res=p_from+rel*t;
|
||||
return true;
|
||||
} else // this means that there is a line intersection
|
||||
} else // this means that there is a line intersection
|
||||
// but not a ray intersection
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) {
|
||||
|
||||
@ -356,24 +356,24 @@ public:
|
||||
real_t box_end=size[i];
|
||||
real_t cmin,cmax;
|
||||
|
||||
|
||||
|
||||
if (seg_from < seg_to) {
|
||||
|
||||
|
||||
if (seg_from > box_end || seg_to < box_begin)
|
||||
return false;
|
||||
real_t length=seg_to-seg_from;
|
||||
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
|
||||
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if (seg_to > box_end || seg_from < box_begin)
|
||||
return false;
|
||||
real_t length=seg_to-seg_from;
|
||||
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
|
||||
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
|
||||
}
|
||||
|
||||
|
||||
if (cmin > min) {
|
||||
min = cmin;
|
||||
axis=i;
|
||||
@ -468,9 +468,9 @@ public:
|
||||
if (l<1e-10)
|
||||
return p_segment[0]; // both points are the same, just give any
|
||||
n/=l;
|
||||
|
||||
|
||||
float d=n.dot(p);
|
||||
|
||||
|
||||
if (d<=0.0)
|
||||
return p_segment[0]; // before first point
|
||||
else if (d>=l)
|
||||
@ -570,27 +570,27 @@ public:
|
||||
|
||||
|
||||
static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) {
|
||||
|
||||
|
||||
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
|
||||
|
||||
Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
|
||||
|
||||
|
||||
|
||||
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
|
||||
|
||||
Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
|
||||
|
||||
if (face_n.dot(n1)<0)
|
||||
return false;
|
||||
|
||||
Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
|
||||
|
||||
|
||||
Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
|
||||
|
||||
if (face_n.dot(n2)<0)
|
||||
return false;
|
||||
|
||||
Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
|
||||
|
||||
|
||||
Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
|
||||
|
||||
if (face_n.dot(n3)<0)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) {
|
||||
@ -814,21 +814,21 @@ public:
|
||||
|
||||
|
||||
struct MeshData {
|
||||
|
||||
|
||||
struct Face {
|
||||
Plane plane;
|
||||
Vector<int> indices;
|
||||
};
|
||||
|
||||
|
||||
Vector<Face> faces;
|
||||
|
||||
|
||||
struct Edge {
|
||||
|
||||
|
||||
int a,b;
|
||||
};
|
||||
|
||||
|
||||
Vector<Edge> edges;
|
||||
|
||||
|
||||
Vector< Vector3 > vertices;
|
||||
|
||||
void optimize_vertices();
|
||||
@ -927,7 +927,7 @@ public:
|
||||
|
||||
static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,10 +45,10 @@ float Vector2::length_squared() const {
|
||||
}
|
||||
|
||||
void Vector2::normalize() {
|
||||
|
||||
|
||||
float l = x*x + y*y;
|
||||
if (l!=0) {
|
||||
|
||||
|
||||
l=Math::sqrt(l);
|
||||
x/=l;
|
||||
y/=l;
|
||||
@ -56,14 +56,14 @@ void Vector2::normalize() {
|
||||
}
|
||||
|
||||
Vector2 Vector2::normalized() const {
|
||||
|
||||
|
||||
Vector2 v=*this;
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
float Vector2::distance_to(const Vector2& p_vector2) const {
|
||||
|
||||
|
||||
return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y));
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ float Vector2::distance_squared_to(const Vector2& p_vector2) const {
|
||||
}
|
||||
|
||||
float Vector2::angle_to(const Vector2& p_vector2) const {
|
||||
|
||||
|
||||
return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) );
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ float Vector2::angle_to_point(const Vector2& p_vector2) const {
|
||||
}
|
||||
|
||||
float Vector2::dot(const Vector2& p_other) const {
|
||||
|
||||
|
||||
return x*p_other.x + y*p_other.y;
|
||||
}
|
||||
|
||||
@ -99,62 +99,62 @@ Vector2 Vector2::cross(real_t p_other) const {
|
||||
|
||||
|
||||
Vector2 Vector2::operator+(const Vector2& p_v) const {
|
||||
|
||||
|
||||
return Vector2(x+p_v.x,y+p_v.y);
|
||||
}
|
||||
void Vector2::operator+=(const Vector2& p_v) {
|
||||
|
||||
|
||||
x+=p_v.x; y+=p_v.y;
|
||||
}
|
||||
Vector2 Vector2::operator-(const Vector2& p_v) const {
|
||||
|
||||
|
||||
return Vector2(x-p_v.x,y-p_v.y);
|
||||
}
|
||||
void Vector2::operator-=(const Vector2& p_v) {
|
||||
|
||||
|
||||
x-=p_v.x; y-=p_v.y;
|
||||
}
|
||||
|
||||
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
|
||||
|
||||
|
||||
return Vector2(x * p_v1.x, y * p_v1.y);
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator*(const float &rvalue) const {
|
||||
|
||||
|
||||
return Vector2(x * rvalue, y * rvalue);
|
||||
};
|
||||
void Vector2::operator*=(const float &rvalue) {
|
||||
|
||||
|
||||
x *= rvalue; y *= rvalue;
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
|
||||
|
||||
|
||||
return Vector2(x / p_v1.x, y / p_v1.y);
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator/(const float &rvalue) const {
|
||||
|
||||
|
||||
return Vector2(x / rvalue, y / rvalue);
|
||||
};
|
||||
|
||||
void Vector2::operator/=(const float &rvalue) {
|
||||
|
||||
|
||||
x /= rvalue; y /= rvalue;
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator-() const {
|
||||
|
||||
|
||||
return Vector2(-x,-y);
|
||||
}
|
||||
|
||||
bool Vector2::operator==(const Vector2& p_vec2) const {
|
||||
|
||||
|
||||
return x==p_vec2.x && y==p_vec2.y;
|
||||
}
|
||||
bool Vector2::operator!=(const Vector2& p_vec2) const {
|
||||
|
||||
|
||||
return x!=p_vec2.x || y!=p_vec2.y;
|
||||
}
|
||||
Vector2 Vector2::floor() const {
|
||||
@ -621,25 +621,25 @@ float Matrix32::basis_determinant() const {
|
||||
}
|
||||
|
||||
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
|
||||
|
||||
|
||||
//extract parameters
|
||||
Vector2 p1 = get_origin();
|
||||
Vector2 p2 = p_transform.get_origin();
|
||||
|
||||
|
||||
real_t r1 = get_rotation();
|
||||
real_t r2 = p_transform.get_rotation();
|
||||
|
||||
|
||||
Vector2 s1 = get_scale();
|
||||
Vector2 s2 = p_transform.get_scale();
|
||||
|
||||
|
||||
//slerp rotation
|
||||
Vector2 v1(Math::cos(r1), Math::sin(r1));
|
||||
Vector2 v2(Math::cos(r2), Math::sin(r2));
|
||||
|
||||
|
||||
real_t dot = v1.dot(v2);
|
||||
|
||||
|
||||
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
|
||||
|
||||
|
||||
Vector2 v;
|
||||
|
||||
if (dot > 0.9995) {
|
||||
@ -649,7 +649,7 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons
|
||||
Vector2 v3 = (v2 - v1*dot).normalized();
|
||||
v = v1*Math::cos(angle) + v3*Math::sin(angle);
|
||||
}
|
||||
|
||||
|
||||
//construct matrix
|
||||
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
|
||||
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
|
||||
|
@ -35,15 +35,15 @@
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
enum Margin {
|
||||
|
||||
|
||||
MARGIN_LEFT,
|
||||
MARGIN_TOP,
|
||||
MARGIN_RIGHT,
|
||||
MARGIN_BOTTOM
|
||||
MARGIN_BOTTOM
|
||||
};
|
||||
|
||||
enum Orientation {
|
||||
|
||||
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
@ -63,7 +63,7 @@ enum VAlign {
|
||||
};
|
||||
|
||||
struct Vector2 {
|
||||
|
||||
|
||||
union {
|
||||
float x;
|
||||
float width;
|
||||
@ -87,7 +87,7 @@ struct Vector2 {
|
||||
float length() const;
|
||||
float length_squared() const;
|
||||
|
||||
float distance_to(const Vector2& p_vector2) const;
|
||||
float distance_to(const Vector2& p_vector2) const;
|
||||
float distance_squared_to(const Vector2& p_vector2) const;
|
||||
float angle_to(const Vector2& p_vector2) const;
|
||||
float angle_to_point(const Vector2& p_vector2) const;
|
||||
@ -114,19 +114,19 @@ struct Vector2 {
|
||||
Vector2 operator-(const Vector2& p_v) const;
|
||||
void operator-=(const Vector2& p_v);
|
||||
Vector2 operator*(const Vector2 &p_v1) const;
|
||||
|
||||
|
||||
Vector2 operator*(const float &rvalue) const;
|
||||
void operator*=(const float &rvalue);
|
||||
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
|
||||
|
||||
Vector2 operator/(const Vector2 &p_v1) const;
|
||||
|
||||
|
||||
Vector2 operator/(const float &rvalue) const;
|
||||
|
||||
|
||||
void operator/=(const float &rvalue);
|
||||
|
||||
|
||||
Vector2 operator-() const;
|
||||
|
||||
|
||||
bool operator==(const Vector2& p_vec2) const;
|
||||
bool operator!=(const Vector2& p_vec2) const;
|
||||
|
||||
@ -151,14 +151,14 @@ struct Vector2 {
|
||||
|
||||
return Vector2(y,-x);
|
||||
}
|
||||
|
||||
|
||||
Vector2 floor() const;
|
||||
Vector2 snapped(const Vector2& p_by) const;
|
||||
float get_aspect() const { return width/height; }
|
||||
|
||||
|
||||
|
||||
operator String() const { return String::num(x)+","+String::num(y); }
|
||||
|
||||
|
||||
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||
_FORCE_INLINE_ Vector2() { x=0; y=0; }
|
||||
};
|
||||
@ -202,7 +202,7 @@ struct Matrix32;
|
||||
|
||||
|
||||
struct Rect2 {
|
||||
|
||||
|
||||
Point2 pos;
|
||||
Size2 size;
|
||||
|
||||
@ -213,7 +213,7 @@ struct Rect2 {
|
||||
|
||||
float get_area() const { return size.width*size.height; }
|
||||
|
||||
inline bool intersects(const Rect2& p_rect) const {
|
||||
inline bool intersects(const Rect2& p_rect) const {
|
||||
if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
|
||||
return false;
|
||||
if ( (pos.x+size.width) <= p_rect.pos.x )
|
||||
@ -222,7 +222,7 @@ struct Rect2 {
|
||||
return false;
|
||||
if ( (pos.y+size.height) <= p_rect.pos.y )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -254,73 +254,73 @@ struct Rect2 {
|
||||
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
|
||||
|
||||
inline bool encloses(const Rect2& p_rect) const {
|
||||
|
||||
|
||||
return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
|
||||
((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
|
||||
((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline bool has_no_area() const {
|
||||
|
||||
|
||||
return (size.x<=0 || size.y<=0);
|
||||
|
||||
|
||||
}
|
||||
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
|
||||
|
||||
|
||||
Rect2 new_rect=p_rect;
|
||||
|
||||
|
||||
if (!intersects( new_rect ))
|
||||
return Rect2();
|
||||
|
||||
|
||||
new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
|
||||
new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
|
||||
|
||||
|
||||
Point2 p_rect_end=p_rect.pos+p_rect.size;
|
||||
Point2 end=pos+size;
|
||||
|
||||
|
||||
new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
|
||||
new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
|
||||
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
|
||||
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
|
||||
|
||||
|
||||
Rect2 new_rect;
|
||||
|
||||
|
||||
new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
|
||||
new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
|
||||
|
||||
|
||||
|
||||
|
||||
new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
|
||||
new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
|
||||
|
||||
|
||||
new_rect.size = new_rect.size - new_rect.pos; //make relative again
|
||||
|
||||
|
||||
return new_rect;
|
||||
};
|
||||
inline bool has_point(const Point2& p_point) const {
|
||||
if (p_point.x < pos.x)
|
||||
return false;
|
||||
return false;
|
||||
if (p_point.y < pos.y)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
if (p_point.x >= (pos.x+size.x) )
|
||||
return false;
|
||||
return false;
|
||||
if (p_point.y >= (pos.y+size.y) )
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool no_area() const { return (size.width<=0 || size.height<=0 ); }
|
||||
|
||||
|
||||
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
|
||||
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
|
||||
|
||||
|
||||
inline Rect2 grow(real_t p_by) const {
|
||||
|
||||
|
||||
Rect2 g=*this;
|
||||
g.pos.x-=p_by;
|
||||
g.pos.y-=p_by;
|
||||
@ -357,9 +357,9 @@ struct Rect2 {
|
||||
|
||||
|
||||
operator String() const { return String(pos)+","+String(size); }
|
||||
|
||||
|
||||
Rect2() {}
|
||||
Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
|
||||
Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
|
||||
Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; }
|
||||
};
|
||||
|
||||
|
@ -185,12 +185,12 @@ double Math::fmod(double p_x,double p_y) {
|
||||
double Math::fposmod(double p_x,double p_y) {
|
||||
|
||||
if (p_x>=0) {
|
||||
|
||||
|
||||
return Math::fmod(p_x,p_y);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
return p_y-Math::fmod(-p_x,p_y);
|
||||
|
||||
return p_y-Math::fmod(-p_x,p_y);
|
||||
}
|
||||
|
||||
}
|
||||
@ -205,7 +205,7 @@ double Math::ceil(double p_x) {
|
||||
}
|
||||
|
||||
int Math::decimals(double p_step) {
|
||||
|
||||
|
||||
int max=4;
|
||||
double llimit = Math::pow(0.1,max);
|
||||
double ulimit = 1.0-llimit;
|
||||
@ -220,7 +220,7 @@ int Math::decimals(double p_step) {
|
||||
max--;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
@ -251,11 +251,11 @@ double Math::ease(double p_x, double p_c) {
|
||||
}
|
||||
|
||||
double Math::stepify(double p_value,double p_step) {
|
||||
|
||||
|
||||
if (p_step!=0) {
|
||||
|
||||
p_value=floor( p_value / p_step + 0.5 ) * p_step;
|
||||
}
|
||||
|
||||
p_value=floor( p_value / p_step + 0.5 ) * p_step;
|
||||
}
|
||||
return p_value;
|
||||
}
|
||||
|
||||
|
@ -91,25 +91,25 @@ public:
|
||||
|
||||
static uint32_t rand();
|
||||
static double randf();
|
||||
|
||||
|
||||
static double round(double p_val);
|
||||
|
||||
static double random(double from, double to);
|
||||
|
||||
|
||||
|
||||
static _FORCE_INLINE_ real_t abs(real_t g) {
|
||||
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
|
||||
return absd(g);
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
|
||||
return absd(g);
|
||||
#else
|
||||
|
||||
return absf(g);
|
||||
return absf(g);
|
||||
#endif
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ float absf(float g) {
|
||||
|
||||
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
@ -174,7 +174,7 @@ public:
|
||||
static double pow(double x, double y);
|
||||
static double log(double x);
|
||||
static double exp(double x);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -62,11 +62,11 @@ void Matrix3::invert() {
|
||||
real_t det = elements[0][0] * co[0]+
|
||||
elements[0][1] * co[1]+
|
||||
elements[0][2] * co[2];
|
||||
|
||||
|
||||
ERR_FAIL_COND( det == 0 );
|
||||
real_t s = 1.0/det;
|
||||
|
||||
set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
||||
|
||||
set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
||||
co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
||||
co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s );
|
||||
|
||||
@ -148,7 +148,7 @@ Vector3 Matrix3::get_scale() const {
|
||||
Vector3(elements[0][1],elements[1][1],elements[2][1]).length(),
|
||||
Vector3(elements[0][2],elements[1][2],elements[2][2]).length()
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) {
|
||||
|
||||
@ -223,7 +223,7 @@ bool Matrix3::operator==(const Matrix3& p_matrix) const {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
bool Matrix3::operator!=(const Matrix3& p_matrix) const {
|
||||
@ -235,16 +235,16 @@ Matrix3::operator String() const {
|
||||
|
||||
String mtx;
|
||||
for (int i=0;i<3;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
mtx+=", ";
|
||||
|
||||
|
||||
mtx+=rtos( elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return mtx;
|
||||
}
|
||||
|
||||
@ -255,34 +255,34 @@ Matrix3::operator Quat() const {
|
||||
|
||||
real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
|
||||
real_t temp[4];
|
||||
|
||||
if (trace > 0.0)
|
||||
|
||||
if (trace > 0.0)
|
||||
{
|
||||
real_t s = Math::sqrt(trace + 1.0);
|
||||
temp[3]=(s * 0.5);
|
||||
s = 0.5 / s;
|
||||
|
||||
|
||||
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
|
||||
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
|
||||
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = m.elements[0][0] < m.elements[1][1] ?
|
||||
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
|
||||
(m.elements[0][0] < m.elements[2][2] ? 2 : 0);
|
||||
int j = (i + 1) % 3;
|
||||
int j = (i + 1) % 3;
|
||||
int k = (i + 2) % 3;
|
||||
|
||||
|
||||
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
|
||||
temp[i] = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
|
||||
|
||||
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
|
||||
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
|
||||
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
|
||||
}
|
||||
|
||||
|
||||
return Quat(temp[0],temp[1],temp[2],temp[3]);
|
||||
|
||||
}
|
||||
@ -439,7 +439,7 @@ void Matrix3::get_axis_and_angle(Vector3 &r_axis,real_t& r_angle) const {
|
||||
Matrix3::Matrix3(const Vector3& p_euler) {
|
||||
|
||||
set_euler( p_euler );
|
||||
|
||||
|
||||
}
|
||||
|
||||
Matrix3::Matrix3(const Quat& p_quat) {
|
||||
@ -450,8 +450,8 @@ Matrix3::Matrix3(const Quat& p_quat) {
|
||||
real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs;
|
||||
real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs;
|
||||
real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs;
|
||||
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
||||
xy + wz, 1.0 - (xx + zz), yz - wx,
|
||||
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
||||
xy + wz, 1.0 - (xx + zz), yz - wx,
|
||||
xz - wy, yz + wx, 1.0 - (xx + yy)) ;
|
||||
|
||||
}
|
||||
|
@ -39,20 +39,20 @@ class Matrix3 {
|
||||
public:
|
||||
|
||||
Vector3 elements[3];
|
||||
|
||||
|
||||
_FORCE_INLINE_ const Vector3& operator[](int axis) const {
|
||||
|
||||
|
||||
return elements[axis];
|
||||
}
|
||||
_FORCE_INLINE_ Vector3& operator[](int axis) {
|
||||
|
||||
|
||||
return elements[axis];
|
||||
}
|
||||
|
||||
void invert();
|
||||
void invert();
|
||||
void transpose();
|
||||
|
||||
Matrix3 inverse() const;
|
||||
|
||||
Matrix3 inverse() const;
|
||||
Matrix3 transposed() const;
|
||||
|
||||
_FORCE_INLINE_ float determinant() const;
|
||||
@ -90,7 +90,7 @@ public:
|
||||
_FORCE_INLINE_ real_t tdotz(const Vector3& v) const {
|
||||
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const Matrix3& p_matrix) const;
|
||||
bool operator!=(const Matrix3& p_matrix) const;
|
||||
|
||||
@ -110,7 +110,7 @@ public:
|
||||
|
||||
|
||||
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
||||
|
||||
|
||||
elements[0][0]=xx;
|
||||
elements[0][1]=xy;
|
||||
elements[0][2]=xz;
|
||||
@ -119,15 +119,15 @@ public:
|
||||
elements[1][2]=yz;
|
||||
elements[2][0]=zx;
|
||||
elements[2][1]=zy;
|
||||
elements[2][2]=zz;
|
||||
elements[2][2]=zz;
|
||||
}
|
||||
_FORCE_INLINE_ Vector3 get_column(int i) const {
|
||||
|
||||
|
||||
return Vector3(elements[0][i],elements[1][i],elements[2][i]);
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ Vector3 get_row(int i) const {
|
||||
|
||||
|
||||
return Vector3(elements[i][0],elements[i][1],elements[i][2]);
|
||||
}
|
||||
_FORCE_INLINE_ void set_row(int i, const Vector3& p_row) {
|
||||
@ -155,8 +155,8 @@ public:
|
||||
elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
|
||||
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
|
||||
}
|
||||
Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
||||
|
||||
Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
||||
|
||||
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ public:
|
||||
Matrix3(const Vector3& p_axis, real_t p_phi);
|
||||
|
||||
_FORCE_INLINE_ Matrix3() {
|
||||
|
||||
|
||||
elements[0][0]=1;
|
||||
elements[0][1]=0;
|
||||
elements[0][2]=0;
|
||||
@ -191,7 +191,7 @@ _FORCE_INLINE_ void Matrix3::operator*=(const Matrix3& p_matrix) {
|
||||
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
|
||||
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
|
||||
p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
|
||||
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const {
|
||||
|
@ -52,11 +52,11 @@ public:
|
||||
typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int);
|
||||
typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
|
||||
|
||||
private:
|
||||
private:
|
||||
enum {
|
||||
|
||||
|
||||
NEG=0,
|
||||
POS=1,
|
||||
POS=1,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -72,7 +72,7 @@ private:
|
||||
|
||||
|
||||
struct PairKey {
|
||||
|
||||
|
||||
union {
|
||||
struct {
|
||||
OctreeElementID A;
|
||||
@ -80,66 +80,66 @@ private:
|
||||
};
|
||||
uint64_t key;
|
||||
};
|
||||
|
||||
|
||||
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
|
||||
|
||||
|
||||
return key<p_pair.key;
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
|
||||
|
||||
|
||||
if (p_A<p_B) {
|
||||
|
||||
|
||||
A=p_A;
|
||||
B=p_B;
|
||||
B=p_B;
|
||||
} else {
|
||||
|
||||
|
||||
B=p_A;
|
||||
A=p_B;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ PairKey() {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct Element;
|
||||
|
||||
|
||||
struct Octant {
|
||||
|
||||
|
||||
// cached for FAST plane check
|
||||
AABB aabb;
|
||||
|
||||
|
||||
uint64_t last_pass;
|
||||
Octant *parent;
|
||||
Octant *children[8];
|
||||
|
||||
|
||||
int children_count; // cache for amount of childrens (fast check for removal)
|
||||
int parent_index; // cache for parent index (fast check for removal)
|
||||
|
||||
|
||||
List<Element*,AL> pairable_elements;
|
||||
List<Element*,AL> elements;
|
||||
|
||||
|
||||
Octant() {
|
||||
children_count=0;
|
||||
parent_index=-1;
|
||||
last_pass=0;
|
||||
parent=NULL;
|
||||
for (int i=0;i<8;i++)
|
||||
children[i]=NULL;
|
||||
children[i]=NULL;
|
||||
}
|
||||
|
||||
|
||||
~Octant() {
|
||||
|
||||
|
||||
//for (int i=0;i<8;i++)
|
||||
// memdelete_notnull(children[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PairData;
|
||||
|
||||
struct Element {
|
||||
|
||||
|
||||
Octree *octree;
|
||||
|
||||
T *userdata;
|
||||
@ -147,28 +147,28 @@ private:
|
||||
bool pairable;
|
||||
uint32_t pairable_mask;
|
||||
uint32_t pairable_type;
|
||||
|
||||
|
||||
uint64_t last_pass;
|
||||
OctreeElementID _id;
|
||||
Octant *common_parent;
|
||||
|
||||
|
||||
AABB aabb;
|
||||
AABB container_aabb;
|
||||
|
||||
List<PairData*,AL> pair_list;
|
||||
|
||||
|
||||
struct OctantOwner {
|
||||
|
||||
|
||||
Octant *octant;
|
||||
typename List<Element*,AL>::Element *E;
|
||||
}; // an element can be in max 8 octants
|
||||
|
||||
}; // an element can be in max 8 octants
|
||||
|
||||
List<OctantOwner,AL> octant_owners;
|
||||
|
||||
|
||||
|
||||
|
||||
Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PairData {
|
||||
|
||||
@ -181,15 +181,15 @@ private:
|
||||
|
||||
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
|
||||
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
|
||||
ElementMap element_map;
|
||||
PairMap pair_map;
|
||||
ElementMap element_map;
|
||||
PairMap pair_map;
|
||||
|
||||
PairCallback pair_callback;
|
||||
UnpairCallback unpair_callback;
|
||||
void *pair_callback_userdata;
|
||||
void *unpair_callback_userdata;
|
||||
|
||||
OctreeElementID last_element_id;
|
||||
|
||||
OctreeElementID last_element_id;
|
||||
uint64_t pass;
|
||||
|
||||
real_t unit_size;
|
||||
@ -231,7 +231,7 @@ private:
|
||||
|
||||
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
|
||||
return;
|
||||
|
||||
|
||||
if ( !(p_A->pairable_type&p_B->pairable_mask) &&
|
||||
!(p_B->pairable_type&p_A->pairable_mask) )
|
||||
return; // none can pair with none
|
||||
@ -253,17 +253,17 @@ private:
|
||||
// if (pair_callback)
|
||||
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
|
||||
} else {
|
||||
|
||||
|
||||
E->get().refcount++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
|
||||
|
||||
|
||||
if (p_A==p_B)
|
||||
return;
|
||||
|
||||
|
||||
PairKey key(p_A->_id, p_B->_id);
|
||||
typename PairMap::Element *E=pair_map.find(key);
|
||||
if (!E) {
|
||||
@ -293,7 +293,7 @@ private:
|
||||
p_B->pair_list.erase( E->get().eB );
|
||||
pair_map.erase(E);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
|
||||
@ -341,7 +341,7 @@ private:
|
||||
void _ensure_valid_root(const AABB& p_aabb);
|
||||
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
|
||||
void _remove_element(Element *p_element);
|
||||
void _pair_element(Element *p_element,Octant *p_octant);
|
||||
void _pair_element(Element *p_element,Octant *p_octant);
|
||||
void _unpair_element(Element *p_element,Octant *p_octant);
|
||||
|
||||
|
||||
@ -361,16 +361,16 @@ private:
|
||||
void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask);
|
||||
|
||||
void _remove_tree(Octant *p_octant) {
|
||||
|
||||
|
||||
if (!p_octant)
|
||||
return;
|
||||
|
||||
for(int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i])
|
||||
_remove_tree(p_octant->children[i]);
|
||||
}
|
||||
|
||||
|
||||
memdelete_allocator<Octant,AL>(p_octant);
|
||||
}
|
||||
public:
|
||||
@ -432,24 +432,24 @@ template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) {
|
||||
|
||||
float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
|
||||
|
||||
|
||||
if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) {
|
||||
//if (p_octant->aabb.size.x*0.5 < element_size) {
|
||||
|
||||
/* at smallest possible size for the element */
|
||||
//if (p_octant->aabb.size.x*0.5 < element_size) {
|
||||
|
||||
/* at smallest possible size for the element */
|
||||
typename Element::OctantOwner owner;
|
||||
owner.octant=p_octant;
|
||||
|
||||
|
||||
if (use_pairs && p_element->pairable) {
|
||||
|
||||
|
||||
p_octant->pairable_elements.push_back(p_element);
|
||||
owner.E = p_octant->pairable_elements.back();
|
||||
} else {
|
||||
|
||||
|
||||
p_octant->elements.push_back(p_element);
|
||||
owner.E = p_octant->elements.back();
|
||||
}
|
||||
|
||||
|
||||
p_element->octant_owners.push_back( owner );
|
||||
|
||||
if (p_element->common_parent==NULL) {
|
||||
@ -461,13 +461,13 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
|
||||
|
||||
if (use_pairs && p_octant->children_count>0) {
|
||||
|
||||
|
||||
pass++; //elements below this only get ONE reference added
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i]) {
|
||||
_pair_element(p_element,p_octant->children[i]);
|
||||
_pair_element(p_element,p_octant->children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -477,7 +477,7 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
bool candidate=p_element->common_parent==NULL;
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i]) {
|
||||
/* element exists, go straight to it */
|
||||
if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
|
||||
@ -486,20 +486,20 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
}
|
||||
} else {
|
||||
/* check againt AABB where child should be */
|
||||
|
||||
|
||||
AABB aabb=p_octant->aabb;
|
||||
aabb.size*=0.5;
|
||||
|
||||
|
||||
if (i&1)
|
||||
aabb.pos.x+=aabb.size.x;
|
||||
if (i&2)
|
||||
aabb.pos.y+=aabb.size.y;
|
||||
if (i&4)
|
||||
aabb.pos.z+=aabb.size.z;
|
||||
|
||||
|
||||
if (aabb.intersects_inclusive( p_element->aabb) ) {
|
||||
/* if actually intersects, create the child */
|
||||
|
||||
|
||||
Octant *child = memnew_allocator( Octant, AL );
|
||||
p_octant->children[i]=child;
|
||||
child->parent=p_octant;
|
||||
@ -517,14 +517,14 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (candidate && splits>1) {
|
||||
|
||||
p_element->common_parent=p_octant;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs) {
|
||||
|
||||
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
||||
@ -532,8 +532,8 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
while(E) {
|
||||
_pair_reference( p_element,E->get() );
|
||||
E=E->next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
E=p_octant->elements.front();
|
||||
@ -541,9 +541,9 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||
_pair_reference( p_element,E->get() );
|
||||
E=E->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -553,35 +553,35 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||
|
||||
if (!root) {
|
||||
// octre is empty
|
||||
|
||||
|
||||
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
|
||||
|
||||
|
||||
while ( !base.encloses(p_aabb) ) {
|
||||
|
||||
|
||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||
/* grow towards positive */
|
||||
base.size*=2.0;
|
||||
} else {
|
||||
base.pos-=base.size;
|
||||
base.pos-=base.size;
|
||||
base.size*=2.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
root = memnew_allocator( Octant, AL );
|
||||
|
||||
root->parent=NULL;
|
||||
root->parent_index=-1;
|
||||
root->parent=NULL;
|
||||
root->parent_index=-1;
|
||||
root->aabb=base;
|
||||
|
||||
|
||||
octant_count++;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
AABB base=root->aabb;
|
||||
|
||||
|
||||
while( !base.encloses( p_aabb ) ) {
|
||||
|
||||
|
||||
if (base.size.x > OCTREE_SIZE_LIMIT) {
|
||||
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
|
||||
ERR_FAIL();
|
||||
@ -590,7 +590,7 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||
Octant * gp = memnew_allocator( Octant, AL );
|
||||
octant_count++;
|
||||
root->parent=gp;
|
||||
|
||||
|
||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||
/* grow towards positive */
|
||||
base.size*=2.0;
|
||||
@ -598,16 +598,16 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||
gp->children[0]=root;
|
||||
root->parent_index=0;
|
||||
} else {
|
||||
base.pos-=base.size;
|
||||
base.pos-=base.size;
|
||||
base.size*=2.0;
|
||||
gp->aabb=base;
|
||||
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
|
||||
root->parent_index=(1<<0)|(1<<1)|(1<<2);
|
||||
}
|
||||
|
||||
|
||||
gp->children_count=1;
|
||||
root=gp;
|
||||
}
|
||||
root=gp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,16 +615,16 @@ template<class T,bool use_pairs,class AL>
|
||||
bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) {
|
||||
|
||||
bool octant_removed=false;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
// check all exit conditions
|
||||
|
||||
|
||||
if (p_octant==p_limit) // reached limit, nothing to erase, exit
|
||||
return octant_removed;
|
||||
|
||||
|
||||
bool unpaired=false;
|
||||
|
||||
|
||||
if (use_pairs && p_octant->last_pass!=pass) {
|
||||
// check wether we should unpair stuff
|
||||
// always test pairable
|
||||
@ -644,21 +644,21 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||
p_octant->last_pass=pass;
|
||||
unpaired=true;
|
||||
}
|
||||
|
||||
|
||||
bool removed=false;
|
||||
|
||||
|
||||
Octant *parent=p_octant->parent;
|
||||
|
||||
|
||||
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
// erase octant
|
||||
|
||||
|
||||
if (p_octant==root) { // won't have a parent, just erase
|
||||
|
||||
|
||||
root=NULL;
|
||||
} else {
|
||||
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
|
||||
|
||||
|
||||
parent->children[ p_octant->parent_index ]=NULL;
|
||||
parent->children_count--;
|
||||
}
|
||||
@ -668,12 +668,12 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||
removed=true;
|
||||
octant_removed=true;
|
||||
}
|
||||
|
||||
|
||||
if (!removed && !unpaired)
|
||||
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
|
||||
|
||||
|
||||
p_octant=parent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return octant_removed;
|
||||
@ -682,8 +682,8 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||
template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) {
|
||||
|
||||
|
||||
// always test pairable
|
||||
|
||||
// always test pairable
|
||||
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
||||
while(E) {
|
||||
if (E->get()->last_pass!=pass) { // only remove ONE reference
|
||||
@ -692,7 +692,7 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
|
||||
}
|
||||
E=E->next();
|
||||
}
|
||||
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
E=p_octant->elements.front();
|
||||
@ -704,14 +704,14 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
|
||||
E=E->next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p_octant->last_pass=pass;
|
||||
|
||||
|
||||
if (p_octant->children_count==0)
|
||||
return; // small optimization for leafs
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i])
|
||||
_unpair_element(p_element,p_octant->children[i]);
|
||||
}
|
||||
@ -732,7 +732,7 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
|
||||
}
|
||||
E=E->next();
|
||||
}
|
||||
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
E=p_octant->elements.front();
|
||||
@ -745,12 +745,12 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
|
||||
}
|
||||
}
|
||||
p_octant->last_pass=pass;
|
||||
|
||||
|
||||
if (p_octant->children_count==0)
|
||||
return; // small optimization for leafs
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i])
|
||||
_pair_element(p_element,p_octant->children[i]);
|
||||
}
|
||||
@ -760,13 +760,13 @@ template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
|
||||
|
||||
pass++; // will do a new pass for this
|
||||
|
||||
|
||||
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
|
||||
|
||||
|
||||
|
||||
/* FIRST remove going up normally */
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Octant *o=I->get().octant;
|
||||
|
||||
if (!use_pairs) // small speedup
|
||||
@ -809,14 +809,14 @@ void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
|
||||
int remaining=p_element->pair_list.size();
|
||||
//p_element->pair_list.clear();
|
||||
ERR_FAIL_COND( remaining );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class T,bool use_pairs,class AL>
|
||||
OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) {
|
||||
|
||||
// check for AABB validity
|
||||
// check for AABB validity
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 );
|
||||
ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 );
|
||||
@ -828,12 +828,12 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
|
||||
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 );
|
||||
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
typename ElementMap::Element *E = element_map.insert(last_element_id++,
|
||||
Element());
|
||||
Element &e = E->get();
|
||||
|
||||
|
||||
e.aabb=p_aabb;
|
||||
e.userdata=p_userdata;
|
||||
e.subindex=p_subindex;
|
||||
@ -843,7 +843,7 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
|
||||
e.pairable_type=p_pairable_type;
|
||||
e.pairable_mask=p_pairable_mask;
|
||||
e._id=last_element_id-1;
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_ensure_valid_root(p_aabb);
|
||||
_insert_element(&e,root);
|
||||
@ -964,7 +964,7 @@ void Octree<T,use_pairs,AL>::move(OctreeElementID p_id, const AABB& p_aabb) {
|
||||
_insert_element(&e,common_parent); // reinsert from this point
|
||||
|
||||
pass++;
|
||||
|
||||
|
||||
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
|
||||
|
||||
Octant *o=E->get().octant;
|
||||
@ -1018,28 +1018,28 @@ void Octree<T,use_pairs,AL>::set_pairable(OctreeElementID p_id,bool p_pairable,u
|
||||
|
||||
typename ElementMap::Element *E = element_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
|
||||
|
||||
Element &e = E->get();
|
||||
|
||||
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
|
||||
return; // no changes, return
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_remove_element(&e);
|
||||
}
|
||||
|
||||
|
||||
e.pairable=p_pairable;
|
||||
e.pairable_type=p_pairable_type;
|
||||
e.pairable_mask=p_pairable_mask;
|
||||
e.common_parent=NULL;
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_ensure_valid_root(e.aabb);
|
||||
_insert_element(&e,root);
|
||||
if (use_pairs)
|
||||
_element_check_pairs(&e);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1048,155 +1048,155 @@ void Octree<T,use_pairs,AL>::erase(OctreeElementID p_id) {
|
||||
|
||||
typename ElementMap::Element *E = element_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
|
||||
|
||||
Element &e = E->get();
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
|
||||
_remove_element(&e);
|
||||
|
||||
_remove_element(&e);
|
||||
}
|
||||
|
||||
|
||||
element_map.erase(p_id);
|
||||
_optimize();
|
||||
}
|
||||
|
||||
template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx==p_cull->result_max)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
|
||||
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx<p_cull->result_max) {
|
||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||
(*p_cull->result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
|
||||
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx<p_cull->result_max) {
|
||||
|
||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||
(*p_cull->result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||
_cull_convex(p_octant->children[i],p_cull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) {
|
||||
|
||||
|
||||
if (*p_result_idx==p_result_max)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
|
||||
(*p_result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
(*p_result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
|
||||
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1205,53 +1205,53 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
|
||||
|
||||
if (*p_result_idx==p_result_max)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
(*p_result_idx)++;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
|
||||
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
@ -1259,20 +1259,20 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
|
||||
(*p_result_idx)++;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) {
|
||||
_cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1357,7 +1357,7 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
|
||||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_CullConvexData cdata;
|
||||
@ -1367,9 +1367,9 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
|
||||
cdata.result_max=p_result_max;
|
||||
cdata.result_idx=&result_count;
|
||||
cdata.mask=p_mask;
|
||||
|
||||
|
||||
_cull_convex(root,&cdata);
|
||||
|
||||
|
||||
return result_count;
|
||||
}
|
||||
|
||||
@ -1381,11 +1381,11 @@ int Octree<T,use_pairs,AL>::cull_AABB(const AABB& p_aabb,T** p_result_array,int
|
||||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||
|
||||
|
||||
return result_count;
|
||||
}
|
||||
|
||||
@ -1395,11 +1395,11 @@ int Octree<T,use_pairs,AL>::cull_segment(const Vector3& p_from, const Vector3& p
|
||||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||
|
||||
|
||||
return result_count;
|
||||
|
||||
}
|
||||
@ -1436,7 +1436,7 @@ void Octree<T,use_pairs,AL>::set_unpair_callback( UnpairCallback p_callback, voi
|
||||
|
||||
template<class T,bool use_pairs,class AL>
|
||||
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
|
||||
|
||||
|
||||
last_element_id=1;
|
||||
pass=1;
|
||||
unit_size=p_unit_size;
|
||||
|
@ -50,7 +50,7 @@ void Plane::normalize() {
|
||||
}
|
||||
|
||||
Plane Plane::normalized() const {
|
||||
|
||||
|
||||
Plane p = *this;
|
||||
p.normalize();
|
||||
return p;
|
||||
@ -66,12 +66,12 @@ Vector3 Plane::get_any_perpendicular_normal() const {
|
||||
static const Vector3 p1 = Vector3(1,0,0);
|
||||
static const Vector3 p2 = Vector3(0,1,0);
|
||||
Vector3 p;
|
||||
|
||||
|
||||
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
|
||||
p=p2; // use p2
|
||||
else
|
||||
p=p1; // use p1
|
||||
|
||||
|
||||
p-=normal * normal.dot(p);
|
||||
p.normalize();
|
||||
|
||||
|
@ -62,9 +62,9 @@ public:
|
||||
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
|
||||
|
||||
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
|
||||
|
||||
|
||||
return p_point - normal * distance_to(p_point);
|
||||
}
|
||||
}
|
||||
|
||||
/* misc */
|
||||
|
||||
|
@ -30,9 +30,9 @@
|
||||
#include "print_string.h"
|
||||
|
||||
void Quat::set_euler(const Vector3& p_euler) {
|
||||
real_t half_yaw = p_euler.x * 0.5;
|
||||
real_t half_pitch = p_euler.y * 0.5;
|
||||
real_t half_roll = p_euler.z * 0.5;
|
||||
real_t half_yaw = p_euler.x * 0.5;
|
||||
real_t half_pitch = p_euler.y * 0.5;
|
||||
real_t half_roll = p_euler.z * 0.5;
|
||||
real_t cos_yaw = Math::cos(half_yaw);
|
||||
real_t sin_yaw = Math::sin(half_yaw);
|
||||
real_t cos_pitch = Math::cos(half_pitch);
|
||||
@ -75,7 +75,7 @@ void Quat::normalize() {
|
||||
|
||||
Quat Quat::normalized() const {
|
||||
return *this / length();
|
||||
}
|
||||
}
|
||||
|
||||
Quat Quat::inverse() const {
|
||||
return Quat( -x, -y, -z, w );
|
||||
@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const
|
||||
|
||||
Quat::operator String() const {
|
||||
|
||||
return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
|
||||
return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
|
||||
}
|
||||
|
||||
Quat::Quat(const Vector3& axis, const real_t& angle) {
|
||||
@ -261,7 +261,7 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
|
||||
set(0,0,0,0);
|
||||
else {
|
||||
real_t s = Math::sin(-angle * 0.5) / d;
|
||||
set(axis.x * s, axis.y * s, axis.z * s,
|
||||
set(axis.x * s, axis.y * s, axis.z * s,
|
||||
Math::cos(-angle * 0.5));
|
||||
}
|
||||
}
|
||||
|
@ -89,18 +89,18 @@ public:
|
||||
_FORCE_INLINE_ Quat operator-() const;
|
||||
_FORCE_INLINE_ Quat operator*(const real_t& s) const;
|
||||
_FORCE_INLINE_ Quat operator/(const real_t& s) const;
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
|
||||
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
|
||||
inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||
}
|
||||
inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||
}
|
||||
Quat(const Vector3& axis, const real_t& angle);
|
||||
|
||||
@ -127,7 +127,7 @@ public:
|
||||
}
|
||||
|
||||
inline Quat() {x=y=z=0; w=1; }
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -141,7 +141,7 @@ real_t Quat::length_squared() const {
|
||||
}
|
||||
|
||||
void Quat::operator+=(const Quat& q) {
|
||||
x += q.x; y += q.y; z += q.z; w += q.w;
|
||||
x += q.x; y += q.y; z += q.z; w += q.w;
|
||||
}
|
||||
|
||||
void Quat::operator-=(const Quat& q) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "math_funcs.h"
|
||||
#include "os/copymem.h"
|
||||
#include "print_string.h"
|
||||
|
||||
|
||||
|
||||
void Transform::affine_invert() {
|
||||
|
||||
@ -50,7 +50,7 @@ Transform Transform::affine_inverse() const {
|
||||
void Transform::invert() {
|
||||
|
||||
basis.transpose();
|
||||
origin = basis.xform(-origin);
|
||||
origin = basis.xform(-origin);
|
||||
}
|
||||
|
||||
Transform Transform::inverse() const {
|
||||
@ -87,30 +87,30 @@ void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, cons
|
||||
|
||||
// Reference: MESA source code
|
||||
Vector3 v_x, v_y, v_z;
|
||||
|
||||
|
||||
/* Make rotation matrix */
|
||||
|
||||
|
||||
/* Z vector */
|
||||
v_z = p_eye - p_target;
|
||||
|
||||
|
||||
v_z.normalize();
|
||||
|
||||
|
||||
v_y = p_up;
|
||||
|
||||
|
||||
|
||||
v_x=v_y.cross(v_z);
|
||||
|
||||
|
||||
/* Recompute Y = Z cross X */
|
||||
v_y=v_z.cross(v_x);
|
||||
|
||||
|
||||
v_x.normalize();
|
||||
v_y.normalize();
|
||||
|
||||
|
||||
basis.set_axis(0,v_x);
|
||||
basis.set_axis(1,v_y);
|
||||
basis.set_axis(2,v_z);
|
||||
origin=p_eye;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
|
||||
@ -193,7 +193,7 @@ bool Transform::operator!=(const Transform& p_transform) const {
|
||||
void Transform::operator*=(const Transform& p_transform) {
|
||||
|
||||
origin=xform(p_transform.origin);
|
||||
basis*=p_transform.basis;
|
||||
basis*=p_transform.basis;
|
||||
}
|
||||
|
||||
Transform Transform::operator*(const Transform& p_transform) const {
|
||||
|
@ -40,9 +40,9 @@ public:
|
||||
|
||||
Matrix3 basis;
|
||||
Vector3 origin;
|
||||
|
||||
void invert();
|
||||
Transform inverse() const;
|
||||
|
||||
void invert();
|
||||
Transform inverse() const;
|
||||
|
||||
void affine_invert();
|
||||
Transform affine_inverse() const;
|
||||
@ -76,27 +76,27 @@ public:
|
||||
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
|
||||
_FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
|
||||
_FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
|
||||
|
||||
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
|
||||
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
|
||||
|
||||
|
||||
void operator*=(const Transform& p_transform);
|
||||
Transform operator*(const Transform& p_transform) const;
|
||||
|
||||
Transform interpolate_with(const Transform& p_transform, float p_c) const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
|
||||
|
||||
|
||||
Vector3 v = t.origin - origin;
|
||||
return Transform(basis.transpose_xform(t.basis),
|
||||
basis.xform(v));
|
||||
}
|
||||
|
||||
|
||||
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
|
||||
|
||||
|
||||
basis.elements[0][0]=xx;
|
||||
basis.elements[0][1]=xy;
|
||||
basis.elements[0][2]=xz;
|
||||
@ -105,14 +105,14 @@ public:
|
||||
basis.elements[1][2]=yz;
|
||||
basis.elements[2][0]=zx;
|
||||
basis.elements[2][1]=zy;
|
||||
basis.elements[2][2]=zz;
|
||||
basis.elements[2][2]=zz;
|
||||
origin.x=tx;
|
||||
origin.y=ty;
|
||||
origin.z=tz;
|
||||
}
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
|
||||
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
|
||||
Transform() {}
|
||||
|
||||
@ -128,9 +128,9 @@ _FORCE_INLINE_ Vector3 Transform::xform(const Vector3& p_vector) const {
|
||||
);
|
||||
}
|
||||
_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
|
||||
|
||||
|
||||
Vector3 v = p_vector - origin;
|
||||
|
||||
|
||||
return Vector3(
|
||||
(basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
|
||||
(basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
|
||||
@ -140,16 +140,16 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
|
||||
|
||||
_FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
|
||||
|
||||
|
||||
|
||||
Vector3 point=p_plane.normal*p_plane.d;
|
||||
Vector3 point_dir=point+p_plane.normal;
|
||||
point=xform(point);
|
||||
point_dir=xform(point_dir);
|
||||
|
||||
|
||||
Vector3 normal=point_dir-point;
|
||||
normal.normalize();
|
||||
real_t d=normal.dot(point);
|
||||
|
||||
|
||||
return Plane(normal,d);
|
||||
|
||||
}
|
||||
@ -159,11 +159,11 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane& p_plane) const {
|
||||
Vector3 point_dir=point+p_plane.normal;
|
||||
xform_inv(point);
|
||||
xform_inv(point_dir);
|
||||
|
||||
|
||||
Vector3 normal=point_dir-point;
|
||||
normal.normalize();
|
||||
real_t d=normal.dot(point);
|
||||
|
||||
|
||||
return Plane(normal,d);
|
||||
|
||||
}
|
||||
@ -199,17 +199,17 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB& p_aabb) const {
|
||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
AABB ret;
|
||||
|
||||
|
||||
ret.pos=xform(vertices[0]);
|
||||
|
||||
|
||||
for (int i=1;i<8;i++) {
|
||||
|
||||
|
||||
ret.expand_to( xform(vertices[i]) );
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
@ -227,17 +227,17 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB& p_aabb) const {
|
||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
AABB ret;
|
||||
|
||||
|
||||
ret.pos=xform_inv(vertices[0]);
|
||||
|
||||
|
||||
for (int i=1;i<8;i++) {
|
||||
|
||||
|
||||
ret.expand_to( xform_inv(vertices[i]) );
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ template<class T>
|
||||
struct VariantCaster {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||
|
||||
return p_variant;
|
||||
|
||||
return p_variant;
|
||||
}
|
||||
};
|
||||
|
||||
@ -67,8 +67,8 @@ template<class T>
|
||||
struct VariantCaster<T&> {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||
|
||||
return p_variant;
|
||||
|
||||
return p_variant;
|
||||
}
|
||||
};
|
||||
|
||||
@ -76,8 +76,8 @@ template<class T>
|
||||
struct VariantCaster<const T&> {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||
|
||||
return p_variant;
|
||||
|
||||
return p_variant;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -255,7 +255,7 @@ Object::Connection::Connection(const Variant& p_variant) {
|
||||
|
||||
|
||||
bool Object::_predelete() {
|
||||
|
||||
|
||||
_predelete_ok=1;
|
||||
notification(NOTIFICATION_PREDELETE,true);
|
||||
if (_predelete_ok) {
|
||||
@ -269,16 +269,16 @@ void Object::_postinitialize() {
|
||||
_type_ptr=_get_type_namev();
|
||||
_initialize_typev();
|
||||
notification(NOTIFICATION_POSTINITIALIZE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Object::get_valid_parents_static(List<String> *p_parents) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
void Object::_get_valid_parents_static(List<String> *p_parents) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#if 0
|
||||
//old style set, deprecated
|
||||
@ -286,7 +286,7 @@ void Object::_get_valid_parents_static(List<String> *p_parents) {
|
||||
void Object::set(const String& p_name, const Variant& p_value) {
|
||||
|
||||
_setv(p_name,p_value);
|
||||
|
||||
|
||||
//if (!_use_builtin_script())
|
||||
// return;
|
||||
|
||||
@ -303,8 +303,8 @@ void Object::set(const String& p_name, const Variant& p_value) {
|
||||
} else if (script_instance) {
|
||||
script_instance->set(p_name,p_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -348,7 +348,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
|
||||
*r_valid=true;
|
||||
return;
|
||||
} else {
|
||||
//something inside the object... :|
|
||||
//something inside the object... :|
|
||||
bool success = _setv(p_name,p_value);
|
||||
if (success) {
|
||||
if (r_valid)
|
||||
@ -420,7 +420,7 @@ Variant Object::get(const String& p_name) const {
|
||||
Variant ret=_getv(p_name);
|
||||
if (ret.get_type()!=Variant::NIL)
|
||||
return ret;
|
||||
|
||||
|
||||
bool success;
|
||||
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
|
||||
if (success) {
|
||||
@ -431,11 +431,11 @@ Variant Object::get(const String& p_name) const {
|
||||
return metadata;
|
||||
else if (p_name=="script/script")
|
||||
return script;
|
||||
|
||||
|
||||
if (script_instance) {
|
||||
return script_instance->get(p_name);
|
||||
}
|
||||
|
||||
|
||||
return Variant();
|
||||
|
||||
}
|
||||
@ -449,10 +449,10 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
|
||||
}
|
||||
|
||||
_get_property_listv(p_list,p_reversed);
|
||||
|
||||
|
||||
if (!_use_builtin_script())
|
||||
return;
|
||||
|
||||
|
||||
if (!is_type("Script")) // can still be set, but this is for userfriendlyness
|
||||
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
|
||||
if (!metadata.empty())
|
||||
@ -460,15 +460,15 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
|
||||
if (script_instance && !p_reversed) {
|
||||
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
|
||||
script_instance->get_property_list(p_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void Object::get_method_list(List<MethodInfo> *p_list) const {
|
||||
|
||||
ObjectTypeDB::get_method_list(get_type_name(),p_list);
|
||||
if (script_instance) {
|
||||
script_instance->get_method_list(p_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -898,22 +898,22 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
|
||||
|
||||
|
||||
void Object::notification(int p_notification,bool p_reversed) {
|
||||
|
||||
|
||||
|
||||
_notificationv(p_notification,p_reversed);
|
||||
|
||||
|
||||
if (script_instance) {
|
||||
script_instance->notification(p_notification);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::_changed_callback(Object *p_changed,const char *p_prop) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Object::add_change_receptor( Object *p_receptor ) {
|
||||
|
||||
|
||||
change_receptors.insert(p_receptor);
|
||||
}
|
||||
|
||||
@ -941,8 +941,8 @@ void Object::set_script(const RefPtr& p_script) {
|
||||
memdelete(script_instance);
|
||||
script_instance=NULL;
|
||||
}
|
||||
|
||||
script=p_script;
|
||||
|
||||
script=p_script;
|
||||
Ref<Script> s(script);
|
||||
|
||||
if (!s.is_null() && s->can_instance() ) {
|
||||
@ -1760,7 +1760,7 @@ bool Object::is_edited() const {
|
||||
#endif
|
||||
|
||||
Object::Object() {
|
||||
|
||||
|
||||
_type_ptr=NULL;
|
||||
_block_signals=false;
|
||||
_predelete_ok=0;
|
||||
@ -1831,12 +1831,12 @@ Object::~Object() {
|
||||
|
||||
|
||||
bool predelete_handler(Object *p_object) {
|
||||
|
||||
|
||||
return p_object->_predelete();
|
||||
}
|
||||
|
||||
void postinitialize_handler(Object *p_object) {
|
||||
|
||||
|
||||
p_object->_postinitialize();
|
||||
}
|
||||
|
||||
@ -1900,8 +1900,8 @@ void ObjectDB::cleanup() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
if (instances.size()) {
|
||||
|
||||
WARN_PRINT("ObjectDB Instances still exist!");
|
||||
|
||||
WARN_PRINT("ObjectDB Instances still exist!");
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
const uint32_t *K=NULL;
|
||||
while((K=instances.next(K))) {
|
||||
|
@ -200,37 +200,37 @@ ObjectTypeDB::TypeInfo::TypeInfo() {
|
||||
disabled=false;
|
||||
}
|
||||
ObjectTypeDB::TypeInfo::~TypeInfo() {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
StringName inherits=p_type;
|
||||
|
||||
|
||||
while (inherits.operator String().length()) {
|
||||
|
||||
|
||||
if (inherits==p_inherits)
|
||||
return true;
|
||||
inherits=type_inherits_from(inherits);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
p_types->push_back(*k);
|
||||
}
|
||||
|
||||
|
||||
p_types->sort();
|
||||
}
|
||||
|
||||
@ -238,11 +238,11 @@ void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
if (*k!=p_type && is_type(*k,p_type))
|
||||
p_types->push_back(*k);
|
||||
}
|
||||
@ -250,18 +250,18 @@ void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName
|
||||
}
|
||||
|
||||
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *ti = types.getptr(p_type);
|
||||
ERR_FAIL_COND_V(!ti,"");
|
||||
return ti->inherits;
|
||||
}
|
||||
|
||||
bool ObjectTypeDB::type_exists(const StringName &p_type) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
return types.has(p_type);
|
||||
return types.has(p_type);
|
||||
}
|
||||
|
||||
void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) {
|
||||
@ -270,7 +270,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
|
||||
}
|
||||
|
||||
Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||
|
||||
|
||||
TypeInfo *ti;
|
||||
{
|
||||
OBJTYPE_LOCK;
|
||||
@ -288,9 +288,9 @@ Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||
return ti->creation_func();
|
||||
}
|
||||
bool ObjectTypeDB::can_instance(const StringName &p_type) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *ti = types.getptr(p_type);
|
||||
ERR_FAIL_COND_V(!ti,false);
|
||||
return (!ti->disabled && ti->creation_func!=NULL);
|
||||
@ -326,11 +326,11 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
if (type->disabled) {
|
||||
|
||||
if (p_no_inheritance)
|
||||
@ -348,14 +348,14 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||
}
|
||||
|
||||
for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
|
||||
|
||||
|
||||
MethodBind *method=type->method_map.get(E->get());
|
||||
MethodInfo minfo;
|
||||
minfo.name=E->get();
|
||||
minfo.id=method->get_method_id();
|
||||
|
||||
for (int i=0;i<method->get_argument_count();i++) {
|
||||
|
||||
|
||||
//Variant::Type t=method->get_argument_type(i);
|
||||
|
||||
minfo.arguments.push_back(method->get_argument_info(i));
|
||||
@ -386,24 +386,24 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (p_no_inheritance)
|
||||
break;
|
||||
|
||||
|
||||
type=type->inherits_ptr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
MethodBind **method=type->method_map.getptr(p_name);
|
||||
if (method && *method)
|
||||
return *method;
|
||||
@ -416,18 +416,18 @@ MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
||||
void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
if (!type) {
|
||||
|
||||
ERR_FAIL_COND(!type);
|
||||
}
|
||||
|
||||
|
||||
if (type->constant_map.has(p_name)) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
|
||||
type->constant_map[p_name]=p_constant;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
type->constant_order.push_back(p_name);
|
||||
@ -438,11 +438,11 @@ void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringN
|
||||
void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
|
||||
p_constants->push_back(E->get());
|
||||
@ -456,7 +456,7 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
|
||||
#endif
|
||||
if (p_no_inheritance)
|
||||
break;
|
||||
|
||||
|
||||
type=type->inherits_ptr;
|
||||
}
|
||||
|
||||
@ -466,28 +466,28 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
|
||||
int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
|
||||
int *constant=type->constant_map.getptr(p_name);
|
||||
if (constant) {
|
||||
|
||||
|
||||
if (p_success)
|
||||
*p_success=true;
|
||||
return *constant;
|
||||
}
|
||||
|
||||
|
||||
type=type->inherits_ptr;
|
||||
}
|
||||
|
||||
if (p_success)
|
||||
*p_success=false;
|
||||
|
||||
return 0;
|
||||
if (p_success)
|
||||
*p_success=false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
|
||||
@ -966,7 +966,7 @@ void ObjectTypeDB::init() {
|
||||
}
|
||||
|
||||
void ObjectTypeDB::cleanup() {
|
||||
|
||||
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
@ -974,19 +974,19 @@ void ObjectTypeDB::cleanup() {
|
||||
#endif
|
||||
|
||||
//OBJTYPE_LOCK; hah not here
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
TypeInfo &ti=types[*k];
|
||||
|
||||
|
||||
const StringName *m=NULL;
|
||||
while((m=ti.method_map.next(m))) {
|
||||
|
||||
|
||||
memdelete( ti.method_map[*m] );
|
||||
}
|
||||
}
|
||||
}
|
||||
types.clear();
|
||||
resource_base_extensions.clear();
|
||||
compat_types.clear();
|
||||
|
@ -42,9 +42,9 @@ struct ParamHint {
|
||||
PropertyHint hint;
|
||||
String hint_text;
|
||||
Variant default_val;
|
||||
|
||||
|
||||
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
|
||||
|
||||
|
||||
name=p_name;
|
||||
hint=p_hint;
|
||||
hint_text=p_hint_text;
|
||||
@ -73,9 +73,9 @@ struct MethodDefinition {
|
||||
|
||||
StringName name;
|
||||
Vector<StringName> args;
|
||||
MethodDefinition() {}
|
||||
MethodDefinition() {}
|
||||
MethodDefinition(const char *p_name) { name=p_name; }
|
||||
MethodDefinition(const StringName& p_name) { name=p_name; }
|
||||
MethodDefinition(const StringName& p_name) { name=p_name; }
|
||||
};
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
|
||||
#endif
|
||||
|
||||
class ObjectTypeDB {
|
||||
|
||||
|
||||
struct PropertySetGet {
|
||||
|
||||
int index;
|
||||
@ -121,7 +121,7 @@ class ObjectTypeDB {
|
||||
};
|
||||
|
||||
struct TypeInfo {
|
||||
|
||||
|
||||
TypeInfo *inherits_ptr;
|
||||
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
|
||||
HashMap<StringName,int,StringNameHasher> constant_map;
|
||||
@ -143,12 +143,12 @@ class ObjectTypeDB {
|
||||
TypeInfo();
|
||||
~TypeInfo();
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
static Object *creator() {
|
||||
return memnew( T );
|
||||
}
|
||||
|
||||
|
||||
static Mutex *lock;
|
||||
static HashMap<StringName,TypeInfo,StringNameHasher> types;
|
||||
static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
|
||||
@ -163,8 +163,8 @@ class ObjectTypeDB {
|
||||
|
||||
|
||||
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||
template<class T>
|
||||
static void _add_type() {
|
||||
@ -195,7 +195,7 @@ public:
|
||||
|
||||
template<class T>
|
||||
static void register_type() {
|
||||
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_type();
|
||||
TypeInfo *t=types.getptr(T::get_type_static());
|
||||
@ -206,7 +206,7 @@ public:
|
||||
|
||||
template<class T>
|
||||
static void register_virtual_type() {
|
||||
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_type();
|
||||
//nothing
|
||||
@ -247,9 +247,9 @@ public:
|
||||
ParamDef d4=ParamDef(),
|
||||
ParamDef d5=ParamDef()
|
||||
) {
|
||||
|
||||
|
||||
return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -472,7 +472,7 @@ public:
|
||||
|
||||
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
|
||||
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
|
||||
|
||||
|
||||
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
|
||||
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
|
||||
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
void movemem_system(void *to, void *from,int amount) {
|
||||
|
||||
memmove(to,from,amount);
|
||||
memmove(to,from,amount);
|
||||
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ DirAccess *DirAccess::open(const String& p_path,Error *r_error) {
|
||||
}
|
||||
|
||||
DirAccess *DirAccess::create(AccessType p_access) {
|
||||
|
||||
|
||||
DirAccess * da = create_func[p_access]?create_func[p_access]():NULL;
|
||||
if (da) {
|
||||
da->_access_type=p_access;
|
||||
@ -359,7 +359,7 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
|
||||
DirAccess *d=DirAccess::create(p_access);
|
||||
if (!d)
|
||||
return p_path;
|
||||
|
||||
|
||||
d->change_dir(p_path);
|
||||
String full=d->get_current_dir();
|
||||
memdelete(d);
|
||||
@ -367,31 +367,31 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
|
||||
}
|
||||
|
||||
Error DirAccess::copy(String p_from,String p_to) {
|
||||
|
||||
|
||||
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
|
||||
Error err;
|
||||
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
|
||||
|
||||
|
||||
if (err) {
|
||||
|
||||
ERR_FAIL_COND_V( err, err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
|
||||
if (err) {
|
||||
|
||||
|
||||
fsrc->close();
|
||||
memdelete( fsrc );
|
||||
ERR_FAIL_COND_V( err, err );
|
||||
}
|
||||
|
||||
|
||||
fsrc->seek_end(0);
|
||||
int size = fsrc->get_pos();
|
||||
fsrc->seek(0);
|
||||
err = OK;
|
||||
while(size--) {
|
||||
|
||||
|
||||
if (fsrc->get_error()!=OK) {
|
||||
err= fsrc->get_error();
|
||||
break;
|
||||
@ -400,13 +400,13 @@ Error DirAccess::copy(String p_from,String p_to) {
|
||||
err= fdst->get_error();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
fdst->store_8( fsrc->get_8() );
|
||||
}
|
||||
|
||||
|
||||
memdelete(fsrc);
|
||||
memdelete(fdst);
|
||||
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -79,13 +79,13 @@ public:
|
||||
virtual String get_next()=0;
|
||||
virtual bool current_is_dir() const=0;
|
||||
virtual bool current_is_hidden() const=0;
|
||||
|
||||
virtual void list_dir_end()=0; ///<
|
||||
|
||||
|
||||
virtual void list_dir_end()=0; ///<
|
||||
|
||||
virtual int get_drive_count()=0;
|
||||
virtual String get_drive(int p_drive)=0;
|
||||
virtual int get_current_drive();
|
||||
|
||||
|
||||
virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success
|
||||
virtual String get_current_dir()=0; ///< return current dir location
|
||||
virtual Error make_dir(String p_dir)=0;
|
||||
@ -100,7 +100,7 @@ public:
|
||||
virtual Error copy(String p_from,String p_to);
|
||||
virtual Error rename(String p_from, String p_to)=0;
|
||||
virtual Error remove(String p_name)=0;
|
||||
|
||||
|
||||
static String get_full_path(const String& p_path,AccessType p_access);
|
||||
static DirAccess *create_for_path(const String& p_path);
|
||||
|
||||
@ -111,7 +111,7 @@ public:
|
||||
FILE_TYPE_FILE,
|
||||
FILE_TYPE_DIR,
|
||||
};
|
||||
|
||||
|
||||
//virtual DirType get_file_type() const=0;
|
||||
*/
|
||||
static DirAccess *create(AccessType p_access);
|
||||
|
@ -169,69 +169,69 @@ String FileAccess::fix_path(const String& p_path) const {
|
||||
return r_path;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
return r_path;
|
||||
}
|
||||
|
||||
/* these are all implemented for ease of porting, then can later be optimized */
|
||||
|
||||
uint16_t FileAccess::get_16()const {
|
||||
|
||||
|
||||
uint16_t res;
|
||||
uint8_t a,b;
|
||||
|
||||
|
||||
a=get_8();
|
||||
b=get_8();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=8;
|
||||
res|=a;
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
uint32_t FileAccess::get_32() const{
|
||||
|
||||
|
||||
uint32_t res;
|
||||
uint16_t a,b;
|
||||
|
||||
|
||||
a=get_16();
|
||||
b=get_16();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=16;
|
||||
res|=a;
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
uint64_t FileAccess::get_64()const {
|
||||
|
||||
|
||||
uint64_t res;
|
||||
uint32_t a,b;
|
||||
|
||||
|
||||
a=get_32();
|
||||
b=get_32();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=32;
|
||||
res|=a;
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
float FileAccess::get_float() const {
|
||||
@ -262,15 +262,15 @@ String FileAccess::get_line() const {
|
||||
CharString line;
|
||||
|
||||
CharType c=get_8();
|
||||
|
||||
|
||||
while(!eof_reached()) {
|
||||
|
||||
|
||||
if (c=='\n' || c=='\0') {
|
||||
line.push_back(0);
|
||||
return String::utf8(line.get_data());
|
||||
} else if (c!='\r')
|
||||
line.push_back(c);
|
||||
|
||||
|
||||
c=get_8();
|
||||
}
|
||||
line.push_back(0);
|
||||
@ -331,7 +331,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
||||
|
||||
|
||||
int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
|
||||
|
||||
|
||||
int i=0;
|
||||
for (i=0; i<p_length && !eof_reached(); i++)
|
||||
p_dst[i]=get_8();
|
||||
@ -340,53 +340,53 @@ int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
|
||||
}
|
||||
|
||||
void FileAccess::store_16(uint16_t p_dest) {
|
||||
|
||||
|
||||
uint8_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFF;
|
||||
b=p_dest>>8;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_8(a);
|
||||
store_8(b);
|
||||
|
||||
}
|
||||
void FileAccess::store_32(uint32_t p_dest) {
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFFFF;
|
||||
b=p_dest>>16;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_16(a);
|
||||
store_16(b);
|
||||
|
||||
|
||||
}
|
||||
void FileAccess::store_64(uint64_t p_dest) {
|
||||
|
||||
|
||||
uint32_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFFFFFFFF;
|
||||
b=p_dest>>32;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_32(a);
|
||||
store_32(b);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FileAccess::store_real(real_t p_real) {
|
||||
@ -461,7 +461,7 @@ void FileAccess::store_line(const String& p_line) {
|
||||
}
|
||||
|
||||
void FileAccess::store_buffer(const uint8_t *p_src,int p_length) {
|
||||
|
||||
|
||||
for (int i=0;i<p_length;i++)
|
||||
store_8(p_src[i]);
|
||||
}
|
||||
|
@ -80,21 +80,21 @@ public:
|
||||
READ_WRITE=3,
|
||||
WRITE_READ=7,
|
||||
};
|
||||
|
||||
virtual void close()=0; ///< close a file
|
||||
virtual bool is_open() const=0; ///< true when file is open
|
||||
|
||||
virtual void seek(size_t p_position)=0; ///< seek to a given position
|
||||
virtual void seek_end(int64_t p_position=0)=0; ///< seek from the end of file
|
||||
virtual size_t get_pos() const=0; ///< get position in the file
|
||||
virtual size_t get_len() const=0; ///< get size of the file
|
||||
virtual void close()=0; ///< close a file
|
||||
virtual bool is_open() const=0; ///< true when file is open
|
||||
|
||||
virtual bool eof_reached() const=0; ///< reading passed EOF
|
||||
virtual void seek(size_t p_position)=0; ///< seek to a given position
|
||||
virtual void seek_end(int64_t p_position=0)=0; ///< seek from the end of file
|
||||
virtual size_t get_pos() const=0; ///< get position in the file
|
||||
virtual size_t get_len() const=0; ///< get size of the file
|
||||
|
||||
virtual uint8_t get_8() const=0; ///< get a byte
|
||||
virtual uint16_t get_16() const; ///< get 16 bits uint
|
||||
virtual uint32_t get_32() const; ///< get 32 bits uint
|
||||
virtual uint64_t get_64() const; ///< get 64 bits uint
|
||||
virtual bool eof_reached() const=0; ///< reading passed EOF
|
||||
|
||||
virtual uint8_t get_8() const=0; ///< get a byte
|
||||
virtual uint16_t get_16() const; ///< get 16 bits uint
|
||||
virtual uint32_t get_32() const; ///< get 32 bits uint
|
||||
virtual uint64_t get_64() const; ///< get 64 bits uint
|
||||
|
||||
virtual float get_float() const;
|
||||
virtual double get_double() const;
|
||||
@ -103,21 +103,21 @@ public:
|
||||
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
|
||||
virtual String get_line() const;
|
||||
virtual Vector<String> get_csv_line(String delim=",") const;
|
||||
|
||||
|
||||
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
|
||||
* It's not about the current CPU type but file formats.
|
||||
* this flags get reset to false (little endian) on each open
|
||||
*/
|
||||
|
||||
|
||||
virtual void set_endian_swap(bool p_swap) { endian_swap=p_swap; }
|
||||
inline bool get_endian_swap() const { return endian_swap; }
|
||||
|
||||
virtual Error get_error() const=0; ///< get last error
|
||||
virtual Error get_error() const=0; ///< get last error
|
||||
|
||||
virtual void store_8(uint8_t p_dest)=0; ///< store a byte
|
||||
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
|
||||
virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
|
||||
virtual void store_64(uint64_t p_dest); ///< store 64 bits uint
|
||||
virtual void store_8(uint8_t p_dest)=0; ///< store a byte
|
||||
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
|
||||
virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
|
||||
virtual void store_64(uint64_t p_dest); ///< store 64 bits uint
|
||||
|
||||
virtual void store_float(float p_dest);
|
||||
virtual void store_double(double p_dest);
|
||||
@ -129,9 +129,9 @@ public:
|
||||
virtual void store_pascal_string(const String& p_string);
|
||||
virtual String get_pascal_string();
|
||||
|
||||
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
|
||||
|
||||
virtual bool file_exists(const String& p_name)=0; ///< return true if a file exists
|
||||
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
|
||||
|
||||
virtual bool file_exists(const String& p_name)=0; ///< return true if a file exists
|
||||
|
||||
virtual Error reopen(const String& p_path, int p_mode_flags); ///< does not change the AccessType
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
static Input *get_singleton();
|
||||
|
||||
virtual bool is_key_pressed(int p_scancode)=0;
|
||||
virtual bool is_key_pressed(int p_scancode)=0;
|
||||
virtual bool is_mouse_button_pressed(int p_button)=0;
|
||||
virtual bool is_joy_button_pressed(int p_device, int p_button)=0;
|
||||
virtual bool is_action_pressed(const StringName& p_action)=0;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "input_map.h"
|
||||
#include "os/keyboard.h"
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
bool InputEvent::operator==(const InputEvent &p_event) const {
|
||||
@ -40,15 +40,15 @@ bool InputEvent::operator==(const InputEvent &p_event) const {
|
||||
InputEvent::operator String() const {
|
||||
|
||||
String str="Device "+itos(device)+" ID "+itos(ID)+" ";
|
||||
|
||||
|
||||
switch(type) {
|
||||
|
||||
|
||||
case NONE: {
|
||||
|
||||
|
||||
return "Event: None";
|
||||
} break;
|
||||
case KEY: {
|
||||
|
||||
|
||||
str+= "Event: Key ";
|
||||
str=str+"Unicode: "+String::chr(key.unicode)+" Scan: "+itos( key.scancode )+" Echo: "+String(key.echo?"True":"False")+" Pressed"+String(key.pressed?"True":"False")+" Mod: ";
|
||||
if (key.mod.shift)
|
||||
@ -59,15 +59,15 @@ InputEvent::operator String() const {
|
||||
str+="A";
|
||||
if (key.mod.meta)
|
||||
str+="M";
|
||||
|
||||
|
||||
return str;
|
||||
} break;
|
||||
case MOUSE_MOTION: {
|
||||
|
||||
|
||||
str+= "Event: Motion ";
|
||||
str=str+" Pos: " +itos(mouse_motion.x)+","+itos(mouse_motion.y)+" Rel: "+itos(mouse_motion.relative_x)+","+itos(mouse_motion.relative_y)+" Mask: ";
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if ((1<<i)&mouse_motion.button_mask)
|
||||
str+=itos(i+1);
|
||||
}
|
||||
@ -87,7 +87,7 @@ InputEvent::operator String() const {
|
||||
str+= "Event: Button ";
|
||||
str=str+"Pressed: "+itos(mouse_button.pressed)+" Pos: " +itos(mouse_button.x)+","+itos(mouse_button.y)+" Button: "+itos(mouse_button.button_index)+" Mask: ";
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if ((1<<i)&mouse_button.button_mask)
|
||||
str+=itos(i+1);
|
||||
}
|
||||
@ -102,9 +102,9 @@ InputEvent::operator String() const {
|
||||
str+="M";
|
||||
|
||||
str+=String(" DoubleClick: ")+(mouse_button.doubleclick?"Yes":"No");
|
||||
|
||||
|
||||
return str;
|
||||
|
||||
|
||||
} break;
|
||||
case JOYSTICK_MOTION: {
|
||||
str+= "Event: JoystickMotion ";
|
||||
@ -137,7 +137,7 @@ InputEvent::operator String() const {
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ struct InputModifierState {
|
||||
struct InputEventKey {
|
||||
|
||||
InputModifierState mod;
|
||||
|
||||
|
||||
bool pressed; /// otherwise release
|
||||
|
||||
uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks
|
||||
@ -212,11 +212,11 @@ struct InputEventMouse {
|
||||
|
||||
struct InputEventMouseButton : public InputEventMouse {
|
||||
|
||||
|
||||
|
||||
int button_index;
|
||||
bool pressed; //otherwise released
|
||||
bool doubleclick; //last even less than doubleclick time
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct InputEventMouseMotion : public InputEventMouse {
|
||||
|
@ -121,7 +121,7 @@ enum KeyList {
|
||||
KEY_DIRECTION_R=SPKEY | 0x33,
|
||||
KEY_BACK=SPKEY | 0x40,
|
||||
KEY_FORWARD=SPKEY | 0x41,
|
||||
KEY_STOP=SPKEY | 0x42,
|
||||
KEY_STOP=SPKEY | 0x42,
|
||||
KEY_REFRESH=SPKEY | 0x43,
|
||||
KEY_VOLUMEDOWN=SPKEY | 0x44,
|
||||
KEY_VOLUMEMUTE=SPKEY | 0x45,
|
||||
@ -159,11 +159,11 @@ enum KeyList {
|
||||
KEY_LAUNCHD=SPKEY | 0x65,
|
||||
KEY_LAUNCHE=SPKEY | 0x66,
|
||||
KEY_LAUNCHF=SPKEY | 0x67,
|
||||
|
||||
|
||||
KEY_UNKNOWN=SPKEY | 0xFFFFFF,
|
||||
|
||||
|
||||
/* PRINTABLE LATIN 1 CODES */
|
||||
|
||||
|
||||
KEY_SPACE=0x0020,
|
||||
KEY_EXCLAM=0x0021,
|
||||
KEY_QUOTEDBL=0x0022,
|
||||
@ -297,18 +297,18 @@ enum KeyList {
|
||||
KEY_YACUTE=0x00DD,
|
||||
KEY_THORN=0x00DE,
|
||||
KEY_SSHARP=0x00DF,
|
||||
|
||||
|
||||
KEY_DIVISION=0x00F7,
|
||||
KEY_YDIAERESIS=0x00FF,
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum KeyModifierMask {
|
||||
|
||||
|
||||
KEY_CODE_MASK=((1<<25)-1), ///< Apply this mask to any keycode to remove modifiers.
|
||||
KEY_MODIFIER_MASK=(0xFF<<24), ///< Apply this mask to isolate modifiers.
|
||||
KEY_MODIFIER_MASK=(0xFF<<24), ///< Apply this mask to isolate modifiers.
|
||||
KEY_MASK_SHIFT = (1<<25),
|
||||
KEY_MASK_ALT = (1<<26),
|
||||
KEY_MASK_META = (1<<27),
|
||||
@ -322,7 +322,7 @@ enum KeyModifierMask {
|
||||
KEY_MASK_KPAD = (1<<29),
|
||||
KEY_MASK_GROUP_SWITCH = (1<<30)
|
||||
// bit 31 can't be used because variant uses regular 32 bits int as datatype
|
||||
|
||||
|
||||
};
|
||||
|
||||
String keycode_get_string(uint32_t p_code);
|
||||
|
@ -36,7 +36,7 @@
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class MainLoop : public Object {
|
||||
|
||||
|
||||
OBJ_TYPE( MainLoop, Object );
|
||||
OBJ_CATEGORY("Main Loop");
|
||||
|
||||
@ -44,7 +44,7 @@ class MainLoop : public Object {
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
enum {
|
||||
NOTIFICATION_WM_MOUSE_ENTER = 3,
|
||||
@ -55,7 +55,7 @@ public:
|
||||
NOTIFICATION_WM_UNFOCUS_REQUEST = 8,
|
||||
NOTIFICATION_OS_MEMORY_WARNING = 9,
|
||||
};
|
||||
|
||||
|
||||
virtual void input_event( const InputEvent& p_event );
|
||||
virtual void input_text( const String& p_text );
|
||||
|
||||
|
@ -88,16 +88,16 @@ void Memory::dump_static_mem_to_file(const char* p_file) {
|
||||
MID Memory::alloc_dynamic(size_t p_bytes, const char *p_descr) {
|
||||
|
||||
MemoryPoolDynamic::ID id = MemoryPoolDynamic::get_singleton()->alloc(p_bytes,p_descr);
|
||||
|
||||
|
||||
return MID(id);
|
||||
}
|
||||
Error Memory::realloc_dynamic(MID p_mid,size_t p_bytes) {
|
||||
|
||||
MemoryPoolDynamic::ID id = p_mid.data?p_mid.data->id:MemoryPoolDynamic::INVALID_ID;
|
||||
|
||||
|
||||
if (id==MemoryPoolDynamic::INVALID_ID)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
|
||||
return MemoryPoolDynamic::get_singleton()->realloc(p_mid, p_bytes);
|
||||
|
||||
}
|
||||
|
@ -42,61 +42,61 @@
|
||||
class MID {
|
||||
|
||||
struct Data {
|
||||
|
||||
|
||||
SafeRefCount refcount;
|
||||
MemoryPoolDynamic::ID id;
|
||||
};
|
||||
|
||||
mutable Data *data;
|
||||
|
||||
|
||||
void unref() {
|
||||
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
if (data->refcount.unref()) {
|
||||
|
||||
|
||||
if (data->id!=MemoryPoolDynamic::INVALID_ID)
|
||||
MemoryPoolDynamic::get_singleton()->free(data->id);
|
||||
MemoryPoolStatic::get_singleton()->free(data);
|
||||
MemoryPoolDynamic::get_singleton()->free(data->id);
|
||||
MemoryPoolStatic::get_singleton()->free(data);
|
||||
}
|
||||
|
||||
|
||||
data=NULL;
|
||||
}
|
||||
|
||||
|
||||
void ref(Data *p_data) {
|
||||
|
||||
|
||||
if (data==p_data)
|
||||
return;
|
||||
unref();
|
||||
|
||||
|
||||
if (p_data && p_data->refcount.ref())
|
||||
data=p_data;
|
||||
data=p_data;
|
||||
}
|
||||
|
||||
|
||||
friend class MID_Lock;
|
||||
|
||||
inline void lock() {
|
||||
|
||||
|
||||
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
|
||||
MemoryPoolDynamic::get_singleton()->lock(data->id);
|
||||
}
|
||||
inline void unlock() {
|
||||
|
||||
|
||||
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
|
||||
MemoryPoolDynamic::get_singleton()->unlock(data->id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline void * get() {
|
||||
|
||||
|
||||
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
|
||||
return MemoryPoolDynamic::get_singleton()->get(data->id);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Error _resize(size_t p_size) {
|
||||
|
||||
|
||||
Error _resize(size_t p_size) {
|
||||
|
||||
if (p_size==0 && (!data || data->id==MemoryPoolDynamic::INVALID_ID))
|
||||
return OK;
|
||||
if (p_size && !data) {
|
||||
@ -104,46 +104,46 @@ friend class MID_Lock;
|
||||
data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
|
||||
ERR_FAIL_COND_V( !data,ERR_OUT_OF_MEMORY );
|
||||
data->refcount.init();
|
||||
data->id=MemoryPoolDynamic::INVALID_ID;
|
||||
data->id=MemoryPoolDynamic::INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
if (p_size==0 && data && data->id==MemoryPoolDynamic::INVALID_ID) {
|
||||
|
||||
|
||||
MemoryPoolDynamic::get_singleton()->free(data->id);
|
||||
data->id=MemoryPoolDynamic::INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
if (p_size>0) {
|
||||
|
||||
|
||||
if (data->id==MemoryPoolDynamic::INVALID_ID) {
|
||||
|
||||
|
||||
data->id=MemoryPoolDynamic::get_singleton()->alloc(p_size,"Unnamed MID");
|
||||
ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
MemoryPoolDynamic::get_singleton()->realloc(data->id,p_size);
|
||||
ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
friend class Memory;
|
||||
|
||||
|
||||
MID(MemoryPoolDynamic::ID p_id) {
|
||||
|
||||
|
||||
data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
|
||||
data->refcount.init();
|
||||
data->id=p_id;
|
||||
}
|
||||
public:
|
||||
public:
|
||||
|
||||
bool is_valid() const { return data; }
|
||||
operator bool() const { return data; }
|
||||
|
||||
|
||||
|
||||
|
||||
size_t get_size() const { return (data && data->id!=MemoryPoolDynamic::INVALID_ID) ? MemoryPoolDynamic::get_singleton()->get_size(data->id) : 0; }
|
||||
Error resize(size_t p_size) { return _resize(p_size); }
|
||||
inline void operator=(const MID& p_mid) { ref( p_mid.data ); }
|
||||
@ -157,7 +157,7 @@ public:
|
||||
class MID_Lock {
|
||||
|
||||
MID mid;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
void *data() { return mid.get(); }
|
||||
@ -174,21 +174,21 @@ class Memory{
|
||||
|
||||
Memory();
|
||||
public:
|
||||
|
||||
|
||||
static void * alloc_static(size_t p_bytes,const char *p_descr="");
|
||||
static void * realloc_static(void *p_memory,size_t p_bytes);
|
||||
static void free_static(void *p_ptr);
|
||||
static size_t get_static_mem_available();
|
||||
static size_t get_static_mem_usage();
|
||||
static size_t get_static_mem_usage();
|
||||
static size_t get_static_mem_max_usage();
|
||||
static void dump_static_mem_to_file(const char* p_file);
|
||||
|
||||
static MID alloc_dynamic(size_t p_bytes, const char *p_descr="");
|
||||
static Error realloc_dynamic(MID p_mid,size_t p_bytes);
|
||||
|
||||
|
||||
static size_t get_dynamic_mem_available();
|
||||
static size_t get_dynamic_mem_usage();
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
@ -241,7 +241,7 @@ _ALWAYS_INLINE_ void postinitialize_handler(void *) {}
|
||||
|
||||
template<class T>
|
||||
_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
|
||||
|
||||
|
||||
postinitialize_handler(p_obj);
|
||||
return p_obj;
|
||||
}
|
||||
@ -272,7 +272,7 @@ _ALWAYS_INLINE_ bool predelete_handler(void *) { return true; }
|
||||
|
||||
template<class T>
|
||||
void memdelete(T *p_class) {
|
||||
|
||||
|
||||
if (!predelete_handler(p_class))
|
||||
return; // doesn't want to be deleted
|
||||
p_class->~T();
|
||||
|
@ -40,10 +40,10 @@ friend class Memory;
|
||||
friend class MID;
|
||||
|
||||
enum {
|
||||
|
||||
|
||||
INVALID_ID=0xFFFFFFFF
|
||||
};
|
||||
|
||||
|
||||
static MemoryPoolDynamic* get_singleton();
|
||||
|
||||
typedef uint64_t ID;
|
||||
@ -55,12 +55,12 @@ friend class MID;
|
||||
virtual bool is_valid(ID p_id)=0;
|
||||
virtual size_t get_size(ID p_id) const=0;
|
||||
virtual const char* get_description(ID p_id) const=0;
|
||||
|
||||
|
||||
virtual Error lock(ID p_id)=0;
|
||||
virtual void * get(ID p_ID)=0;
|
||||
virtual Error unlock(ID p_id)=0;
|
||||
virtual bool is_locked(ID p_id) const=0;
|
||||
|
||||
|
||||
virtual size_t get_available_mem() const=0;
|
||||
virtual size_t get_total_usage() const=0;
|
||||
|
||||
|
@ -37,10 +37,10 @@ MemoryPoolDynamicStatic::Chunk *MemoryPoolDynamicStatic::get_chunk(ID p_id) {
|
||||
|
||||
uint64_t check = p_id/MAX_CHUNKS;
|
||||
uint64_t idx = p_id%MAX_CHUNKS;
|
||||
|
||||
|
||||
if (!chunk[idx].mem || chunk[idx].check!=check)
|
||||
return NULL;
|
||||
|
||||
|
||||
return &chunk[idx];
|
||||
}
|
||||
|
||||
@ -49,32 +49,32 @@ const MemoryPoolDynamicStatic::Chunk *MemoryPoolDynamicStatic::get_chunk(ID p_id
|
||||
|
||||
uint64_t check = p_id/MAX_CHUNKS;
|
||||
uint64_t idx = p_id%MAX_CHUNKS;
|
||||
|
||||
|
||||
if (!chunk[idx].mem || chunk[idx].check!=check)
|
||||
return NULL;
|
||||
|
||||
|
||||
return &chunk[idx];
|
||||
}
|
||||
|
||||
MemoryPoolDynamic::ID MemoryPoolDynamicStatic::alloc(size_t p_amount,const char* p_description) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
int idx=-1;
|
||||
|
||||
|
||||
for (int i=0;i<MAX_CHUNKS;i++) {
|
||||
|
||||
|
||||
last_alloc++;
|
||||
if (last_alloc>=MAX_CHUNKS)
|
||||
last_alloc=0;
|
||||
|
||||
|
||||
if ( !chunk[last_alloc].mem ) {
|
||||
|
||||
|
||||
idx=last_alloc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (idx==-1) {
|
||||
ERR_EXPLAIN("Out of dynamic Memory IDs");
|
||||
@ -86,36 +86,36 @@ MemoryPoolDynamic::ID MemoryPoolDynamicStatic::alloc(size_t p_amount,const char*
|
||||
chunk[idx].mem = memalloc(p_amount);
|
||||
if (!chunk[idx].mem)
|
||||
return INVALID_ID;
|
||||
|
||||
|
||||
chunk[idx].size=p_amount;
|
||||
chunk[idx].check=++last_check;
|
||||
chunk[idx].descr=p_description;
|
||||
chunk[idx].lock=0;
|
||||
|
||||
|
||||
total_usage+=p_amount;
|
||||
if (total_usage>max_usage)
|
||||
max_usage=total_usage;
|
||||
|
||||
|
||||
ID id = chunk[idx].check*MAX_CHUNKS + (uint64_t)idx;
|
||||
|
||||
|
||||
return id;
|
||||
|
||||
|
||||
}
|
||||
void MemoryPoolDynamicStatic::free(ID p_id) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND(!c);
|
||||
|
||||
|
||||
|
||||
|
||||
total_usage-=c->size;
|
||||
memfree(c->mem);
|
||||
|
||||
c->mem=0;
|
||||
|
||||
|
||||
if (c->lock>0) {
|
||||
|
||||
|
||||
ERR_PRINT("Freed ID Still locked");
|
||||
}
|
||||
}
|
||||
@ -123,14 +123,14 @@ void MemoryPoolDynamicStatic::free(ID p_id) {
|
||||
Error MemoryPoolDynamicStatic::realloc(ID p_id, size_t p_amount) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(c->lock > 0 , ERR_LOCKED );
|
||||
|
||||
|
||||
|
||||
|
||||
void * new_mem = memrealloc(c->mem,p_amount);
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(!new_mem,ERR_OUT_OF_MEMORY);
|
||||
total_usage-=c->size;
|
||||
c->mem=new_mem;
|
||||
@ -138,37 +138,37 @@ Error MemoryPoolDynamicStatic::realloc(ID p_id, size_t p_amount) {
|
||||
total_usage+=c->size;
|
||||
if (total_usage>max_usage)
|
||||
max_usage=total_usage;
|
||||
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
bool MemoryPoolDynamicStatic::is_valid(ID p_id) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Chunk *c = get_chunk(p_id);
|
||||
|
||||
|
||||
return c!=NULL;
|
||||
|
||||
}
|
||||
size_t MemoryPoolDynamicStatic::get_size(ID p_id) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
const Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,0);
|
||||
|
||||
|
||||
return c->size;
|
||||
|
||||
|
||||
|
||||
}
|
||||
const char* MemoryPoolDynamicStatic::get_description(ID p_id) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
const Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,"");
|
||||
|
||||
|
||||
return c->descr;
|
||||
|
||||
}
|
||||
@ -177,10 +177,10 @@ const char* MemoryPoolDynamicStatic::get_description(ID p_id) const {
|
||||
bool MemoryPoolDynamicStatic::is_locked(ID p_id) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
const Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,false);
|
||||
|
||||
|
||||
return c->lock>0;
|
||||
|
||||
}
|
||||
@ -188,10 +188,10 @@ bool MemoryPoolDynamicStatic::is_locked(ID p_id) const {
|
||||
Error MemoryPoolDynamicStatic::lock(ID p_id) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
|
||||
|
||||
|
||||
c->lock++;
|
||||
|
||||
return OK;
|
||||
@ -199,23 +199,23 @@ Error MemoryPoolDynamicStatic::lock(ID p_id) {
|
||||
void * MemoryPoolDynamicStatic::get(ID p_id) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
const Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,NULL);
|
||||
ERR_FAIL_COND_V( c->lock==0, NULL );
|
||||
|
||||
|
||||
return c->mem;
|
||||
}
|
||||
Error MemoryPoolDynamicStatic::unlock(ID p_id) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Chunk *c = get_chunk(p_id);
|
||||
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( c->lock<=0, ERR_INVALID_PARAMETER );
|
||||
c->lock--;
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ size_t MemoryPoolDynamicStatic::get_available_mem() const {
|
||||
|
||||
size_t MemoryPoolDynamicStatic::get_total_usage() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
return total_usage;
|
||||
}
|
||||
|
||||
|
@ -40,19 +40,19 @@ class MemoryPoolDynamicStatic : public MemoryPoolDynamic {
|
||||
enum {
|
||||
MAX_CHUNKS=65536
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct Chunk {
|
||||
|
||||
|
||||
uint64_t lock;
|
||||
uint64_t check;
|
||||
void *mem;
|
||||
size_t size;
|
||||
const char *descr;
|
||||
|
||||
const char *descr;
|
||||
|
||||
Chunk() { mem=NULL; lock=0; check=0; }
|
||||
};
|
||||
|
||||
|
||||
Chunk chunk[MAX_CHUNKS];
|
||||
uint64_t last_check;
|
||||
int last_alloc;
|
||||
@ -62,14 +62,14 @@ class MemoryPoolDynamicStatic : public MemoryPoolDynamic {
|
||||
Chunk *get_chunk(ID p_id);
|
||||
const Chunk *get_chunk(ID p_id) const;
|
||||
public:
|
||||
|
||||
|
||||
virtual ID alloc(size_t p_amount,const char* p_description);
|
||||
virtual void free(ID p_id);
|
||||
virtual Error realloc(ID p_id, size_t p_amount);
|
||||
virtual bool is_valid(ID p_id);
|
||||
virtual size_t get_size(ID p_id) const;
|
||||
virtual const char* get_description(ID p_id) const;
|
||||
|
||||
|
||||
virtual bool is_locked(ID p_id) const;
|
||||
virtual Error lock(ID p_id);
|
||||
virtual void * get(ID p_ID);
|
||||
|
@ -31,13 +31,13 @@
|
||||
MemoryPoolStatic *MemoryPoolStatic::singleton=0;
|
||||
|
||||
MemoryPoolStatic *MemoryPoolStatic::get_singleton() {
|
||||
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
|
||||
MemoryPoolStatic::MemoryPoolStatic() {
|
||||
|
||||
|
||||
singleton=this;
|
||||
}
|
||||
|
||||
|
@ -38,17 +38,17 @@
|
||||
*/
|
||||
class MemoryPoolStatic {
|
||||
private:
|
||||
|
||||
|
||||
static MemoryPoolStatic *singleton;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static MemoryPoolStatic *get_singleton();
|
||||
|
||||
|
||||
virtual void* alloc(size_t p_bytes,const char *p_description)=0; ///< Pointer in p_description shold be to a const char const like "hello"
|
||||
virtual void* realloc(void * p_memory,size_t p_bytes)=0; ///< Pointer in p_description shold be to a const char const like "hello"
|
||||
virtual void free(void *p_ptr)=0; ///< Pointer in p_description shold be to a const char const
|
||||
|
||||
|
||||
virtual size_t get_available_mem() const=0;
|
||||
virtual size_t get_total_usage()=0;
|
||||
virtual size_t get_max_usage()=0;
|
||||
|
@ -50,13 +50,13 @@ Mutex::~Mutex() {
|
||||
Mutex *_global_mutex=NULL;;
|
||||
|
||||
void _global_lock() {
|
||||
|
||||
|
||||
if (_global_mutex)
|
||||
_global_mutex->lock();
|
||||
}
|
||||
void _global_unlock() {
|
||||
|
||||
|
||||
if (_global_mutex)
|
||||
_global_mutex->unlock();
|
||||
_global_mutex->unlock();
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* @class Mutex
|
||||
* @class Mutex
|
||||
* @author Juan Linietsky
|
||||
* Portable Mutex (thread-safe locking) implementation.
|
||||
* Mutexes are always recursive ( they don't self-lock in a single thread ).
|
||||
@ -43,9 +43,9 @@
|
||||
|
||||
|
||||
class Mutex {
|
||||
protected:
|
||||
protected:
|
||||
static Mutex* (*create_func)(bool);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual void lock()=0; ///< Lock the mutex, block if locked by someone else
|
||||
@ -53,7 +53,7 @@ public:
|
||||
virtual Error try_lock()=0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock.
|
||||
|
||||
static Mutex * create(bool p_recursive=true); ///< Create a mutex
|
||||
|
||||
|
||||
virtual ~Mutex();
|
||||
};
|
||||
|
||||
|
32
core/os/os.h
32
core/os/os.h
@ -71,7 +71,7 @@ public:
|
||||
RENDER_SEPARATE_THREAD
|
||||
};
|
||||
struct VideoMode {
|
||||
|
||||
|
||||
int width,height;
|
||||
bool fullscreen;
|
||||
bool resizable;
|
||||
@ -80,33 +80,33 @@ public:
|
||||
};
|
||||
protected:
|
||||
friend class Main;
|
||||
|
||||
|
||||
RenderThreadMode _render_thread_mode;
|
||||
|
||||
// functions used by main to initialize/deintialize the OS
|
||||
virtual int get_video_driver_count() const=0;
|
||||
virtual const char * get_video_driver_name(int p_driver) const=0;
|
||||
|
||||
|
||||
virtual VideoMode get_default_video_mode() const=0;
|
||||
|
||||
|
||||
virtual int get_audio_driver_count() const=0;
|
||||
virtual const char * get_audio_driver_name(int p_driver) const=0;
|
||||
|
||||
|
||||
virtual void initialize_core()=0;
|
||||
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver)=0;
|
||||
|
||||
virtual void set_main_loop( MainLoop * p_main_loop )=0;
|
||||
|
||||
virtual void set_main_loop( MainLoop * p_main_loop )=0;
|
||||
virtual void delete_main_loop()=0;
|
||||
|
||||
|
||||
virtual void finalize()=0;
|
||||
virtual void finalize_core()=0;
|
||||
|
||||
virtual void set_cmdline(const char* p_execpath, const List<String>& p_args);
|
||||
|
||||
void _ensure_data_dir();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef int64_t ProcessID;
|
||||
|
||||
static OS* get_singleton();
|
||||
@ -148,7 +148,7 @@ public:
|
||||
|
||||
virtual void set_clipboard(const String& p_text);
|
||||
virtual String get_clipboard() const;
|
||||
|
||||
|
||||
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0)=0;
|
||||
virtual VideoMode get_video_mode(int p_screen=0) const=0;
|
||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const=0;
|
||||
@ -219,7 +219,7 @@ public:
|
||||
DAY_FRIDAY,
|
||||
DAY_SATURDAY
|
||||
};
|
||||
|
||||
|
||||
enum Month {
|
||||
MONTH_JANUARY,
|
||||
MONTH_FEBRUARY,
|
||||
@ -236,7 +236,7 @@ public:
|
||||
};
|
||||
|
||||
struct Date {
|
||||
|
||||
|
||||
int year;
|
||||
Month month;
|
||||
int day;
|
||||
@ -245,7 +245,7 @@ public:
|
||||
};
|
||||
|
||||
struct Time {
|
||||
|
||||
|
||||
int hour;
|
||||
int min;
|
||||
int sec;
|
||||
@ -262,7 +262,7 @@ public:
|
||||
virtual uint64_t get_unix_time() const;
|
||||
virtual uint64_t get_system_time_secs() const;
|
||||
|
||||
virtual void delay_usec(uint32_t p_usec) const=0;
|
||||
virtual void delay_usec(uint32_t p_usec) const=0;
|
||||
virtual uint64_t get_ticks_usec() const=0;
|
||||
uint32_t get_ticks_msec() const;
|
||||
uint64_t get_splash_tick_msec() const;
|
||||
@ -412,7 +412,7 @@ public:
|
||||
|
||||
virtual void set_context(int p_context);
|
||||
|
||||
OS();
|
||||
OS();
|
||||
virtual ~OS();
|
||||
|
||||
};
|
||||
|
@ -35,17 +35,17 @@
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class Semaphore {
|
||||
protected:
|
||||
protected:
|
||||
static Semaphore* (*create_func)();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual Error wait()=0; ///< wait until semaphore has positive value, then decrement and pass
|
||||
virtual Error post()=0; ///< unlock the semaphore, incrementing the value
|
||||
virtual int get() const=0; ///< get semaphore value
|
||||
|
||||
|
||||
static Semaphore * create(); ///< Create a mutex
|
||||
|
||||
|
||||
virtual ~Semaphore();
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
static Shell * get_singleton();
|
||||
virtual void execute(String p_path)=0;
|
||||
|
||||
|
||||
Shell();
|
||||
virtual ~Shell();
|
||||
};
|
||||
|
@ -37,26 +37,26 @@ Error (*Thread::set_name_func)(const String&)=NULL;
|
||||
Thread::ID Thread::_main_thread_id=0;
|
||||
|
||||
Thread::ID Thread::get_caller_ID() {
|
||||
|
||||
|
||||
if (get_thread_ID_func)
|
||||
return get_thread_ID_func();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Thread* Thread::create(ThreadCreateCallback p_callback,void * p_user,const Settings& p_settings) {
|
||||
|
||||
|
||||
if (create_func) {
|
||||
|
||||
|
||||
return create_func(p_callback,p_user,p_settings);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Thread::wait_to_finish(Thread *p_thread) {
|
||||
|
||||
|
||||
if (wait_to_finish_func)
|
||||
wait_to_finish_func(p_thread);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Error Thread::set_name(const String &p_name) {
|
||||
|
@ -41,25 +41,25 @@ typedef void (*ThreadCreateCallback)(void *p_userdata);
|
||||
|
||||
class Thread {
|
||||
public:
|
||||
|
||||
|
||||
enum Priority {
|
||||
|
||||
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_HIGH
|
||||
};
|
||||
|
||||
|
||||
struct Settings {
|
||||
|
||||
|
||||
Priority priority;
|
||||
Settings() { priority=PRIORITY_NORMAL; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef uint64_t ID;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
static Thread* (*create_func)(ThreadCreateCallback p_callback,void *,const Settings&);
|
||||
static ID (*get_thread_ID_func)();
|
||||
static void (*wait_to_finish_func)(Thread*);
|
||||
@ -72,7 +72,7 @@ protected:
|
||||
|
||||
Thread();
|
||||
public:
|
||||
|
||||
|
||||
|
||||
virtual ID get_ID() const=0;
|
||||
|
||||
@ -81,8 +81,8 @@ public:
|
||||
static ID get_caller_ID(); ///< get the ID of the caller function ID
|
||||
static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it.
|
||||
static Thread * create(ThreadCreateCallback p_callback,void * p_user,const Settings& p_settings=Settings()); ///< Static function to create a thread, will call p_callback
|
||||
|
||||
|
||||
|
||||
|
||||
virtual ~Thread();
|
||||
|
||||
};
|
||||
|
@ -30,17 +30,17 @@
|
||||
#include "error_macros.h"
|
||||
#include "os/memory.h"
|
||||
|
||||
ThreadSafe::ThreadSafe() {
|
||||
ThreadSafe::ThreadSafe() {
|
||||
|
||||
mutex = Mutex::create();
|
||||
mutex = Mutex::create();
|
||||
if (!mutex) {
|
||||
|
||||
|
||||
WARN_PRINT("THREAD_SAFE defined, but no default mutex type");
|
||||
}
|
||||
}
|
||||
|
||||
ThreadSafe::~ThreadSafe() {
|
||||
|
||||
if (mutex)
|
||||
memdelete( mutex );
|
||||
ThreadSafe::~ThreadSafe() {
|
||||
|
||||
if (mutex)
|
||||
memdelete( mutex );
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
ThreadSafe();
|
||||
~ThreadSafe();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -51,11 +51,11 @@ class ThreadSafeMethod {
|
||||
const ThreadSafe *_ts;
|
||||
public:
|
||||
ThreadSafeMethod(const ThreadSafe *p_ts) {
|
||||
|
||||
|
||||
_ts=p_ts;
|
||||
_ts->lock();
|
||||
}
|
||||
|
||||
|
||||
~ThreadSafeMethod() { _ts->unlock(); }
|
||||
};
|
||||
|
||||
|
@ -182,12 +182,12 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs,const Variant& p_key,boo
|
||||
err=true;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
||||
} else if (type==TYPE_DICT) {
|
||||
|
||||
uint32_t hash=p_key.hash();
|
||||
uint32_t len = decode_uint32(r+4);
|
||||
|
||||
|
||||
bool found=false;
|
||||
for(int i=0;i<len;i++) {
|
||||
uint32_t khash=decode_uint32(r+8+i*12+0);
|
||||
@ -214,7 +214,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs,const Variant& p_key,boo
|
||||
err=true;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user