mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Bring that Whole New World to the Old Continent too
Applies the clang-format style to the 2.1 branch as done for master in
5dbf1809c6.
This commit is contained in:
parent
1d418afe86
commit
f8db8a3faa
1308 changed files with 147754 additions and 174357 deletions
|
|
@ -31,164 +31,152 @@
|
|||
#include "servers/physics_server.h"
|
||||
void Area::set_space_override_mode(SpaceOverride p_mode) {
|
||||
|
||||
space_override=p_mode;
|
||||
PhysicsServer::get_singleton()->area_set_space_override_mode(get_rid(),PhysicsServer::AreaSpaceOverrideMode(p_mode));
|
||||
|
||||
|
||||
space_override = p_mode;
|
||||
PhysicsServer::get_singleton()->area_set_space_override_mode(get_rid(), PhysicsServer::AreaSpaceOverrideMode(p_mode));
|
||||
}
|
||||
Area::SpaceOverride Area::get_space_override_mode() const{
|
||||
Area::SpaceOverride Area::get_space_override_mode() const {
|
||||
|
||||
return space_override;
|
||||
}
|
||||
|
||||
void Area::set_gravity_is_point(bool p_enabled){
|
||||
|
||||
gravity_is_point=p_enabled;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT,p_enabled);
|
||||
void Area::set_gravity_is_point(bool p_enabled) {
|
||||
|
||||
gravity_is_point = p_enabled;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT, p_enabled);
|
||||
}
|
||||
bool Area::is_gravity_a_point() const{
|
||||
bool Area::is_gravity_a_point() const {
|
||||
|
||||
return gravity_is_point;
|
||||
}
|
||||
|
||||
void Area::set_gravity_distance_scale(real_t p_scale){
|
||||
|
||||
gravity_distance_scale=p_scale;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE,p_scale);
|
||||
void Area::set_gravity_distance_scale(real_t p_scale) {
|
||||
|
||||
gravity_distance_scale = p_scale;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale);
|
||||
}
|
||||
|
||||
real_t Area::get_gravity_distance_scale() const{
|
||||
real_t Area::get_gravity_distance_scale() const {
|
||||
return gravity_distance_scale;
|
||||
}
|
||||
|
||||
void Area::set_gravity_vector(const Vector3& p_vec){
|
||||
|
||||
gravity_vec=p_vec;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY_VECTOR,p_vec);
|
||||
void Area::set_gravity_vector(const Vector3 &p_vec) {
|
||||
|
||||
gravity_vec = p_vec;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, p_vec);
|
||||
}
|
||||
Vector3 Area::get_gravity_vector() const{
|
||||
Vector3 Area::get_gravity_vector() const {
|
||||
|
||||
return gravity_vec;
|
||||
}
|
||||
|
||||
void Area::set_gravity(real_t p_gravity){
|
||||
void Area::set_gravity(real_t p_gravity) {
|
||||
|
||||
gravity=p_gravity;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY,p_gravity);
|
||||
gravity = p_gravity;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_GRAVITY, p_gravity);
|
||||
}
|
||||
real_t Area::get_gravity() const{
|
||||
real_t Area::get_gravity() const {
|
||||
|
||||
return gravity;
|
||||
}
|
||||
void Area::set_linear_damp(real_t p_linear_damp){
|
||||
void Area::set_linear_damp(real_t p_linear_damp) {
|
||||
|
||||
linear_damp=p_linear_damp;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_LINEAR_DAMP,p_linear_damp);
|
||||
linear_damp = p_linear_damp;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_LINEAR_DAMP, p_linear_damp);
|
||||
}
|
||||
real_t Area::get_linear_damp() const{
|
||||
real_t Area::get_linear_damp() const {
|
||||
|
||||
return linear_damp;
|
||||
}
|
||||
|
||||
void Area::set_angular_damp(real_t p_angular_damp){
|
||||
void Area::set_angular_damp(real_t p_angular_damp) {
|
||||
|
||||
angular_damp=p_angular_damp;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_ANGULAR_DAMP,p_angular_damp);
|
||||
angular_damp = p_angular_damp;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_ANGULAR_DAMP, p_angular_damp);
|
||||
}
|
||||
|
||||
real_t Area::get_angular_damp() const{
|
||||
real_t Area::get_angular_damp() const {
|
||||
|
||||
return angular_damp;
|
||||
}
|
||||
|
||||
void Area::set_priority(real_t p_priority){
|
||||
void Area::set_priority(real_t p_priority) {
|
||||
|
||||
priority=p_priority;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_PRIORITY,p_priority);
|
||||
priority = p_priority;
|
||||
PhysicsServer::get_singleton()->area_set_param(get_rid(), PhysicsServer::AREA_PARAM_PRIORITY, p_priority);
|
||||
}
|
||||
real_t Area::get_priority() const{
|
||||
real_t Area::get_priority() const {
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
void Area::_body_enter_tree(ObjectID p_id) {
|
||||
|
||||
Object *obj = ObjectDB::get_instance(p_id);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
ERR_FAIL_COND(!node);
|
||||
|
||||
Map<ObjectID,BodyState>::Element *E=body_map.find(p_id);
|
||||
Map<ObjectID, BodyState>::Element *E = body_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
ERR_FAIL_COND(E->get().in_tree);
|
||||
|
||||
E->get().in_tree=true;
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
E->get().in_tree = true;
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter, node);
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter_shape, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Area::_body_exit_tree(ObjectID p_id) {
|
||||
|
||||
|
||||
Object *obj = ObjectDB::get_instance(p_id);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
ERR_FAIL_COND(!node);
|
||||
Map<ObjectID,BodyState>::Element *E=body_map.find(p_id);
|
||||
Map<ObjectID, BodyState>::Element *E = body_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
ERR_FAIL_COND(!E->get().in_tree);
|
||||
E->get().in_tree=false;
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
E->get().in_tree = false;
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit, node);
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Area::_body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape) {
|
||||
void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
|
||||
|
||||
|
||||
bool body_in = p_status==PhysicsServer::AREA_BODY_ADDED;
|
||||
ObjectID objid=p_instance;
|
||||
bool body_in = p_status == PhysicsServer::AREA_BODY_ADDED;
|
||||
ObjectID objid = p_instance;
|
||||
|
||||
Object *obj = ObjectDB::get_instance(objid);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
|
||||
Map<ObjectID,BodyState>::Element *E=body_map.find(objid);
|
||||
Map<ObjectID, BodyState>::Element *E = body_map.find(objid);
|
||||
|
||||
ERR_FAIL_COND(!body_in && !E);
|
||||
|
||||
locked=true;
|
||||
locked = true;
|
||||
|
||||
if (body_in) {
|
||||
if (!E) {
|
||||
|
||||
E = body_map.insert(objid,BodyState());
|
||||
E->get().rc=0;
|
||||
E->get().in_tree=node && node->is_inside_tree();
|
||||
E = body_map.insert(objid, BodyState());
|
||||
E->get().rc = 0;
|
||||
E->get().in_tree = node && node->is_inside_tree();
|
||||
if (node) {
|
||||
node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree,make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree,make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid));
|
||||
if (E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter, node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
E->get().rc++;
|
||||
if (node)
|
||||
E->get().shapes.insert(ShapePair(p_body_shape,p_area_shape));
|
||||
|
||||
E->get().shapes.insert(ShapePair(p_body_shape, p_area_shape));
|
||||
|
||||
if (E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter_shape,objid,node,p_body_shape,p_area_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_enter_shape, objid, node, p_body_shape, p_area_shape);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -196,38 +184,32 @@ void Area::_body_inout(int p_status,const RID& p_body, int p_instance, int p_bod
|
|||
E->get().rc--;
|
||||
|
||||
if (node)
|
||||
E->get().shapes.erase(ShapePair(p_body_shape,p_area_shape));
|
||||
E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape));
|
||||
|
||||
bool eraseit=false;
|
||||
bool eraseit = false;
|
||||
|
||||
if (E->get().rc==0) {
|
||||
if (E->get().rc == 0) {
|
||||
|
||||
if (node) {
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree);
|
||||
if (E->get().in_tree)
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit, obj);
|
||||
}
|
||||
|
||||
eraseit=true;
|
||||
|
||||
eraseit = true;
|
||||
}
|
||||
if (node && E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_area_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape, objid, obj, p_body_shape, p_area_shape);
|
||||
}
|
||||
|
||||
if (eraseit)
|
||||
body_map.erase(E);
|
||||
|
||||
}
|
||||
|
||||
locked=false;
|
||||
|
||||
|
||||
locked = false;
|
||||
}
|
||||
|
||||
|
||||
void Area::_clear_monitoring() {
|
||||
|
||||
if (locked) {
|
||||
|
|
@ -236,11 +218,11 @@ void Area::_clear_monitoring() {
|
|||
ERR_FAIL_COND(locked);
|
||||
|
||||
{
|
||||
Map<ObjectID,BodyState> bmcopy = body_map;
|
||||
Map<ObjectID, BodyState> bmcopy = body_map;
|
||||
body_map.clear();
|
||||
//disconnect all monitored stuff
|
||||
|
||||
for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) {
|
||||
for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
|
||||
|
||||
Object *obj = ObjectDB::get_instance(E->key());
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
|
|
@ -248,26 +230,25 @@ void Area::_clear_monitoring() {
|
|||
if (!E->get().in_tree)
|
||||
continue;
|
||||
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit_shape, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
|
||||
}
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
|
||||
emit_signal(SceneStringNames::get_singleton()->body_exit, obj);
|
||||
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Map<ObjectID,AreaState> bmcopy = area_map;
|
||||
Map<ObjectID, AreaState> bmcopy = area_map;
|
||||
area_map.clear();
|
||||
//disconnect all monitored stuff
|
||||
|
||||
for (Map<ObjectID,AreaState>::Element *E=bmcopy.front();E;E=E->next()) {
|
||||
for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
|
||||
|
||||
Object *obj = ObjectDB::get_instance(E->key());
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
|
|
@ -275,22 +256,21 @@ void Area::_clear_monitoring() {
|
|||
if (!E->get().in_tree)
|
||||
continue;
|
||||
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape,E->key(),node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
|
||||
}
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit,obj);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit, obj);
|
||||
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void Area::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
_clear_monitoring();
|
||||
}
|
||||
}
|
||||
|
|
@ -302,41 +282,38 @@ void Area::set_enable_monitoring(bool p_enable) {
|
|||
}
|
||||
ERR_FAIL_COND(locked);
|
||||
|
||||
if (p_enable==monitoring)
|
||||
if (p_enable == monitoring)
|
||||
return;
|
||||
|
||||
monitoring=p_enable;
|
||||
monitoring = p_enable;
|
||||
|
||||
if (monitoring) {
|
||||
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_body_inout);
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_area_inout);
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
|
||||
} else {
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName());
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName());
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(), NULL, StringName());
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(), NULL, StringName());
|
||||
_clear_monitoring();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Area::_area_enter_tree(ObjectID p_id) {
|
||||
|
||||
Object *obj = ObjectDB::get_instance(p_id);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
ERR_FAIL_COND(!node);
|
||||
|
||||
Map<ObjectID,AreaState>::Element *E=area_map.find(p_id);
|
||||
Map<ObjectID, AreaState>::Element *E = area_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
ERR_FAIL_COND(E->get().in_tree);
|
||||
|
||||
E->get().in_tree=true;
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter,node);
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
E->get().in_tree = true;
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter, node);
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter_shape, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Area::_area_exit_tree(ObjectID p_id) {
|
||||
|
|
@ -344,56 +321,51 @@ void Area::_area_exit_tree(ObjectID p_id) {
|
|||
Object *obj = ObjectDB::get_instance(p_id);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
ERR_FAIL_COND(!node);
|
||||
Map<ObjectID,AreaState>::Element *E=area_map.find(p_id);
|
||||
Map<ObjectID, AreaState>::Element *E = area_map.find(p_id);
|
||||
ERR_FAIL_COND(!E);
|
||||
ERR_FAIL_COND(!E->get().in_tree);
|
||||
E->get().in_tree=false;
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit,node);
|
||||
for(int i=0;i<E->get().shapes.size();i++) {
|
||||
E->get().in_tree = false;
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit, node);
|
||||
for (int i = 0; i < E->get().shapes.size(); i++) {
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Area::_area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape) {
|
||||
void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
|
||||
|
||||
|
||||
bool area_in = p_status==PhysicsServer::AREA_BODY_ADDED;
|
||||
ObjectID objid=p_instance;
|
||||
bool area_in = p_status == PhysicsServer::AREA_BODY_ADDED;
|
||||
ObjectID objid = p_instance;
|
||||
|
||||
Object *obj = ObjectDB::get_instance(objid);
|
||||
Node *node = obj ? obj->cast_to<Node>() : NULL;
|
||||
|
||||
Map<ObjectID,AreaState>::Element *E=area_map.find(objid);
|
||||
Map<ObjectID, AreaState>::Element *E = area_map.find(objid);
|
||||
|
||||
ERR_FAIL_COND(!area_in && !E);
|
||||
|
||||
locked=true;
|
||||
locked = true;
|
||||
|
||||
if (area_in) {
|
||||
if (!E) {
|
||||
|
||||
E = area_map.insert(objid,AreaState());
|
||||
E->get().rc=0;
|
||||
E->get().in_tree=node && node->is_inside_tree();
|
||||
E = area_map.insert(objid, AreaState());
|
||||
E->get().rc = 0;
|
||||
E->get().in_tree = node && node->is_inside_tree();
|
||||
if (node) {
|
||||
node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree,make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree,make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree, make_binds(objid));
|
||||
node->connect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree, make_binds(objid));
|
||||
if (E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter,node);
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter, node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
E->get().rc++;
|
||||
if (node)
|
||||
E->get().shapes.insert(AreaShapePair(p_area_shape,p_self_shape));
|
||||
|
||||
E->get().shapes.insert(AreaShapePair(p_area_shape, p_self_shape));
|
||||
|
||||
if (!node || E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter_shape,objid,node,p_area_shape,p_self_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_enter_shape, objid, node, p_area_shape, p_self_shape);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -401,36 +373,31 @@ void Area::_area_inout(int p_status,const RID& p_area, int p_instance, int p_are
|
|||
E->get().rc--;
|
||||
|
||||
if (node)
|
||||
E->get().shapes.erase(AreaShapePair(p_area_shape,p_self_shape));
|
||||
E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
|
||||
|
||||
bool eraseit=false;
|
||||
bool eraseit = false;
|
||||
|
||||
if (E->get().rc==0) {
|
||||
if (E->get().rc == 0) {
|
||||
|
||||
if (node) {
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree);
|
||||
node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree);
|
||||
if (E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit,obj);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit, obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eraseit=true;
|
||||
|
||||
eraseit = true;
|
||||
}
|
||||
if (!node || E->get().in_tree) {
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape,objid,obj,p_area_shape,p_self_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->area_exit_shape, objid, obj, p_area_shape, p_self_shape);
|
||||
}
|
||||
|
||||
if (eraseit)
|
||||
area_map.erase(E);
|
||||
|
||||
}
|
||||
|
||||
locked=false;
|
||||
|
||||
|
||||
locked = false;
|
||||
}
|
||||
|
||||
bool Area::is_monitoring_enabled() const {
|
||||
|
|
@ -438,21 +405,19 @@ bool Area::is_monitoring_enabled() const {
|
|||
return monitoring;
|
||||
}
|
||||
|
||||
|
||||
Array Area::get_overlapping_bodies() const {
|
||||
|
||||
ERR_FAIL_COND_V(!monitoring,Array());
|
||||
ERR_FAIL_COND_V(!monitoring, Array());
|
||||
Array ret;
|
||||
ret.resize(body_map.size());
|
||||
int idx=0;
|
||||
for (const Map<ObjectID,BodyState>::Element *E=body_map.front();E;E=E->next()) {
|
||||
int idx = 0;
|
||||
for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
|
||||
Object *obj = ObjectDB::get_instance(E->key());
|
||||
if (!obj) {
|
||||
ret.resize( ret.size() -1 ); //ops
|
||||
ret.resize(ret.size() - 1); //ops
|
||||
} else {
|
||||
ret[idx++]=obj;
|
||||
ret[idx++] = obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -465,12 +430,12 @@ void Area::set_monitorable(bool p_enable) {
|
|||
}
|
||||
ERR_FAIL_COND(locked);
|
||||
|
||||
if (p_enable==monitorable)
|
||||
if (p_enable == monitorable)
|
||||
return;
|
||||
|
||||
monitorable=p_enable;
|
||||
monitorable = p_enable;
|
||||
|
||||
PhysicsServer::get_singleton()->area_set_monitorable(get_rid(),monitorable);
|
||||
PhysicsServer::get_singleton()->area_set_monitorable(get_rid(), monitorable);
|
||||
}
|
||||
|
||||
bool Area::is_monitorable() const {
|
||||
|
|
@ -478,51 +443,45 @@ bool Area::is_monitorable() const {
|
|||
return monitorable;
|
||||
}
|
||||
|
||||
|
||||
Array Area::get_overlapping_areas() const {
|
||||
|
||||
ERR_FAIL_COND_V(!monitoring,Array());
|
||||
ERR_FAIL_COND_V(!monitoring, Array());
|
||||
Array ret;
|
||||
ret.resize(area_map.size());
|
||||
int idx=0;
|
||||
for (const Map<ObjectID,AreaState>::Element *E=area_map.front();E;E=E->next()) {
|
||||
int idx = 0;
|
||||
for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
|
||||
Object *obj = ObjectDB::get_instance(E->key());
|
||||
if (!obj) {
|
||||
ret.resize( ret.size() -1 ); //ops
|
||||
ret.resize(ret.size() - 1); //ops
|
||||
} else {
|
||||
ret[idx++]=obj;
|
||||
ret[idx++] = obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Area::overlaps_area(Node* p_area) const {
|
||||
bool Area::overlaps_area(Node *p_area) const {
|
||||
|
||||
ERR_FAIL_NULL_V(p_area,false);
|
||||
const Map<ObjectID,AreaState>::Element *E=area_map.find(p_area->get_instance_ID());
|
||||
ERR_FAIL_NULL_V(p_area, false);
|
||||
const Map<ObjectID, AreaState>::Element *E = area_map.find(p_area->get_instance_ID());
|
||||
if (!E)
|
||||
return false;
|
||||
return E->get().in_tree;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Area::overlaps_body(Node* p_body) const{
|
||||
bool Area::overlaps_body(Node *p_body) const {
|
||||
|
||||
ERR_FAIL_NULL_V(p_body,false);
|
||||
const Map<ObjectID,BodyState>::Element *E=body_map.find(p_body->get_instance_ID());
|
||||
ERR_FAIL_NULL_V(p_body, false);
|
||||
const Map<ObjectID, BodyState>::Element *E = body_map.find(p_body->get_instance_ID());
|
||||
if (!E)
|
||||
return false;
|
||||
return E->get().in_tree;
|
||||
|
||||
}
|
||||
void Area::set_collision_mask(uint32_t p_mask) {
|
||||
|
||||
collision_mask=p_mask;
|
||||
PhysicsServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask);
|
||||
collision_mask = p_mask;
|
||||
PhysicsServer::get_singleton()->area_set_collision_mask(get_rid(), p_mask);
|
||||
}
|
||||
|
||||
uint32_t Area::get_collision_mask() const {
|
||||
|
|
@ -531,8 +490,8 @@ uint32_t Area::get_collision_mask() const {
|
|||
}
|
||||
void Area::set_layer_mask(uint32_t p_mask) {
|
||||
|
||||
layer_mask=p_mask;
|
||||
PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask);
|
||||
layer_mask = p_mask;
|
||||
PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask);
|
||||
}
|
||||
|
||||
uint32_t Area::get_layer_mask() const {
|
||||
|
|
@ -544,143 +503,134 @@ void Area::set_collision_mask_bit(int p_bit, bool p_value) {
|
|||
|
||||
uint32_t mask = get_collision_mask();
|
||||
if (p_value)
|
||||
mask|=1<<p_bit;
|
||||
mask |= 1 << p_bit;
|
||||
else
|
||||
mask&=~(1<<p_bit);
|
||||
mask &= ~(1 << p_bit);
|
||||
set_collision_mask(mask);
|
||||
|
||||
}
|
||||
|
||||
bool Area::get_collision_mask_bit(int p_bit) const{
|
||||
bool Area::get_collision_mask_bit(int p_bit) const {
|
||||
|
||||
return get_collision_mask()&(1<<p_bit);
|
||||
return get_collision_mask() & (1 << p_bit);
|
||||
}
|
||||
|
||||
|
||||
void Area::set_layer_mask_bit(int p_bit, bool p_value) {
|
||||
|
||||
uint32_t mask = get_layer_mask();
|
||||
if (p_value)
|
||||
mask|=1<<p_bit;
|
||||
mask |= 1 << p_bit;
|
||||
else
|
||||
mask&=~(1<<p_bit);
|
||||
mask &= ~(1 << p_bit);
|
||||
set_layer_mask(mask);
|
||||
|
||||
}
|
||||
|
||||
bool Area::get_layer_mask_bit(int p_bit) const{
|
||||
bool Area::get_layer_mask_bit(int p_bit) const {
|
||||
|
||||
return get_layer_mask()&(1<<p_bit);
|
||||
return get_layer_mask() & (1 << p_bit);
|
||||
}
|
||||
|
||||
|
||||
void Area::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_body_enter_tree","id"),&Area::_body_enter_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_body_exit_tree","id"),&Area::_body_exit_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_body_enter_tree", "id"), &Area::_body_enter_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_body_exit_tree", "id"), &Area::_body_exit_tree);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_area_enter_tree","id"),&Area::_area_enter_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_area_exit_tree","id"),&Area::_area_exit_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_area_enter_tree", "id"), &Area::_area_enter_tree);
|
||||
ObjectTypeDB::bind_method(_MD("_area_exit_tree", "id"), &Area::_area_exit_tree);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_space_override_mode","enable"),&Area::set_space_override_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_space_override_mode"),&Area::get_space_override_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_space_override_mode", "enable"), &Area::set_space_override_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_space_override_mode"), &Area::get_space_override_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_is_point","enable"),&Area::set_gravity_is_point);
|
||||
ObjectTypeDB::bind_method(_MD("is_gravity_a_point"),&Area::is_gravity_a_point);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_is_point", "enable"), &Area::set_gravity_is_point);
|
||||
ObjectTypeDB::bind_method(_MD("is_gravity_a_point"), &Area::is_gravity_a_point);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale","distance_scale"),&Area::set_gravity_distance_scale);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"),&Area::get_gravity_distance_scale);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale", "distance_scale"), &Area::set_gravity_distance_scale);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"), &Area::get_gravity_distance_scale);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_vector","vector"),&Area::set_gravity_vector);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_vector"),&Area::get_gravity_vector);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_vector", "vector"), &Area::set_gravity_vector);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_vector"), &Area::get_gravity_vector);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity","gravity"),&Area::set_gravity);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity"),&Area::get_gravity);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity", "gravity"), &Area::set_gravity);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity"), &Area::get_gravity);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_angular_damp","angular_damp"),&Area::set_angular_damp);
|
||||
ObjectTypeDB::bind_method(_MD("get_angular_damp"),&Area::get_angular_damp);
|
||||
ObjectTypeDB::bind_method(_MD("set_angular_damp", "angular_damp"), &Area::set_angular_damp);
|
||||
ObjectTypeDB::bind_method(_MD("get_angular_damp"), &Area::get_angular_damp);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_linear_damp","linear_damp"),&Area::set_linear_damp);
|
||||
ObjectTypeDB::bind_method(_MD("get_linear_damp"),&Area::get_linear_damp);
|
||||
ObjectTypeDB::bind_method(_MD("set_linear_damp", "linear_damp"), &Area::set_linear_damp);
|
||||
ObjectTypeDB::bind_method(_MD("get_linear_damp"), &Area::get_linear_damp);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
|
||||
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
|
||||
ObjectTypeDB::bind_method(_MD("set_priority", "priority"), &Area::set_priority);
|
||||
ObjectTypeDB::bind_method(_MD("get_priority"), &Area::get_priority);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area::set_collision_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area::get_collision_mask);
|
||||
ObjectTypeDB::bind_method(_MD("set_collision_mask", "collision_mask"), &Area::set_collision_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_mask"), &Area::get_collision_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area::get_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask", "layer_mask"), &Area::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"), &Area::get_layer_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&Area::set_collision_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&Area::get_collision_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("set_collision_mask_bit", "bit", "value"), &Area::set_collision_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_mask_bit", "bit"), &Area::get_collision_mask_bit);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&Area::set_layer_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&Area::get_layer_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask_bit", "bit", "value"), &Area::set_layer_mask_bit);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask_bit", "bit"), &Area::get_layer_mask_bit);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area::set_monitorable);
|
||||
ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area::is_monitorable);
|
||||
ObjectTypeDB::bind_method(_MD("set_monitorable", "enable"), &Area::set_monitorable);
|
||||
ObjectTypeDB::bind_method(_MD("is_monitorable"), &Area::is_monitorable);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enable_monitoring", "enable"), &Area::set_enable_monitoring);
|
||||
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"), &Area::is_monitoring_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring);
|
||||
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"), &Area::get_overlapping_bodies);
|
||||
ObjectTypeDB::bind_method(_MD("get_overlapping_areas"), &Area::get_overlapping_areas);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"),&Area::get_overlapping_bodies);
|
||||
ObjectTypeDB::bind_method(_MD("get_overlapping_areas"),&Area::get_overlapping_areas);
|
||||
ObjectTypeDB::bind_method(_MD("overlaps_body", "body"), &Area::overlaps_body);
|
||||
ObjectTypeDB::bind_method(_MD("overlaps_area", "area"), &Area::overlaps_area);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("overlaps_body","body"),&Area::overlaps_body);
|
||||
ObjectTypeDB::bind_method(_MD("overlaps_area","area"),&Area::overlaps_area);
|
||||
ObjectTypeDB::bind_method(_MD("_body_inout"), &Area::_body_inout);
|
||||
ObjectTypeDB::bind_method(_MD("_area_inout"), &Area::_area_inout);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_body_inout"),&Area::_body_inout);
|
||||
ObjectTypeDB::bind_method(_MD("_area_inout"),&Area::_area_inout);
|
||||
ADD_SIGNAL(MethodInfo("body_enter_shape", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
|
||||
ADD_SIGNAL(MethodInfo("body_exit_shape", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
|
||||
ADD_SIGNAL(MethodInfo("body_enter", PropertyInfo(Variant::OBJECT, "body")));
|
||||
ADD_SIGNAL(MethodInfo("body_exit", PropertyInfo(Variant::OBJECT, "body")));
|
||||
|
||||
ADD_SIGNAL(MethodInfo("area_enter_shape", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
|
||||
ADD_SIGNAL(MethodInfo("area_exit_shape", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
|
||||
ADD_SIGNAL(MethodInfo("area_enter", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area")));
|
||||
ADD_SIGNAL(MethodInfo("area_exit", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area")));
|
||||
|
||||
ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape")));
|
||||
ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape")));
|
||||
ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body")));
|
||||
ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body")));
|
||||
|
||||
ADD_SIGNAL( MethodInfo("area_enter_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"self_shape")));
|
||||
ADD_SIGNAL( MethodInfo("area_exit_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"self_shape")));
|
||||
ADD_SIGNAL( MethodInfo("area_enter",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area")));
|
||||
ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area")));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Combine-Replace,Replace,Replace-Combine"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_angular_damp"),_SCS("get_angular_damp"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), _SCS("set_space_override_mode"), _SCS("get_space_override_mode"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), _SCS("set_gravity_is_point"), _SCS("is_gravity_a_point"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001"), _SCS("set_gravity_distance_scale"), _SCS("get_gravity_distance_scale"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), _SCS("set_gravity_vector"), _SCS("get_gravity_vector"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), _SCS("set_gravity"), _SCS("get_gravity"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), _SCS("set_linear_damp"), _SCS("get_linear_damp"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), _SCS("set_angular_damp"), _SCS("get_angular_damp"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), _SCS("set_priority"), _SCS("get_priority"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), _SCS("set_enable_monitoring"), _SCS("is_monitoring_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), _SCS("set_monitorable"), _SCS("is_monitorable"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision/layers", PROPERTY_HINT_ALL_FLAGS), _SCS("set_layer_mask"), _SCS("get_layer_mask"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision/mask", PROPERTY_HINT_ALL_FLAGS), _SCS("set_collision_mask"), _SCS("get_collision_mask"));
|
||||
}
|
||||
|
||||
Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),true) {
|
||||
Area::Area()
|
||||
: CollisionObject(PhysicsServer::get_singleton()->area_create(), true) {
|
||||
|
||||
space_override=SPACE_OVERRIDE_DISABLED;
|
||||
space_override = SPACE_OVERRIDE_DISABLED;
|
||||
set_gravity(9.8);
|
||||
locked=false;
|
||||
set_gravity_vector(Vector3(0,-1,0));
|
||||
gravity_is_point=false;
|
||||
gravity_distance_scale=0;
|
||||
linear_damp=0.1;
|
||||
angular_damp=1;
|
||||
priority=0;
|
||||
monitoring=false;
|
||||
collision_mask=1;
|
||||
layer_mask=1;
|
||||
locked = false;
|
||||
set_gravity_vector(Vector3(0, -1, 0));
|
||||
gravity_is_point = false;
|
||||
gravity_distance_scale = 0;
|
||||
linear_damp = 0.1;
|
||||
angular_damp = 1;
|
||||
priority = 0;
|
||||
monitoring = false;
|
||||
collision_mask = 1;
|
||||
layer_mask = 1;
|
||||
set_ray_pickable(false);
|
||||
set_enable_monitoring(true);
|
||||
set_monitorable(true);
|
||||
|
||||
}
|
||||
|
||||
Area::~Area() {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@
|
|||
|
||||
class Area : public CollisionObject {
|
||||
|
||||
OBJ_TYPE( Area, CollisionObject );
|
||||
public:
|
||||
OBJ_TYPE(Area, CollisionObject);
|
||||
|
||||
public:
|
||||
enum SpaceOverride {
|
||||
SPACE_OVERRIDE_DISABLED,
|
||||
SPACE_OVERRIDE_COMBINE,
|
||||
|
|
@ -44,9 +44,8 @@ public:
|
|||
SPACE_OVERRIDE_REPLACE,
|
||||
SPACE_OVERRIDE_REPLACE_COMBINE
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
|
||||
SpaceOverride space_override;
|
||||
Vector3 gravity_vec;
|
||||
real_t gravity;
|
||||
|
|
@ -61,8 +60,7 @@ private:
|
|||
bool monitorable;
|
||||
bool locked;
|
||||
|
||||
|
||||
void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape);
|
||||
void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape);
|
||||
|
||||
void _body_enter_tree(ObjectID p_id);
|
||||
void _body_exit_tree(ObjectID p_id);
|
||||
|
|
@ -71,15 +69,18 @@ private:
|
|||
|
||||
int body_shape;
|
||||
int area_shape;
|
||||
bool operator<(const ShapePair& p_sp) const {
|
||||
if (body_shape==p_sp.body_shape)
|
||||
bool operator<(const ShapePair &p_sp) const {
|
||||
if (body_shape == p_sp.body_shape)
|
||||
return area_shape < p_sp.area_shape;
|
||||
else
|
||||
return body_shape < p_sp.body_shape;
|
||||
}
|
||||
|
||||
ShapePair() {}
|
||||
ShapePair(int p_bs, int p_as) { body_shape=p_bs; area_shape=p_as; }
|
||||
ShapePair(int p_bs, int p_as) {
|
||||
body_shape = p_bs;
|
||||
area_shape = p_as;
|
||||
}
|
||||
};
|
||||
|
||||
struct BodyState {
|
||||
|
|
@ -89,10 +90,9 @@ private:
|
|||
VSet<ShapePair> shapes;
|
||||
};
|
||||
|
||||
Map<ObjectID,BodyState> body_map;
|
||||
Map<ObjectID, BodyState> body_map;
|
||||
|
||||
|
||||
void _area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape);
|
||||
void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape);
|
||||
|
||||
void _area_enter_tree(ObjectID p_id);
|
||||
void _area_exit_tree(ObjectID p_id);
|
||||
|
|
@ -101,15 +101,18 @@ private:
|
|||
|
||||
int area_shape;
|
||||
int self_shape;
|
||||
bool operator<(const AreaShapePair& p_sp) const {
|
||||
if (area_shape==p_sp.area_shape)
|
||||
bool operator<(const AreaShapePair &p_sp) const {
|
||||
if (area_shape == p_sp.area_shape)
|
||||
return self_shape < p_sp.self_shape;
|
||||
else
|
||||
return area_shape < p_sp.area_shape;
|
||||
}
|
||||
|
||||
AreaShapePair() {}
|
||||
AreaShapePair(int p_bs, int p_as) { area_shape=p_bs; self_shape=p_as; }
|
||||
AreaShapePair(int p_bs, int p_as) {
|
||||
area_shape = p_bs;
|
||||
self_shape = p_as;
|
||||
}
|
||||
};
|
||||
|
||||
struct AreaState {
|
||||
|
|
@ -119,16 +122,14 @@ private:
|
|||
VSet<AreaShapePair> shapes;
|
||||
};
|
||||
|
||||
Map<ObjectID,AreaState> area_map;
|
||||
Map<ObjectID, AreaState> area_map;
|
||||
void _clear_monitoring();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_space_override_mode(SpaceOverride p_mode);
|
||||
SpaceOverride get_space_override_mode() const;
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ public:
|
|||
void set_gravity_distance_scale(real_t p_scale);
|
||||
real_t get_gravity_distance_scale() const;
|
||||
|
||||
void set_gravity_vector(const Vector3& p_vec);
|
||||
void set_gravity_vector(const Vector3 &p_vec);
|
||||
Vector3 get_gravity_vector() const;
|
||||
|
||||
void set_gravity(real_t p_gravity);
|
||||
|
|
@ -174,9 +175,8 @@ public:
|
|||
Array get_overlapping_bodies() const;
|
||||
Array get_overlapping_areas() const; //function for script
|
||||
|
||||
bool overlaps_area(Node* p_area) const;
|
||||
bool overlaps_body(Node* p_body) const;
|
||||
|
||||
bool overlaps_area(Node *p_area) const;
|
||||
bool overlaps_body(Node *p_body) const;
|
||||
|
||||
Area();
|
||||
~Area();
|
||||
|
|
|
|||
|
|
@ -29,26 +29,24 @@
|
|||
#include "baked_light_instance.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
|
||||
RID BakedLightInstance::get_baked_light_instance() const {
|
||||
|
||||
if (baked_light.is_null())
|
||||
return RID();
|
||||
else
|
||||
return get_instance();
|
||||
|
||||
}
|
||||
|
||||
void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) {
|
||||
void BakedLightInstance::set_baked_light(const Ref<BakedLight> &p_baked_light) {
|
||||
|
||||
baked_light=p_baked_light;
|
||||
baked_light = p_baked_light;
|
||||
|
||||
RID base_rid;
|
||||
|
||||
if (baked_light.is_valid())
|
||||
base_rid=baked_light->get_rid();
|
||||
base_rid = baked_light->get_rid();
|
||||
else
|
||||
base_rid=RID();
|
||||
base_rid = RID();
|
||||
|
||||
set_base(base_rid);
|
||||
|
||||
|
|
@ -56,29 +54,28 @@ void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) {
|
|||
|
||||
emit_signal(SceneStringNames::get_singleton()->baked_light_changed);
|
||||
|
||||
// for (List<Node*>::Element *E=baked_geometry.front();E;E=E->next()) {
|
||||
// VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID());
|
||||
// }
|
||||
// for (List<Node*>::Element *E=baked_geometry.front();E;E=E->next()) {
|
||||
// VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID());
|
||||
// }
|
||||
}
|
||||
|
||||
update_configuration_warning();
|
||||
}
|
||||
|
||||
Ref<BakedLight> BakedLightInstance::get_baked_light() const{
|
||||
Ref<BakedLight> BakedLightInstance::get_baked_light() const {
|
||||
|
||||
return baked_light;
|
||||
}
|
||||
|
||||
AABB BakedLightInstance::get_aabb() const {
|
||||
|
||||
return AABB(Vector3(0,0,0),Vector3(1,1,1));
|
||||
return AABB(Vector3(0, 0, 0), Vector3(1, 1, 1));
|
||||
}
|
||||
DVector<Face3> BakedLightInstance::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
return DVector<Face3>();
|
||||
}
|
||||
|
||||
|
||||
String BakedLightInstance::get_configuration_warning() const {
|
||||
if (get_baked_light().is_null()) {
|
||||
return TTR("BakedLightInstance does not contain a BakedLight resource.");
|
||||
|
|
@ -86,42 +83,37 @@ String BakedLightInstance::get_configuration_warning() const {
|
|||
return String();
|
||||
}
|
||||
|
||||
|
||||
void BakedLightInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_baked_light","baked_light"),&BakedLightInstance::set_baked_light);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light"),&BakedLightInstance::get_baked_light);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light_instance"),&BakedLightInstance::get_baked_light_instance);
|
||||
ObjectTypeDB::bind_method(_MD("set_baked_light", "baked_light"), &BakedLightInstance::set_baked_light);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light"), &BakedLightInstance::get_baked_light);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light_instance"), &BakedLightInstance::get_baked_light_instance);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"baked_light",PROPERTY_HINT_RESOURCE_TYPE,"BakedLight"),_SCS("set_baked_light"),_SCS("get_baked_light"));
|
||||
ADD_SIGNAL( MethodInfo("baked_light_changed"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "baked_light", PROPERTY_HINT_RESOURCE_TYPE, "BakedLight"), _SCS("set_baked_light"), _SCS("get_baked_light"));
|
||||
ADD_SIGNAL(MethodInfo("baked_light_changed"));
|
||||
}
|
||||
|
||||
BakedLightInstance::BakedLightInstance() {
|
||||
|
||||
|
||||
}
|
||||
/////////////////////////
|
||||
|
||||
|
||||
void BakedLightSampler::set_param(Param p_param,float p_value) {
|
||||
ERR_FAIL_INDEX(p_param,PARAM_MAX);
|
||||
params[p_param]=p_value;
|
||||
VS::get_singleton()->baked_light_sampler_set_param(base,VS::BakedLightSamplerParam(p_param),p_value);
|
||||
void BakedLightSampler::set_param(Param p_param, float p_value) {
|
||||
ERR_FAIL_INDEX(p_param, PARAM_MAX);
|
||||
params[p_param] = p_value;
|
||||
VS::get_singleton()->baked_light_sampler_set_param(base, VS::BakedLightSamplerParam(p_param), p_value);
|
||||
}
|
||||
|
||||
float BakedLightSampler::get_param(Param p_param) const{
|
||||
float BakedLightSampler::get_param(Param p_param) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
|
||||
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
|
||||
return params[p_param];
|
||||
|
||||
}
|
||||
|
||||
void BakedLightSampler::set_resolution(int p_resolution){
|
||||
void BakedLightSampler::set_resolution(int p_resolution) {
|
||||
|
||||
ERR_FAIL_COND(p_resolution<4 || p_resolution>32);
|
||||
resolution=p_resolution;
|
||||
VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
|
||||
ERR_FAIL_COND(p_resolution < 4 || p_resolution > 32);
|
||||
resolution = p_resolution;
|
||||
VS::get_singleton()->baked_light_sampler_set_resolution(base, resolution);
|
||||
}
|
||||
int BakedLightSampler::get_resolution() const {
|
||||
|
||||
|
|
@ -131,7 +123,7 @@ int BakedLightSampler::get_resolution() const {
|
|||
AABB BakedLightSampler::get_aabb() const {
|
||||
|
||||
float r = get_param(PARAM_RADIUS);
|
||||
return AABB( Vector3(-r,-r,-r),Vector3(r*2,r*2,r*2));
|
||||
return AABB(Vector3(-r, -r, -r), Vector3(r * 2, r * 2, r * 2));
|
||||
}
|
||||
DVector<Face3> BakedLightSampler::get_faces(uint32_t p_usage_flags) const {
|
||||
return DVector<Face3>();
|
||||
|
|
@ -139,26 +131,24 @@ DVector<Face3> BakedLightSampler::get_faces(uint32_t p_usage_flags) const {
|
|||
|
||||
void BakedLightSampler::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_param","param","value"),&BakedLightSampler::set_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_param","param"),&BakedLightSampler::get_param);
|
||||
ObjectTypeDB::bind_method(_MD("set_param", "param", "value"), &BakedLightSampler::set_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_param", "param"), &BakedLightSampler::get_param);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_resolution","resolution"),&BakedLightSampler::set_resolution);
|
||||
ObjectTypeDB::bind_method(_MD("get_resolution"),&BakedLightSampler::get_resolution);
|
||||
ObjectTypeDB::bind_method(_MD("set_resolution", "resolution"), &BakedLightSampler::set_resolution);
|
||||
ObjectTypeDB::bind_method(_MD("get_resolution"), &BakedLightSampler::get_resolution);
|
||||
|
||||
BIND_CONSTANT(PARAM_RADIUS);
|
||||
BIND_CONSTANT(PARAM_STRENGTH);
|
||||
BIND_CONSTANT(PARAM_ATTENUATION);
|
||||
BIND_CONSTANT(PARAM_DETAIL_RATIO);
|
||||
BIND_CONSTANT(PARAM_MAX);
|
||||
|
||||
BIND_CONSTANT( PARAM_RADIUS );
|
||||
BIND_CONSTANT( PARAM_STRENGTH );
|
||||
BIND_CONSTANT( PARAM_ATTENUATION );
|
||||
BIND_CONSTANT( PARAM_DETAIL_RATIO );
|
||||
BIND_CONSTANT( PARAM_MAX );
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/radius",PROPERTY_HINT_RANGE,"0.01,1024,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_RADIUS);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/strength",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_STRENGTH);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/attenuation",PROPERTY_HINT_EXP_EASING),_SCS("set_param"),_SCS("get_param"),PARAM_ATTENUATION);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_DETAIL_RATIO);
|
||||
// ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0,20,1"),_SCS("set_param"),_SCS("get_param"),PARAM_DETAIL_RATIO);
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"params/resolution",PROPERTY_HINT_RANGE,"4,32,1"),_SCS("set_resolution"),_SCS("get_resolution"));
|
||||
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_RADIUS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/strength", PROPERTY_HINT_RANGE, "0.01,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_STRENGTH);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/detail_ratio", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_DETAIL_RATIO);
|
||||
// ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0,20,1"),_SCS("set_param"),_SCS("get_param"),PARAM_DETAIL_RATIO);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "params/resolution", PROPERTY_HINT_RANGE, "4,32,1"), _SCS("set_resolution"), _SCS("get_resolution"));
|
||||
}
|
||||
|
||||
BakedLightSampler::BakedLightSampler() {
|
||||
|
|
@ -166,16 +156,14 @@ BakedLightSampler::BakedLightSampler() {
|
|||
base = VS::get_singleton()->baked_light_sampler_create();
|
||||
set_base(base);
|
||||
|
||||
params[PARAM_RADIUS]=1.0;
|
||||
params[PARAM_STRENGTH]=1.0;
|
||||
params[PARAM_ATTENUATION]=1.0;
|
||||
params[PARAM_DETAIL_RATIO]=0.1;
|
||||
resolution=16;
|
||||
|
||||
|
||||
params[PARAM_RADIUS] = 1.0;
|
||||
params[PARAM_STRENGTH] = 1.0;
|
||||
params[PARAM_ATTENUATION] = 1.0;
|
||||
params[PARAM_DETAIL_RATIO] = 0.1;
|
||||
resolution = 16;
|
||||
}
|
||||
|
||||
BakedLightSampler::~BakedLightSampler(){
|
||||
BakedLightSampler::~BakedLightSampler() {
|
||||
|
||||
VS::get_singleton()->free(base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,22 +34,18 @@
|
|||
|
||||
class BakedLightBaker;
|
||||
|
||||
|
||||
class BakedLightInstance : public VisualInstance {
|
||||
OBJ_TYPE(BakedLightInstance,VisualInstance);
|
||||
OBJ_TYPE(BakedLightInstance, VisualInstance);
|
||||
|
||||
Ref<BakedLight> baked_light;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
RID get_baked_light_instance() const;
|
||||
|
||||
void set_baked_light(const Ref<BakedLight>& baked_light);
|
||||
void set_baked_light(const Ref<BakedLight> &baked_light);
|
||||
Ref<BakedLight> get_baked_light() const;
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
|
|
@ -60,36 +56,29 @@ public:
|
|||
BakedLightInstance();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class BakedLightSampler : public VisualInstance {
|
||||
OBJ_TYPE(BakedLightSampler,VisualInstance);
|
||||
|
||||
OBJ_TYPE(BakedLightSampler, VisualInstance);
|
||||
|
||||
public:
|
||||
|
||||
enum Param {
|
||||
PARAM_RADIUS=VS::BAKED_LIGHT_SAMPLER_RADIUS,
|
||||
PARAM_STRENGTH=VS::BAKED_LIGHT_SAMPLER_STRENGTH,
|
||||
PARAM_ATTENUATION=VS::BAKED_LIGHT_SAMPLER_ATTENUATION,
|
||||
PARAM_DETAIL_RATIO=VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
|
||||
PARAM_MAX=VS::BAKED_LIGHT_SAMPLER_MAX
|
||||
PARAM_RADIUS = VS::BAKED_LIGHT_SAMPLER_RADIUS,
|
||||
PARAM_STRENGTH = VS::BAKED_LIGHT_SAMPLER_STRENGTH,
|
||||
PARAM_ATTENUATION = VS::BAKED_LIGHT_SAMPLER_ATTENUATION,
|
||||
PARAM_DETAIL_RATIO = VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
|
||||
PARAM_MAX = VS::BAKED_LIGHT_SAMPLER_MAX
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
RID base;
|
||||
float params[PARAM_MAX];
|
||||
int resolution;
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
void set_param(Param p_param,float p_value);
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
void set_resolution(int p_resolution);
|
||||
|
|
@ -99,7 +88,6 @@ public:
|
|||
~BakedLightSampler();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( BakedLightSampler::Param );
|
||||
|
||||
VARIANT_ENUM_CAST(BakedLightSampler::Param);
|
||||
|
||||
#endif // BAKED_LIGHT_H
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "body_shape.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "scene/resources/sphere_shape.h"
|
||||
#include "scene/resources/ray_shape.h"
|
||||
#include "scene/resources/box_shape.h"
|
||||
#include "scene/resources/capsule_shape.h"
|
||||
#include "scene/resources/convex_polygon_shape.h"
|
||||
#include "scene/resources/concave_polygon_shape.h"
|
||||
#include "scene/resources/convex_polygon_shape.h"
|
||||
#include "scene/resources/plane_shape.h"
|
||||
#include "scene/resources/ray_shape.h"
|
||||
#include "scene/resources/sphere_shape.h"
|
||||
#include "servers/visual_server.h"
|
||||
//TODO: Implement CylinderShape and HeightMapShape?
|
||||
#include "mesh_instance.h"
|
||||
#include "physics_body.h"
|
||||
|
|
@ -48,7 +48,6 @@ void CollisionShape::_update_body() {
|
|||
return;
|
||||
if (get_parent() && get_parent()->cast_to<CollisionObject>())
|
||||
get_parent()->cast_to<CollisionObject>()->_update_shapes_from_children();
|
||||
|
||||
}
|
||||
|
||||
void CollisionShape::make_convex_from_brothers() {
|
||||
|
|
@ -57,12 +56,12 @@ void CollisionShape::make_convex_from_brothers() {
|
|||
if (!p)
|
||||
return;
|
||||
|
||||
for(int i=0;i<p->get_child_count();i++) {
|
||||
for (int i = 0; i < p->get_child_count(); i++) {
|
||||
|
||||
Node *n = p->get_child(i);
|
||||
if (n->cast_to<MeshInstance>()) {
|
||||
|
||||
MeshInstance *mi=n->cast_to<MeshInstance>();
|
||||
MeshInstance *mi = n->cast_to<MeshInstance>();
|
||||
Ref<Mesh> m = mi->get_mesh();
|
||||
if (m.is_valid()) {
|
||||
|
||||
|
|
@ -71,7 +70,6 @@ void CollisionShape::make_convex_from_brothers() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
|
|
@ -302,32 +300,32 @@ void CollisionShape::_update_indicator() {
|
|||
}
|
||||
|
||||
*/
|
||||
void CollisionShape::_add_to_collision_object(Object* p_cshape) {
|
||||
void CollisionShape::_add_to_collision_object(Object *p_cshape) {
|
||||
|
||||
if (unparenting)
|
||||
return;
|
||||
|
||||
CollisionObject *co=p_cshape->cast_to<CollisionObject>();
|
||||
CollisionObject *co = p_cshape->cast_to<CollisionObject>();
|
||||
ERR_FAIL_COND(!co);
|
||||
|
||||
if (shape.is_valid()) {
|
||||
|
||||
update_shape_index=co->get_shape_count();
|
||||
co->add_shape(shape,get_transform());
|
||||
update_shape_index = co->get_shape_count();
|
||||
co->add_shape(shape, get_transform());
|
||||
if (trigger)
|
||||
co->set_shape_as_trigger( co->get_shape_count() -1, true );
|
||||
co->set_shape_as_trigger(co->get_shape_count() - 1, true);
|
||||
} else {
|
||||
update_shape_index=-1;
|
||||
update_shape_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionShape::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
unparenting=false;
|
||||
can_update_body=get_tree()->is_editor_hint();
|
||||
unparenting = false;
|
||||
can_update_body = get_tree()->is_editor_hint();
|
||||
set_notify_local_transform(!can_update_body);
|
||||
|
||||
if (get_tree()->is_debugging_collisions_hint()) {
|
||||
|
|
@ -337,25 +335,25 @@ void CollisionShape::_notification(int p_what) {
|
|||
//indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
// VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
|
||||
// VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
|
||||
if (can_update_body && updating_body) {
|
||||
_update_body();
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
/* if (indicator_instance.is_valid()) {
|
||||
/* if (indicator_instance.is_valid()) {
|
||||
VisualServer::get_singleton()->free(indicator_instance);
|
||||
indicator_instance=RID();
|
||||
}*/
|
||||
can_update_body=false;
|
||||
can_update_body = false;
|
||||
set_notify_local_transform(false);
|
||||
if (debug_shape) {
|
||||
debug_shape->queue_delete();
|
||||
debug_shape=NULL;
|
||||
debug_shape = NULL;
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_UNPARENTED: {
|
||||
unparenting=true;
|
||||
unparenting = true;
|
||||
if (can_update_body && updating_body)
|
||||
_update_body();
|
||||
} break;
|
||||
|
|
@ -365,34 +363,29 @@ void CollisionShape::_notification(int p_what) {
|
|||
} break;
|
||||
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
|
||||
|
||||
if (!can_update_body && update_shape_index>=0) {
|
||||
if (!can_update_body && update_shape_index >= 0) {
|
||||
|
||||
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
|
||||
if (co) {
|
||||
co->set_shape_transform(update_shape_index,get_transform());
|
||||
co->set_shape_transform(update_shape_index, get_transform());
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CollisionShape::resource_changed(RES res) {
|
||||
|
||||
update_gizmo();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CollisionShape::_set_update_shape_index(int p_index) {
|
||||
|
||||
|
||||
update_shape_index=p_index;
|
||||
update_shape_index = p_index;
|
||||
}
|
||||
|
||||
int CollisionShape::_get_update_shape_index() const{
|
||||
int CollisionShape::_get_update_shape_index() const {
|
||||
|
||||
return update_shape_index;
|
||||
}
|
||||
|
|
@ -410,45 +403,42 @@ String CollisionShape::get_configuration_warning() const {
|
|||
return String();
|
||||
}
|
||||
|
||||
|
||||
void CollisionShape::_bind_methods() {
|
||||
|
||||
//not sure if this should do anything
|
||||
ObjectTypeDB::bind_method(_MD("resource_changed","resource"),&CollisionShape::resource_changed);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape","shape"),&CollisionShape::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape"),&CollisionShape::get_shape);
|
||||
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionShape::_add_to_collision_object);
|
||||
ObjectTypeDB::bind_method(_MD("set_trigger","enable"),&CollisionShape::set_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("is_trigger"),&CollisionShape::is_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("make_convex_from_brothers"),&CollisionShape::make_convex_from_brothers);
|
||||
ObjectTypeDB::set_method_flags("CollisionShape","make_convex_from_brothers",METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
|
||||
ObjectTypeDB::bind_method(_MD("_set_update_shape_index","index"),&CollisionShape::_set_update_shape_index);
|
||||
ObjectTypeDB::bind_method(_MD("_get_update_shape_index"),&CollisionShape::_get_update_shape_index);
|
||||
ObjectTypeDB::bind_method(_MD("resource_changed", "resource"), &CollisionShape::resource_changed);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape", "shape"), &CollisionShape::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape"), &CollisionShape::get_shape);
|
||||
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"), &CollisionShape::_add_to_collision_object);
|
||||
ObjectTypeDB::bind_method(_MD("set_trigger", "enable"), &CollisionShape::set_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("is_trigger"), &CollisionShape::is_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("make_convex_from_brothers"), &CollisionShape::make_convex_from_brothers);
|
||||
ObjectTypeDB::set_method_flags("CollisionShape", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
|
||||
ObjectTypeDB::bind_method(_MD("_set_update_shape_index", "index"), &CollisionShape::_set_update_shape_index);
|
||||
ObjectTypeDB::bind_method(_MD("_get_update_shape_index"), &CollisionShape::_get_update_shape_index);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_shape_index"),&CollisionShape::get_collision_object_shape_index);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_shape_index"), &CollisionShape::get_collision_object_shape_index);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), _SCS("set_shape"), _SCS("get_shape"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"trigger"),_SCS("set_trigger"),_SCS("is_trigger"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "_update_shape_index", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_NOEDITOR), _SCS("_set_update_shape_index"), _SCS("_get_update_shape_index"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), _SCS("set_shape"), _SCS("get_shape"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trigger"), _SCS("set_trigger"), _SCS("is_trigger"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_update_shape_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), _SCS("_set_update_shape_index"), _SCS("_get_update_shape_index"));
|
||||
}
|
||||
|
||||
|
||||
void CollisionShape::set_shape(const Ref<Shape> &p_shape) {
|
||||
|
||||
if (!shape.is_null())
|
||||
shape->unregister_owner(this);
|
||||
shape=p_shape;
|
||||
shape = p_shape;
|
||||
if (!shape.is_null())
|
||||
shape->register_owner(this);
|
||||
update_gizmo();
|
||||
if (updating_body) {
|
||||
_update_body();
|
||||
} else if (can_update_body && update_shape_index>=0 && is_inside_tree()){
|
||||
} else if (can_update_body && update_shape_index >= 0 && is_inside_tree()) {
|
||||
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
|
||||
if (co) {
|
||||
co->set_shape(update_shape_index,p_shape);
|
||||
co->set_shape(update_shape_index, p_shape);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,9 +447,8 @@ Ref<Shape> CollisionShape::get_shape() const {
|
|||
return shape;
|
||||
}
|
||||
|
||||
|
||||
void CollisionShape::set_updating_body(bool p_update) {
|
||||
updating_body=p_update;
|
||||
updating_body = p_update;
|
||||
}
|
||||
|
||||
bool CollisionShape::is_updating_body() const {
|
||||
|
|
@ -469,31 +458,31 @@ bool CollisionShape::is_updating_body() const {
|
|||
|
||||
void CollisionShape::set_trigger(bool p_trigger) {
|
||||
|
||||
trigger=p_trigger;
|
||||
if (updating_body) {
|
||||
_update_body();
|
||||
} else if (can_update_body && update_shape_index>=0 && is_inside_tree()){
|
||||
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
|
||||
if (co) {
|
||||
co->set_shape_as_trigger(update_shape_index,p_trigger);
|
||||
}
|
||||
}
|
||||
trigger = p_trigger;
|
||||
if (updating_body) {
|
||||
_update_body();
|
||||
} else if (can_update_body && update_shape_index >= 0 && is_inside_tree()) {
|
||||
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
|
||||
if (co) {
|
||||
co->set_shape_as_trigger(update_shape_index, p_trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CollisionShape::is_trigger() const{
|
||||
bool CollisionShape::is_trigger() const {
|
||||
|
||||
return trigger;
|
||||
return trigger;
|
||||
}
|
||||
|
||||
CollisionShape::CollisionShape() {
|
||||
|
||||
//indicator = VisualServer::get_singleton()->mesh_create();
|
||||
updating_body=true;
|
||||
unparenting=false;
|
||||
update_shape_index=-1;
|
||||
trigger=false;
|
||||
can_update_body=false;
|
||||
debug_shape=NULL;
|
||||
updating_body = true;
|
||||
unparenting = false;
|
||||
update_shape_index = -1;
|
||||
trigger = false;
|
||||
can_update_body = false;
|
||||
debug_shape = NULL;
|
||||
}
|
||||
|
||||
CollisionShape::~CollisionShape() {
|
||||
|
|
@ -504,10 +493,9 @@ CollisionShape::~CollisionShape() {
|
|||
|
||||
void CollisionShape::_create_debug_shape() {
|
||||
|
||||
|
||||
if (debug_shape) {
|
||||
debug_shape->queue_delete();
|
||||
debug_shape=NULL;
|
||||
debug_shape = NULL;
|
||||
}
|
||||
|
||||
Ref<Shape> s = get_shape();
|
||||
|
|
@ -515,37 +503,35 @@ void CollisionShape::_create_debug_shape() {
|
|||
if (s.is_null())
|
||||
return;
|
||||
|
||||
|
||||
Ref<Mesh> mesh = s->get_debug_mesh();
|
||||
|
||||
MeshInstance *mi = memnew( MeshInstance );
|
||||
MeshInstance *mi = memnew(MeshInstance);
|
||||
mi->set_mesh(mesh);
|
||||
|
||||
add_child(mi);
|
||||
debug_shape=mi;
|
||||
|
||||
debug_shape = mi;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "body_volume.h"
|
||||
|
||||
#include "scene/3d/physics_body.h"
|
||||
#include "geometry.h"
|
||||
#include "scene/3d/physics_body.h"
|
||||
|
||||
#define ADD_TRIANGLE( m_a, m_b, m_c, m_color)\
|
||||
{\
|
||||
Vector<Vector3> points;\
|
||||
points.resize(3);\
|
||||
points[0]=m_a;\
|
||||
points[1]=m_b;\
|
||||
points[2]=m_c;\
|
||||
Vector<Color> colors;\
|
||||
colors.resize(3);\
|
||||
colors[0]=m_color;\
|
||||
colors[1]=m_color;\
|
||||
colors[2]=m_color;\
|
||||
vs->poly_add_primitive(p_indicator,points,Vector<Vector3>(),colors,Vector<Vector3>());\
|
||||
}
|
||||
#define ADD_TRIANGLE(m_a, m_b, m_c, m_color) \
|
||||
{ \
|
||||
Vector<Vector3> points; \
|
||||
points.resize(3); \
|
||||
points[0] = m_a; \
|
||||
points[1] = m_b; \
|
||||
points[2] = m_c; \
|
||||
Vector<Color> colors; \
|
||||
colors.resize(3); \
|
||||
colors[0] = m_color; \
|
||||
colors[1] = m_color; \
|
||||
colors[2] = m_color; \
|
||||
vs->poly_add_primitive(p_indicator, points, Vector<Vector3>(), colors, Vector<Vector3>()); \
|
||||
}
|
||||
|
||||
|
||||
void CollisionShape::_notification(int p_what) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
class CollisionShape : public Spatial {
|
||||
|
||||
OBJ_TYPE( CollisionShape, Spatial );
|
||||
OBJ_TYPE(CollisionShape, Spatial);
|
||||
OBJ_CATEGORY("3D Physics Nodes");
|
||||
|
||||
Ref<Shape> shape;
|
||||
|
|
@ -50,7 +50,7 @@ class CollisionShape : public Spatial {
|
|||
RID indicator_instance;
|
||||
*/
|
||||
|
||||
Node* debug_shape;
|
||||
Node *debug_shape;
|
||||
|
||||
void resource_changed(RES res);
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ class CollisionShape : public Spatial {
|
|||
int update_shape_index;
|
||||
|
||||
void _update_body();
|
||||
void _add_to_collision_object(Object* p_cshape);
|
||||
void _add_to_collision_object(Object *p_cshape);
|
||||
|
||||
void _set_update_shape_index(int p_index);
|
||||
int _get_update_shape_index() const;
|
||||
|
|
@ -71,12 +71,10 @@ class CollisionShape : public Spatial {
|
|||
void _create_debug_shape();
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void make_convex_from_brothers();
|
||||
|
||||
void set_shape(const Ref<Shape> &p_shape);
|
||||
|
|
@ -90,7 +88,6 @@ public:
|
|||
|
||||
int get_collision_object_shape_index() const { return _get_update_shape_index(); }
|
||||
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
CollisionShape();
|
||||
|
|
@ -98,4 +95,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // BODY_VOLUME_H
|
||||
|
||||
|
|
|
|||
|
|
@ -28,19 +28,19 @@
|
|||
/*************************************************************************/
|
||||
#include "bone_attachment.h"
|
||||
|
||||
bool BoneAttachment::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool BoneAttachment::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (String(p_name)=="bone_name") {
|
||||
if (String(p_name) == "bone_name") {
|
||||
|
||||
r_ret=get_bone_name();
|
||||
r_ret = get_bone_name();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool BoneAttachment::_set(const StringName& p_name, const Variant& p_value){
|
||||
bool BoneAttachment::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
if (String(p_name)=="bone_name") {
|
||||
if (String(p_name) == "bone_name") {
|
||||
|
||||
set_bone_name(p_value);
|
||||
return true;
|
||||
|
|
@ -48,40 +48,37 @@ bool BoneAttachment::_set(const StringName& p_name, const Variant& p_value){
|
|||
|
||||
return false;
|
||||
}
|
||||
void BoneAttachment::_get_property_list( List<PropertyInfo>* p_list ) const{
|
||||
void BoneAttachment::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
Skeleton *parent=NULL;
|
||||
if(get_parent())
|
||||
parent=get_parent()->cast_to<Skeleton>();
|
||||
Skeleton *parent = NULL;
|
||||
if (get_parent())
|
||||
parent = get_parent()->cast_to<Skeleton>();
|
||||
|
||||
if (parent) {
|
||||
|
||||
String names;
|
||||
for(int i=0;i<parent->get_bone_count();i++) {
|
||||
if(i>0)
|
||||
names+=",";
|
||||
names+=parent->get_bone_name(i);
|
||||
for (int i = 0; i < parent->get_bone_count(); i++) {
|
||||
if (i > 0)
|
||||
names += ",";
|
||||
names += parent->get_bone_name(i);
|
||||
}
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::STRING,"bone_name",PROPERTY_HINT_ENUM,names));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "bone_name", PROPERTY_HINT_ENUM, names));
|
||||
} else {
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::STRING,"bone_name"));
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "bone_name"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BoneAttachment::_check_bind() {
|
||||
|
||||
if (get_parent() && get_parent()->cast_to<Skeleton>()) {
|
||||
Skeleton *sk = get_parent()->cast_to<Skeleton>();
|
||||
int idx = sk->find_bone(bone_name);
|
||||
if (idx!=-1) {
|
||||
sk->bind_child_node_to_bone(idx,this);
|
||||
if (idx != -1) {
|
||||
sk->bind_child_node_to_bone(idx, this);
|
||||
set_transform(sk->get_bone_global_pose(idx));
|
||||
bound=true;
|
||||
bound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -93,33 +90,33 @@ void BoneAttachment::_check_unbind() {
|
|||
if (get_parent() && get_parent()->cast_to<Skeleton>()) {
|
||||
Skeleton *sk = get_parent()->cast_to<Skeleton>();
|
||||
int idx = sk->find_bone(bone_name);
|
||||
if (idx!=-1) {
|
||||
sk->unbind_child_node_from_bone(idx,this);
|
||||
if (idx != -1) {
|
||||
sk->unbind_child_node_from_bone(idx, this);
|
||||
}
|
||||
}
|
||||
bound=false;
|
||||
bound = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BoneAttachment::set_bone_name(const String& p_name) {
|
||||
void BoneAttachment::set_bone_name(const String &p_name) {
|
||||
|
||||
if (is_inside_tree())
|
||||
_check_unbind();
|
||||
|
||||
bone_name=p_name;
|
||||
bone_name = p_name;
|
||||
|
||||
if (is_inside_tree())
|
||||
_check_bind();
|
||||
}
|
||||
|
||||
String BoneAttachment::get_bone_name() const{
|
||||
String BoneAttachment::get_bone_name() const {
|
||||
|
||||
return bone_name;
|
||||
}
|
||||
|
||||
void BoneAttachment::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
|
|
@ -132,13 +129,11 @@ void BoneAttachment::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
BoneAttachment::BoneAttachment()
|
||||
{
|
||||
bound=false;
|
||||
|
||||
BoneAttachment::BoneAttachment() {
|
||||
bound = false;
|
||||
}
|
||||
|
||||
void BoneAttachment::_bind_methods(){
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_name","bone_name"),&BoneAttachment::set_bone_name);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_name"),&BoneAttachment::get_bone_name);
|
||||
void BoneAttachment::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_name", "bone_name"), &BoneAttachment::set_bone_name);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_name"), &BoneAttachment::get_bone_name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,25 +33,24 @@
|
|||
|
||||
class BoneAttachment : public Spatial {
|
||||
|
||||
OBJ_TYPE(BoneAttachment,Spatial);
|
||||
OBJ_TYPE(BoneAttachment, Spatial);
|
||||
|
||||
bool bound;
|
||||
String bone_name;
|
||||
|
||||
void _check_bind();
|
||||
void _check_unbind();
|
||||
protected:
|
||||
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
void _get_property_list( List<PropertyInfo>* p_list ) const;
|
||||
protected:
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_bone_name(const String& p_name);
|
||||
void set_bone_name(const String &p_name);
|
||||
String get_bone_name() const;
|
||||
|
||||
BoneAttachment();
|
||||
|
|
|
|||
|
|
@ -32,10 +32,7 @@
|
|||
#include "scene/resources/material.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
|
||||
void Camera::_update_audio_listener_state() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Camera::_request_camera_update() {
|
||||
|
|
@ -45,60 +42,56 @@ void Camera::_request_camera_update() {
|
|||
|
||||
void Camera::_update_camera_mode() {
|
||||
|
||||
|
||||
force_change=true;
|
||||
switch(mode) {
|
||||
force_change = true;
|
||||
switch (mode) {
|
||||
case PROJECTION_PERSPECTIVE: {
|
||||
|
||||
|
||||
set_perspective(fov,near,far);
|
||||
set_perspective(fov, near, far);
|
||||
|
||||
} break;
|
||||
case PROJECTION_ORTHOGONAL: {
|
||||
set_orthogonal(size,near,far);
|
||||
set_orthogonal(size, near, far);
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Camera::_set(const StringName& p_name, const Variant& p_value) {
|
||||
bool Camera::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
bool changed_all=false;
|
||||
if (p_name=="projection") {
|
||||
bool changed_all = false;
|
||||
if (p_name == "projection") {
|
||||
|
||||
int proj = p_value;
|
||||
if (proj==PROJECTION_PERSPECTIVE)
|
||||
mode=PROJECTION_PERSPECTIVE;
|
||||
if (proj==PROJECTION_ORTHOGONAL)
|
||||
mode=PROJECTION_ORTHOGONAL;
|
||||
if (proj == PROJECTION_PERSPECTIVE)
|
||||
mode = PROJECTION_PERSPECTIVE;
|
||||
if (proj == PROJECTION_ORTHOGONAL)
|
||||
mode = PROJECTION_ORTHOGONAL;
|
||||
|
||||
changed_all=true;
|
||||
} else if (p_name=="fov" || p_name=="fovy" || p_name=="fovx")
|
||||
fov=p_value;
|
||||
else if (p_name=="size" || p_name=="sizex" || p_name=="sizey")
|
||||
size=p_value;
|
||||
else if (p_name=="near")
|
||||
near=p_value;
|
||||
else if (p_name=="far")
|
||||
far=p_value;
|
||||
else if (p_name=="keep_aspect")
|
||||
changed_all = true;
|
||||
} else if (p_name == "fov" || p_name == "fovy" || p_name == "fovx")
|
||||
fov = p_value;
|
||||
else if (p_name == "size" || p_name == "sizex" || p_name == "sizey")
|
||||
size = p_value;
|
||||
else if (p_name == "near")
|
||||
near = p_value;
|
||||
else if (p_name == "far")
|
||||
far = p_value;
|
||||
else if (p_name == "keep_aspect")
|
||||
set_keep_aspect_mode(KeepAspect(int(p_value)));
|
||||
else if (p_name=="vaspect")
|
||||
set_keep_aspect_mode(p_value?KEEP_WIDTH:KEEP_HEIGHT);
|
||||
else if (p_name=="h_offset")
|
||||
h_offset=p_value;
|
||||
else if (p_name=="v_offset")
|
||||
v_offset=p_value;
|
||||
else if (p_name=="current") {
|
||||
else if (p_name == "vaspect")
|
||||
set_keep_aspect_mode(p_value ? KEEP_WIDTH : KEEP_HEIGHT);
|
||||
else if (p_name == "h_offset")
|
||||
h_offset = p_value;
|
||||
else if (p_name == "v_offset")
|
||||
v_offset = p_value;
|
||||
else if (p_name == "current") {
|
||||
if (p_value.operator bool()) {
|
||||
make_current();
|
||||
} else {
|
||||
clear_current();
|
||||
}
|
||||
} else if (p_name=="visible_layers") {
|
||||
} else if (p_name == "visible_layers") {
|
||||
set_visible_layers(p_value);
|
||||
} else if (p_name=="environment") {
|
||||
} else if (p_name == "environment") {
|
||||
set_environment(p_value);
|
||||
} else
|
||||
return false;
|
||||
|
|
@ -107,117 +100,108 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) {
|
|||
if (changed_all)
|
||||
_change_notify();
|
||||
return true;
|
||||
|
||||
}
|
||||
bool Camera::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool Camera::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (p_name=="projection") {
|
||||
r_ret= mode;
|
||||
} else if (p_name=="fov" || p_name=="fovy" || p_name=="fovx")
|
||||
r_ret= fov;
|
||||
else if (p_name=="size" || p_name=="sizex" || p_name=="sizey")
|
||||
r_ret= size;
|
||||
else if (p_name=="near")
|
||||
r_ret= near;
|
||||
else if (p_name=="far")
|
||||
r_ret= far;
|
||||
else if (p_name=="keep_aspect")
|
||||
r_ret= int(keep_aspect);
|
||||
else if (p_name=="current") {
|
||||
if (p_name == "projection") {
|
||||
r_ret = mode;
|
||||
} else if (p_name == "fov" || p_name == "fovy" || p_name == "fovx")
|
||||
r_ret = fov;
|
||||
else if (p_name == "size" || p_name == "sizex" || p_name == "sizey")
|
||||
r_ret = size;
|
||||
else if (p_name == "near")
|
||||
r_ret = near;
|
||||
else if (p_name == "far")
|
||||
r_ret = far;
|
||||
else if (p_name == "keep_aspect")
|
||||
r_ret = int(keep_aspect);
|
||||
else if (p_name == "current") {
|
||||
|
||||
if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
|
||||
r_ret=current;
|
||||
r_ret = current;
|
||||
} else {
|
||||
r_ret=is_current();
|
||||
r_ret = is_current();
|
||||
}
|
||||
} else if (p_name=="visible_layers") {
|
||||
r_ret=get_visible_layers();
|
||||
} else if (p_name=="h_offset") {
|
||||
r_ret=get_h_offset();
|
||||
} else if (p_name=="v_offset") {
|
||||
r_ret=get_v_offset();
|
||||
} else if (p_name=="environment") {
|
||||
r_ret=get_environment();
|
||||
} else if (p_name == "visible_layers") {
|
||||
r_ret = get_visible_layers();
|
||||
} else if (p_name == "h_offset") {
|
||||
r_ret = get_h_offset();
|
||||
} else if (p_name == "v_offset") {
|
||||
r_ret = get_v_offset();
|
||||
} else if (p_name == "environment") {
|
||||
r_ret = get_environment();
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
void Camera::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal") );
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal"));
|
||||
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
|
||||
case PROJECTION_PERSPECTIVE: {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_NOEDITOR) );
|
||||
if (keep_aspect==KEEP_WIDTH)
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_NOEDITOR));
|
||||
if (keep_aspect == KEEP_WIDTH)
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "fovx", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_EDITOR));
|
||||
else
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "fovy", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_EDITOR));
|
||||
|
||||
} break;
|
||||
case PROJECTION_ORTHOGONAL: {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "size" , PROPERTY_HINT_RANGE, "1,16384,0.01",PROPERTY_USAGE_NOEDITOR ) );
|
||||
if (keep_aspect==KEEP_WIDTH)
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "sizex" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "1,16384,0.01", PROPERTY_USAGE_NOEDITOR));
|
||||
if (keep_aspect == KEEP_WIDTH)
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "sizex", PROPERTY_HINT_RANGE, "0.1,16384,0.01", PROPERTY_USAGE_EDITOR));
|
||||
else
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "sizey" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "sizey", PROPERTY_HINT_RANGE, "0.1,16384,0.01", PROPERTY_USAGE_EDITOR));
|
||||
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "near" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "far" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "keep_aspect",PROPERTY_HINT_ENUM,"Keep Width,Keep Height") );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "current" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "visible_layers",PROPERTY_HINT_ALL_FLAGS ) );
|
||||
p_list->push_back( PropertyInfo( Variant::OBJECT, "environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "h_offset" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "v_offset" ) );
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "current"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "visible_layers", PROPERTY_HINT_ALL_FLAGS));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "h_offset"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "v_offset"));
|
||||
}
|
||||
|
||||
void Camera::_update_camera() {
|
||||
|
||||
Transform tr = get_camera_transform();
|
||||
tr.origin+=tr.basis.get_axis(1)*v_offset;
|
||||
tr.origin+=tr.basis.get_axis(0)*h_offset;
|
||||
VisualServer::get_singleton()->camera_set_transform( camera, tr );
|
||||
tr.origin += tr.basis.get_axis(1) * v_offset;
|
||||
tr.origin += tr.basis.get_axis(0) * h_offset;
|
||||
VisualServer::get_singleton()->camera_set_transform(camera, tr);
|
||||
|
||||
// here goes listener stuff
|
||||
// if (viewport_ptr && is_inside_scene() && is_current())
|
||||
// get_viewport()->_camera_transform_changed_notify();
|
||||
// here goes listener stuff
|
||||
// if (viewport_ptr && is_inside_scene() && is_current())
|
||||
// get_viewport()->_camera_transform_changed_notify();
|
||||
|
||||
if (is_inside_tree() && is_current()) {
|
||||
get_viewport()->_camera_transform_changed_notify();
|
||||
|
||||
}
|
||||
|
||||
if (is_current() && get_world().is_valid()) {
|
||||
get_world()->_update_camera(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Camera::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
|
||||
bool first_camera = get_viewport()->_camera_add(this);
|
||||
if (!get_tree()->is_node_being_edited(this) && (current || first_camera))
|
||||
make_current();
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
|
|
@ -228,16 +212,15 @@ void Camera::_notification(int p_what) {
|
|||
if (!get_tree()->is_node_being_edited(this)) {
|
||||
if (is_current()) {
|
||||
clear_current();
|
||||
current=true; //keep it true
|
||||
current = true; //keep it true
|
||||
|
||||
} else {
|
||||
current=false;
|
||||
current = false;
|
||||
}
|
||||
}
|
||||
|
||||
get_viewport()->_camera_remove(this);
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_BECAME_CURRENT: {
|
||||
if (get_world().is_valid()) {
|
||||
|
|
@ -249,13 +232,9 @@ void Camera::_notification(int p_what) {
|
|||
get_world()->_remove_camera(this);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Transform Camera::get_camera_transform() const {
|
||||
|
||||
return get_global_transform().orthonormalized();
|
||||
|
|
@ -263,31 +242,31 @@ Transform Camera::get_camera_transform() const {
|
|||
|
||||
void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
|
||||
|
||||
if (!force_change && fov==p_fovy_degrees && p_z_near==near && p_z_far==far && mode==PROJECTION_PERSPECTIVE)
|
||||
if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE)
|
||||
return;
|
||||
|
||||
fov=p_fovy_degrees;
|
||||
near=p_z_near;
|
||||
far=p_z_far;
|
||||
mode=PROJECTION_PERSPECTIVE;
|
||||
fov = p_fovy_degrees;
|
||||
near = p_z_near;
|
||||
far = p_z_far;
|
||||
mode = PROJECTION_PERSPECTIVE;
|
||||
|
||||
VisualServer::get_singleton()->camera_set_perspective(camera,fov,near,far);
|
||||
VisualServer::get_singleton()->camera_set_perspective(camera, fov, near, far);
|
||||
update_gizmo();
|
||||
force_change=false;
|
||||
force_change = false;
|
||||
}
|
||||
void Camera::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
|
||||
|
||||
if (!force_change && size==p_size && p_z_near==near && p_z_far==far && mode==PROJECTION_ORTHOGONAL)
|
||||
if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL)
|
||||
return;
|
||||
|
||||
size = p_size;
|
||||
|
||||
near=p_z_near;
|
||||
far=p_z_far;
|
||||
mode=PROJECTION_ORTHOGONAL;
|
||||
force_change=false;
|
||||
near = p_z_near;
|
||||
far = p_z_far;
|
||||
mode = PROJECTION_ORTHOGONAL;
|
||||
force_change = false;
|
||||
|
||||
VisualServer::get_singleton()->camera_set_orthogonal(camera,size,near,far);
|
||||
VisualServer::get_singleton()->camera_set_orthogonal(camera, size, near, far);
|
||||
update_gizmo();
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +277,7 @@ RID Camera::get_camera() const {
|
|||
|
||||
void Camera::make_current() {
|
||||
|
||||
current=true;
|
||||
current = true;
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
|
@ -308,140 +287,127 @@ void Camera::make_current() {
|
|||
//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Camera::clear_current() {
|
||||
|
||||
current=false;
|
||||
current = false;
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
if (get_viewport()->get_camera()==this) {
|
||||
if (get_viewport()->get_camera() == this) {
|
||||
get_viewport()->_camera_set(NULL);
|
||||
get_viewport()->_camera_make_next_current(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Camera::is_current() const {
|
||||
|
||||
if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
|
||||
|
||||
return get_viewport()->get_camera()==this;
|
||||
return get_viewport()->get_camera() == this;
|
||||
} else
|
||||
return current;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Camera::_can_gizmo_scale() const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
RES Camera::_get_gizmo_geometry() const {
|
||||
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.5) );
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(1.0, 0.5, 1.0, 0.5));
|
||||
mat->set_line_width(4);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED,true);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED, true);
|
||||
//mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(mat);
|
||||
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
|
||||
case PROJECTION_PERSPECTIVE: {
|
||||
|
||||
Vector3 side = Vector3(Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)));
|
||||
Vector3 nside = side;
|
||||
nside.x = -nside.x;
|
||||
Vector3 up = Vector3(0, side.x, 0);
|
||||
|
||||
#define ADD_TRIANGLE(m_a, m_b, m_c) \
|
||||
{ \
|
||||
surface_tool->add_vertex(m_a); \
|
||||
surface_tool->add_vertex(m_b); \
|
||||
surface_tool->add_vertex(m_b); \
|
||||
surface_tool->add_vertex(m_c); \
|
||||
surface_tool->add_vertex(m_c); \
|
||||
surface_tool->add_vertex(m_a); \
|
||||
}
|
||||
|
||||
Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) );
|
||||
Vector3 nside=side;
|
||||
nside.x=-nside.x;
|
||||
Vector3 up=Vector3(0,side.x,0);
|
||||
ADD_TRIANGLE(Vector3(), side + up, side - up);
|
||||
ADD_TRIANGLE(Vector3(), nside + up, nside - up);
|
||||
ADD_TRIANGLE(Vector3(), side + up, nside + up);
|
||||
ADD_TRIANGLE(Vector3(), side - up, nside - up);
|
||||
|
||||
|
||||
#define ADD_TRIANGLE( m_a, m_b, m_c)\
|
||||
{\
|
||||
surface_tool->add_vertex(m_a);\
|
||||
surface_tool->add_vertex(m_b);\
|
||||
surface_tool->add_vertex(m_b);\
|
||||
surface_tool->add_vertex(m_c);\
|
||||
surface_tool->add_vertex(m_c);\
|
||||
surface_tool->add_vertex(m_a);\
|
||||
}
|
||||
|
||||
ADD_TRIANGLE( Vector3(), side+up, side-up );
|
||||
ADD_TRIANGLE( Vector3(), nside+up, nside-up );
|
||||
ADD_TRIANGLE( Vector3(), side+up, nside+up );
|
||||
ADD_TRIANGLE( Vector3(), side-up, nside-up );
|
||||
|
||||
side.x*=0.25;
|
||||
nside.x*=0.25;
|
||||
Vector3 tup( 0, up.y*3/2,side.z);
|
||||
ADD_TRIANGLE( tup, side+up, nside+up );
|
||||
side.x *= 0.25;
|
||||
nside.x *= 0.25;
|
||||
Vector3 tup(0, up.y * 3 / 2, side.z);
|
||||
ADD_TRIANGLE(tup, side + up, nside + up);
|
||||
|
||||
} break;
|
||||
case PROJECTION_ORTHOGONAL: {
|
||||
|
||||
#define ADD_QUAD( m_a, m_b, m_c, m_d)\
|
||||
{\
|
||||
surface_tool->add_vertex(m_a);\
|
||||
surface_tool->add_vertex(m_b);\
|
||||
surface_tool->add_vertex(m_b);\
|
||||
surface_tool->add_vertex(m_c);\
|
||||
surface_tool->add_vertex(m_c);\
|
||||
surface_tool->add_vertex(m_d);\
|
||||
surface_tool->add_vertex(m_d);\
|
||||
surface_tool->add_vertex(m_a);\
|
||||
}
|
||||
#define ADD_QUAD(m_a, m_b, m_c, m_d) \
|
||||
{ \
|
||||
surface_tool->add_vertex(m_a); \
|
||||
surface_tool->add_vertex(m_b); \
|
||||
surface_tool->add_vertex(m_b); \
|
||||
surface_tool->add_vertex(m_c); \
|
||||
surface_tool->add_vertex(m_c); \
|
||||
surface_tool->add_vertex(m_d); \
|
||||
surface_tool->add_vertex(m_d); \
|
||||
surface_tool->add_vertex(m_a); \
|
||||
}
|
||||
|
||||
float hsize=size*0.5;
|
||||
Vector3 right(hsize,0,0);
|
||||
Vector3 up(0,hsize,0);
|
||||
Vector3 back(0,0,-1.0);
|
||||
Vector3 front(0,0,0);
|
||||
float hsize = size * 0.5;
|
||||
Vector3 right(hsize, 0, 0);
|
||||
Vector3 up(0, hsize, 0);
|
||||
Vector3 back(0, 0, -1.0);
|
||||
Vector3 front(0, 0, 0);
|
||||
|
||||
ADD_QUAD( -up-right,-up+right,up+right,up-right);
|
||||
ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back);
|
||||
ADD_QUAD( up+right,up+right+back,up-right+back,up-right);
|
||||
ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right);
|
||||
ADD_QUAD(-up - right, -up + right, up + right, up - right);
|
||||
ADD_QUAD(-up - right + back, -up + right + back, up + right + back, up - right + back);
|
||||
ADD_QUAD(up + right, up + right + back, up - right + back, up - right);
|
||||
ADD_QUAD(-up + right, -up + right + back, -up - right + back, -up - right);
|
||||
|
||||
right.x*=0.25;
|
||||
Vector3 tup( 0, up.y*3/2,back.z );
|
||||
ADD_TRIANGLE( tup, right+up+back, -right+up+back );
|
||||
right.x *= 0.25;
|
||||
Vector3 tup(0, up.y * 3 / 2, back.z);
|
||||
ADD_TRIANGLE(tup, right + up + back, -right + up + back);
|
||||
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
return surface_tool->commit();
|
||||
|
||||
}
|
||||
|
||||
Vector3 Camera::project_ray_normal(const Point2& p_pos) const {
|
||||
Vector3 Camera::project_ray_normal(const Point2 &p_pos) const {
|
||||
|
||||
Vector3 ray = project_local_ray_normal(p_pos);
|
||||
return get_camera_transform().basis.xform(ray).normalized();
|
||||
};
|
||||
|
||||
Vector3 Camera::project_local_ray_normal(const Point2& p_pos) const {
|
||||
Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
ERR_EXPLAIN("Camera is not inside scene.");
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),Vector3());
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
Vector2 cpos = p_pos;
|
||||
|
|
@ -453,26 +419,25 @@ Vector3 Camera::project_local_ray_normal(const Point2& p_pos) const {
|
|||
|
||||
Vector3 ray;
|
||||
|
||||
if (mode==PROJECTION_ORTHOGONAL) {
|
||||
if (mode == PROJECTION_ORTHOGONAL) {
|
||||
|
||||
ray=Vector3(0,0,-1);
|
||||
ray = Vector3(0, 0, -1);
|
||||
} else {
|
||||
CameraMatrix cm;
|
||||
cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
float screen_w,screen_h;
|
||||
cm.get_viewport_size(screen_w,screen_h);
|
||||
ray=Vector3( ((cpos.x/viewport_size.width)*2.0-1.0)*screen_w, ((1.0-(cpos.y/viewport_size.height))*2.0-1.0)*screen_h,-near).normalized();
|
||||
cm.set_perspective(fov, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
float screen_w, screen_h;
|
||||
cm.get_viewport_size(screen_w, screen_h);
|
||||
ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_w, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_h, -near).normalized();
|
||||
}
|
||||
|
||||
return ray;
|
||||
};
|
||||
|
||||
|
||||
Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
|
||||
Vector3 Camera::project_ray_origin(const Point2 &p_pos) const {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
ERR_EXPLAIN("Camera is not inside scene.");
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),Vector3());
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -484,8 +449,8 @@ Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
|
|||
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
|
||||
#endif
|
||||
|
||||
ERR_FAIL_COND_V( viewport_size.y == 0, Vector3() );
|
||||
// float aspect = viewport_size.x / viewport_size.y;
|
||||
ERR_FAIL_COND_V(viewport_size.y == 0, Vector3());
|
||||
// float aspect = viewport_size.x / viewport_size.y;
|
||||
|
||||
if (mode == PROJECTION_PERSPECTIVE) {
|
||||
|
||||
|
|
@ -493,91 +458,84 @@ Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
|
|||
} else {
|
||||
|
||||
Vector2 pos = cpos / viewport_size;
|
||||
float vsize,hsize;
|
||||
if (keep_aspect==KEEP_WIDTH) {
|
||||
vsize = size/viewport_size.get_aspect();
|
||||
float vsize, hsize;
|
||||
if (keep_aspect == KEEP_WIDTH) {
|
||||
vsize = size / viewport_size.get_aspect();
|
||||
hsize = size;
|
||||
} else {
|
||||
hsize = size*viewport_size.get_aspect();
|
||||
hsize = size * viewport_size.get_aspect();
|
||||
vsize = size;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3 ray;
|
||||
ray.x = pos.x * (hsize) - hsize/2;
|
||||
ray.y = (1.0 - pos.y) * (vsize) - vsize/2;
|
||||
ray.x = pos.x * (hsize)-hsize / 2;
|
||||
ray.y = (1.0 - pos.y) * (vsize)-vsize / 2;
|
||||
ray.z = -near;
|
||||
ray = get_camera_transform().xform(ray);
|
||||
return ray;
|
||||
};
|
||||
};
|
||||
|
||||
bool Camera::is_position_behind(const Vector3& p_pos) const {
|
||||
bool Camera::is_position_behind(const Vector3 &p_pos) const {
|
||||
|
||||
Transform t = get_global_transform();
|
||||
Vector3 eyedir = -get_global_transform().basis.get_axis(2).normalized();
|
||||
return eyedir.dot(p_pos) < (eyedir.dot(t.origin)+near);
|
||||
return eyedir.dot(p_pos) < (eyedir.dot(t.origin) + near);
|
||||
}
|
||||
|
||||
Point2 Camera::unproject_position(const Vector3& p_pos) const {
|
||||
Point2 Camera::unproject_position(const Vector3 &p_pos) const {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
ERR_EXPLAIN("Camera is not inside scene.");
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),Vector2());
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), Vector2());
|
||||
}
|
||||
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
|
||||
CameraMatrix cm;
|
||||
|
||||
|
||||
if (mode==PROJECTION_ORTHOGONAL)
|
||||
cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
if (mode == PROJECTION_ORTHOGONAL)
|
||||
cm.set_orthogonal(size, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
else
|
||||
cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
cm.set_perspective(fov, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
|
||||
Plane p(get_camera_transform().xform_inv(p_pos),1.0);
|
||||
|
||||
p=cm.xform4(p);
|
||||
p.normal/=p.d;
|
||||
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
|
||||
|
||||
p = cm.xform4(p);
|
||||
p.normal /= p.d;
|
||||
|
||||
Point2 res;
|
||||
res.x = (p.normal.x * 0.5 + 0.5) * viewport_size.x;
|
||||
res.y = (-p.normal.y * 0.5 + 0.5) * viewport_size.y;
|
||||
res.x = (p.normal.x * 0.5 + 0.5) * viewport_size.x;
|
||||
res.y = (-p.normal.y * 0.5 + 0.5) * viewport_size.y;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
Vector3 Camera::project_position(const Point2& p_point) const {
|
||||
Vector3 Camera::project_position(const Point2 &p_point) const {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
ERR_EXPLAIN("Camera is not inside scene.");
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),Vector3());
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
|
||||
}
|
||||
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
|
||||
CameraMatrix cm;
|
||||
|
||||
if (mode==PROJECTION_ORTHOGONAL)
|
||||
cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
if (mode == PROJECTION_ORTHOGONAL)
|
||||
cm.set_orthogonal(size, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
else
|
||||
cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
cm.set_perspective(fov, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
|
||||
Size2 vp_size;
|
||||
cm.get_viewport_size(vp_size.x,vp_size.y);
|
||||
cm.get_viewport_size(vp_size.x, vp_size.y);
|
||||
|
||||
Vector2 point;
|
||||
point.x = (p_point.x/viewport_size.x) * 2.0 - 1.0;
|
||||
point.y = (1.0-(p_point.y/viewport_size.y)) * 2.0 - 1.0;
|
||||
point*=vp_size;
|
||||
|
||||
Vector3 p(point.x,point.y,-near);
|
||||
point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
|
||||
point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
|
||||
point *= vp_size;
|
||||
|
||||
Vector3 p(point.x, point.y, -near);
|
||||
|
||||
return get_camera_transform().xform(p);
|
||||
}
|
||||
|
|
@ -599,13 +557,13 @@ void Camera::_camera_make_current(Node *p_camera) {
|
|||
}
|
||||
*/
|
||||
|
||||
void Camera::set_environment(const Ref<Environment>& p_environment) {
|
||||
void Camera::set_environment(const Ref<Environment> &p_environment) {
|
||||
|
||||
environment=p_environment;
|
||||
environment = p_environment;
|
||||
if (environment.is_valid())
|
||||
VS::get_singleton()->camera_set_environment(camera,environment->get_rid());
|
||||
VS::get_singleton()->camera_set_environment(camera, environment->get_rid());
|
||||
else
|
||||
VS::get_singleton()->camera_set_environment(camera,RID());
|
||||
VS::get_singleton()->camera_set_environment(camera, RID());
|
||||
}
|
||||
|
||||
Ref<Environment> Camera::get_environment() const {
|
||||
|
|
@ -613,59 +571,55 @@ Ref<Environment> Camera::get_environment() const {
|
|||
return environment;
|
||||
}
|
||||
|
||||
|
||||
void Camera::set_keep_aspect_mode(KeepAspect p_aspect) {
|
||||
|
||||
keep_aspect=p_aspect;
|
||||
VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera,p_aspect==KEEP_WIDTH);
|
||||
keep_aspect = p_aspect;
|
||||
VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
|
||||
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
Camera::KeepAspect Camera::get_keep_aspect_mode() const{
|
||||
Camera::KeepAspect Camera::get_keep_aspect_mode() const {
|
||||
|
||||
return keep_aspect;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Camera::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method( _MD("project_ray_normal","screen_point"), &Camera::project_ray_normal);
|
||||
ObjectTypeDB::bind_method( _MD("project_local_ray_normal","screen_point"), &Camera::project_local_ray_normal);
|
||||
ObjectTypeDB::bind_method( _MD("project_ray_origin","screen_point"), &Camera::project_ray_origin);
|
||||
ObjectTypeDB::bind_method( _MD("unproject_position","world_point"), &Camera::unproject_position);
|
||||
ObjectTypeDB::bind_method( _MD("is_position_behind","world_point"), &Camera::is_position_behind);
|
||||
ObjectTypeDB::bind_method( _MD("project_position","screen_point"), &Camera::project_position);
|
||||
ObjectTypeDB::bind_method( _MD("set_perspective","fov","z_near","z_far"),&Camera::set_perspective );
|
||||
ObjectTypeDB::bind_method( _MD("set_orthogonal","size","z_near","z_far"),&Camera::set_orthogonal );
|
||||
ObjectTypeDB::bind_method( _MD("make_current"),&Camera::make_current );
|
||||
ObjectTypeDB::bind_method( _MD("clear_current"),&Camera::clear_current );
|
||||
ObjectTypeDB::bind_method( _MD("is_current"),&Camera::is_current );
|
||||
ObjectTypeDB::bind_method( _MD("get_camera_transform"),&Camera::get_camera_transform );
|
||||
ObjectTypeDB::bind_method( _MD("get_fov"),&Camera::get_fov );
|
||||
ObjectTypeDB::bind_method( _MD("get_size"),&Camera::get_size );
|
||||
ObjectTypeDB::bind_method( _MD("get_zfar"),&Camera::get_zfar );
|
||||
ObjectTypeDB::bind_method( _MD("get_znear"),&Camera::get_znear );
|
||||
ObjectTypeDB::bind_method( _MD("get_projection"),&Camera::get_projection );
|
||||
ObjectTypeDB::bind_method( _MD("set_h_offset","ofs"),&Camera::set_h_offset );
|
||||
ObjectTypeDB::bind_method( _MD("get_h_offset"),&Camera::get_h_offset );
|
||||
ObjectTypeDB::bind_method( _MD("set_v_offset","ofs"),&Camera::set_v_offset );
|
||||
ObjectTypeDB::bind_method( _MD("get_v_offset"),&Camera::get_v_offset );
|
||||
ObjectTypeDB::bind_method( _MD("set_visible_layers","mask"),&Camera::set_visible_layers );
|
||||
ObjectTypeDB::bind_method( _MD("get_visible_layers"),&Camera::get_visible_layers );
|
||||
ObjectTypeDB::bind_method( _MD("set_environment","env:Environment"),&Camera::set_environment );
|
||||
ObjectTypeDB::bind_method( _MD("get_environment:Environment"),&Camera::get_environment );
|
||||
ObjectTypeDB::bind_method( _MD("set_keep_aspect_mode","mode"),&Camera::set_keep_aspect_mode );
|
||||
ObjectTypeDB::bind_method( _MD("get_keep_aspect_mode"),&Camera::get_keep_aspect_mode );
|
||||
ObjectTypeDB::bind_method(_MD("project_ray_normal", "screen_point"), &Camera::project_ray_normal);
|
||||
ObjectTypeDB::bind_method(_MD("project_local_ray_normal", "screen_point"), &Camera::project_local_ray_normal);
|
||||
ObjectTypeDB::bind_method(_MD("project_ray_origin", "screen_point"), &Camera::project_ray_origin);
|
||||
ObjectTypeDB::bind_method(_MD("unproject_position", "world_point"), &Camera::unproject_position);
|
||||
ObjectTypeDB::bind_method(_MD("is_position_behind", "world_point"), &Camera::is_position_behind);
|
||||
ObjectTypeDB::bind_method(_MD("project_position", "screen_point"), &Camera::project_position);
|
||||
ObjectTypeDB::bind_method(_MD("set_perspective", "fov", "z_near", "z_far"), &Camera::set_perspective);
|
||||
ObjectTypeDB::bind_method(_MD("set_orthogonal", "size", "z_near", "z_far"), &Camera::set_orthogonal);
|
||||
ObjectTypeDB::bind_method(_MD("make_current"), &Camera::make_current);
|
||||
ObjectTypeDB::bind_method(_MD("clear_current"), &Camera::clear_current);
|
||||
ObjectTypeDB::bind_method(_MD("is_current"), &Camera::is_current);
|
||||
ObjectTypeDB::bind_method(_MD("get_camera_transform"), &Camera::get_camera_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_fov"), &Camera::get_fov);
|
||||
ObjectTypeDB::bind_method(_MD("get_size"), &Camera::get_size);
|
||||
ObjectTypeDB::bind_method(_MD("get_zfar"), &Camera::get_zfar);
|
||||
ObjectTypeDB::bind_method(_MD("get_znear"), &Camera::get_znear);
|
||||
ObjectTypeDB::bind_method(_MD("get_projection"), &Camera::get_projection);
|
||||
ObjectTypeDB::bind_method(_MD("set_h_offset", "ofs"), &Camera::set_h_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_h_offset"), &Camera::get_h_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_v_offset", "ofs"), &Camera::set_v_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_v_offset"), &Camera::get_v_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_visible_layers", "mask"), &Camera::set_visible_layers);
|
||||
ObjectTypeDB::bind_method(_MD("get_visible_layers"), &Camera::get_visible_layers);
|
||||
ObjectTypeDB::bind_method(_MD("set_environment", "env:Environment"), &Camera::set_environment);
|
||||
ObjectTypeDB::bind_method(_MD("get_environment:Environment"), &Camera::get_environment);
|
||||
ObjectTypeDB::bind_method(_MD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode);
|
||||
//ObjectTypeDB::bind_method( _MD("_camera_make_current"),&Camera::_camera_make_current );
|
||||
|
||||
BIND_CONSTANT( PROJECTION_PERSPECTIVE );
|
||||
BIND_CONSTANT( PROJECTION_ORTHOGONAL );
|
||||
|
||||
BIND_CONSTANT( KEEP_WIDTH );
|
||||
BIND_CONSTANT( KEEP_HEIGHT );
|
||||
BIND_CONSTANT(PROJECTION_PERSPECTIVE);
|
||||
BIND_CONSTANT(PROJECTION_ORTHOGONAL);
|
||||
|
||||
BIND_CONSTANT(KEEP_WIDTH);
|
||||
BIND_CONSTANT(KEEP_HEIGHT);
|
||||
}
|
||||
|
||||
float Camera::get_fov() const {
|
||||
|
|
@ -688,7 +642,6 @@ float Camera::get_zfar() const {
|
|||
return far;
|
||||
}
|
||||
|
||||
|
||||
Camera::Projection Camera::get_projection() const {
|
||||
|
||||
return mode;
|
||||
|
|
@ -696,37 +649,32 @@ Camera::Projection Camera::get_projection() const {
|
|||
|
||||
void Camera::set_visible_layers(uint32_t p_layers) {
|
||||
|
||||
layers=p_layers;
|
||||
VisualServer::get_singleton()->camera_set_visible_layers(camera,layers);
|
||||
layers = p_layers;
|
||||
VisualServer::get_singleton()->camera_set_visible_layers(camera, layers);
|
||||
}
|
||||
|
||||
uint32_t Camera::get_visible_layers() const{
|
||||
uint32_t Camera::get_visible_layers() const {
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
|
||||
Vector<Plane> Camera::get_frustum() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_world(),Vector<Plane>());
|
||||
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
|
||||
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
CameraMatrix cm;
|
||||
if (mode==PROJECTION_PERSPECTIVE)
|
||||
cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
if (mode == PROJECTION_PERSPECTIVE)
|
||||
cm.set_perspective(fov, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
else
|
||||
cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
|
||||
cm.set_orthogonal(size, viewport_size.get_aspect(), near, far, keep_aspect == KEEP_WIDTH);
|
||||
|
||||
return cm.get_projection_planes(get_camera_transform());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Camera::set_v_offset(float p_offset) {
|
||||
|
||||
v_offset=p_offset;
|
||||
v_offset = p_offset;
|
||||
_update_camera();
|
||||
}
|
||||
|
||||
|
|
@ -736,7 +684,7 @@ float Camera::get_v_offset() const {
|
|||
}
|
||||
|
||||
void Camera::set_h_offset(float p_offset) {
|
||||
h_offset=p_offset;
|
||||
h_offset = p_offset;
|
||||
_update_camera();
|
||||
}
|
||||
|
||||
|
|
@ -745,31 +693,26 @@ float Camera::get_h_offset() const {
|
|||
return h_offset;
|
||||
}
|
||||
|
||||
|
||||
Camera::Camera() {
|
||||
|
||||
camera = VisualServer::get_singleton()->camera_create();
|
||||
size=1;
|
||||
fov=0;
|
||||
near=0;
|
||||
far=0;
|
||||
current=false;
|
||||
force_change=false;
|
||||
mode=PROJECTION_PERSPECTIVE;
|
||||
set_perspective(60.0,0.1,100.0);
|
||||
keep_aspect=KEEP_HEIGHT;
|
||||
layers=0xfffff;
|
||||
v_offset=0;
|
||||
h_offset=0;
|
||||
VisualServer::get_singleton()->camera_set_visible_layers(camera,layers);
|
||||
size = 1;
|
||||
fov = 0;
|
||||
near = 0;
|
||||
far = 0;
|
||||
current = false;
|
||||
force_change = false;
|
||||
mode = PROJECTION_PERSPECTIVE;
|
||||
set_perspective(60.0, 0.1, 100.0);
|
||||
keep_aspect = KEEP_HEIGHT;
|
||||
layers = 0xfffff;
|
||||
v_offset = 0;
|
||||
h_offset = 0;
|
||||
VisualServer::get_singleton()->camera_set_visible_layers(camera, layers);
|
||||
//active=false;
|
||||
}
|
||||
|
||||
|
||||
Camera::~Camera() {
|
||||
|
||||
VisualServer::get_singleton()->free(camera);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/resources/environment.h"
|
||||
|
|
@ -38,7 +37,8 @@
|
|||
*/
|
||||
class Camera : public Spatial {
|
||||
|
||||
OBJ_TYPE( Camera, Spatial );
|
||||
OBJ_TYPE(Camera, Spatial);
|
||||
|
||||
public:
|
||||
enum Projection {
|
||||
|
||||
|
|
@ -52,7 +52,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
|
||||
bool force_change;
|
||||
bool current;
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ private:
|
|||
|
||||
float fov;
|
||||
float size;
|
||||
float near,far;
|
||||
float near, far;
|
||||
float v_offset;
|
||||
float h_offset;
|
||||
KeepAspect keep_aspect;
|
||||
|
|
@ -77,29 +76,27 @@ private:
|
|||
virtual bool _can_gizmo_scale() const;
|
||||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
|
||||
//void _camera_make_current(Node *p_camera);
|
||||
friend class Viewport;
|
||||
friend class Viewport;
|
||||
void _update_audio_listener_state();
|
||||
protected:
|
||||
|
||||
protected:
|
||||
void _update_camera();
|
||||
virtual void _request_camera_update();
|
||||
void _update_camera_mode();
|
||||
|
||||
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;
|
||||
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;
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
|
||||
NOTIFICATION_BECAME_CURRENT=50,
|
||||
NOTIFICATION_LOST_CURRENT=51
|
||||
NOTIFICATION_BECAME_CURRENT = 50,
|
||||
NOTIFICATION_LOST_CURRENT = 51
|
||||
};
|
||||
|
||||
void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far);
|
||||
|
|
@ -119,39 +116,35 @@ public:
|
|||
|
||||
virtual Transform get_camera_transform() const;
|
||||
|
||||
Vector3 project_ray_normal(const Point2& p_point) const;
|
||||
Vector3 project_ray_origin(const Point2& p_point) const;
|
||||
Vector3 project_local_ray_normal(const Point2& p_point) const;
|
||||
Point2 unproject_position(const Vector3& p_pos) const;
|
||||
bool is_position_behind(const Vector3& p_pos) const;
|
||||
Vector3 project_position(const Point2& p_point) const;
|
||||
Vector3 project_ray_normal(const Point2 &p_point) const;
|
||||
Vector3 project_ray_origin(const Point2 &p_point) const;
|
||||
Vector3 project_local_ray_normal(const Point2 &p_point) const;
|
||||
Point2 unproject_position(const Vector3 &p_pos) const;
|
||||
bool is_position_behind(const Vector3 &p_pos) const;
|
||||
Vector3 project_position(const Point2 &p_point) const;
|
||||
|
||||
void set_visible_layers(uint32_t p_layers);
|
||||
uint32_t get_visible_layers() const;
|
||||
|
||||
Vector<Plane> get_frustum() const;
|
||||
|
||||
void set_environment(const Ref<Environment>& p_environment);
|
||||
void set_environment(const Ref<Environment> &p_environment);
|
||||
Ref<Environment> get_environment() const;
|
||||
|
||||
void set_keep_aspect_mode(KeepAspect p_aspect);
|
||||
KeepAspect get_keep_aspect_mode() const;
|
||||
|
||||
|
||||
void set_v_offset(float p_offset);
|
||||
float get_v_offset() const;
|
||||
|
||||
void set_h_offset(float p_offset);
|
||||
float get_h_offset() const;
|
||||
|
||||
|
||||
Camera();
|
||||
~Camera();
|
||||
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST( Camera::Projection );
|
||||
VARIANT_ENUM_CAST( Camera::KeepAspect );
|
||||
VARIANT_ENUM_CAST(Camera::Projection);
|
||||
VARIANT_ENUM_CAST(Camera::KeepAspect);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ void CharacterCamera::_compute_camera() {
|
|||
|
||||
new_pos = character_pos + rel_n * l;
|
||||
|
||||
|
||||
#endif
|
||||
follow_pos=new_pos;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#ifndef CHARACTER_CAMERA_H
|
||||
#define CHARACTER_CAMERA_H
|
||||
|
||||
|
||||
#include "scene/3d/camera.h"
|
||||
#if 0
|
||||
class CharacterCamera : public Camera {
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "collision_object.h"
|
||||
#include "servers/physics_server.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "servers/physics_server.h"
|
||||
void CollisionObject::_update_shapes_from_children() {
|
||||
|
||||
shapes.clear();
|
||||
for(int i=0;i<get_child_count();i++) {
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
|
||||
Node* n = get_child(i);
|
||||
n->call("_add_to_collision_object",this);
|
||||
Node *n = get_child(i);
|
||||
n->call("_add_to_collision_object", this);
|
||||
}
|
||||
|
||||
_update_shapes();
|
||||
|
|
@ -43,31 +43,31 @@ void CollisionObject::_update_shapes_from_children() {
|
|||
|
||||
void CollisionObject::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
if (area)
|
||||
PhysicsServer::get_singleton()->area_set_transform(rid,get_global_transform());
|
||||
PhysicsServer::get_singleton()->area_set_transform(rid, get_global_transform());
|
||||
else
|
||||
PhysicsServer::get_singleton()->body_set_state(rid,PhysicsServer::BODY_STATE_TRANSFORM,get_global_transform());
|
||||
PhysicsServer::get_singleton()->body_set_state(rid, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
|
||||
|
||||
RID space = get_world()->get_space();
|
||||
if (area) {
|
||||
PhysicsServer::get_singleton()->area_set_space(rid,space);
|
||||
PhysicsServer::get_singleton()->area_set_space(rid, space);
|
||||
} else
|
||||
PhysicsServer::get_singleton()->body_set_space(rid,space);
|
||||
PhysicsServer::get_singleton()->body_set_space(rid, space);
|
||||
|
||||
_update_pickable();
|
||||
//get space
|
||||
//get space
|
||||
};
|
||||
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
if (area)
|
||||
PhysicsServer::get_singleton()->area_set_transform(rid,get_global_transform());
|
||||
PhysicsServer::get_singleton()->area_set_transform(rid, get_global_transform());
|
||||
else
|
||||
PhysicsServer::get_singleton()->body_set_state(rid,PhysicsServer::BODY_STATE_TRANSFORM,get_global_transform());
|
||||
PhysicsServer::get_singleton()->body_set_state(rid, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||
|
|
@ -78,9 +78,9 @@ void CollisionObject::_notification(int p_what) {
|
|||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
||||
if (area) {
|
||||
PhysicsServer::get_singleton()->area_set_space(rid,RID());
|
||||
PhysicsServer::get_singleton()->area_set_space(rid, RID());
|
||||
} else
|
||||
PhysicsServer::get_singleton()->body_set_space(rid,RID());
|
||||
PhysicsServer::get_singleton()->body_set_space(rid, RID());
|
||||
|
||||
} break;
|
||||
}
|
||||
|
|
@ -96,25 +96,24 @@ void CollisionObject::_update_shapes() {
|
|||
else
|
||||
PhysicsServer::get_singleton()->body_clear_shapes(rid);
|
||||
|
||||
for(int i=0;i<shapes.size();i++) {
|
||||
for (int i = 0; i < shapes.size(); i++) {
|
||||
|
||||
if (shapes[i].shape.is_null())
|
||||
continue;
|
||||
if (area)
|
||||
PhysicsServer::get_singleton()->area_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform);
|
||||
PhysicsServer::get_singleton()->area_add_shape(rid, shapes[i].shape->get_rid(), shapes[i].xform);
|
||||
else {
|
||||
PhysicsServer::get_singleton()->body_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform);
|
||||
PhysicsServer::get_singleton()->body_add_shape(rid, shapes[i].shape->get_rid(), shapes[i].xform);
|
||||
if (shapes[i].trigger)
|
||||
PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,i,shapes[i].trigger);
|
||||
PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid, i, shapes[i].trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CollisionObject::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String name = p_name;
|
||||
|
||||
bool CollisionObject::_set(const StringName& p_name, const Variant& p_value) {
|
||||
String name=p_name;
|
||||
|
||||
if (name=="shape_count") {
|
||||
if (name == "shape_count") {
|
||||
|
||||
shapes.resize(p_value);
|
||||
_update_shapes();
|
||||
|
|
@ -122,40 +121,37 @@ bool CollisionObject::_set(const StringName& p_name, const Variant& p_value) {
|
|||
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape")
|
||||
set_shape(idx,RefPtr(p_value));
|
||||
else if (what=="transform")
|
||||
set_shape_transform(idx,p_value);
|
||||
else if (what=="trigger")
|
||||
set_shape_as_trigger(idx,p_value);
|
||||
|
||||
int idx = name.get_slicec('/', 1).to_int();
|
||||
String what = name.get_slicec('/', 2);
|
||||
if (what == "shape")
|
||||
set_shape(idx, RefPtr(p_value));
|
||||
else if (what == "transform")
|
||||
set_shape_transform(idx, p_value);
|
||||
else if (what == "trigger")
|
||||
set_shape_as_trigger(idx, p_value);
|
||||
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool CollisionObject::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool CollisionObject::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
String name=p_name;
|
||||
String name = p_name;
|
||||
|
||||
if (name=="shape_count") {
|
||||
r_ret= shapes.size();
|
||||
if (name == "shape_count") {
|
||||
r_ret = shapes.size();
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape")
|
||||
r_ret= get_shape(idx);
|
||||
else if (what=="transform")
|
||||
r_ret= get_shape_transform(idx);
|
||||
else if (what=="trigger")
|
||||
r_ret= is_shape_set_as_trigger(idx);
|
||||
int idx = name.get_slicec('/', 1).to_int();
|
||||
String what = name.get_slicec('/', 2);
|
||||
if (what == "shape")
|
||||
r_ret = get_shape(idx);
|
||||
else if (what == "transform")
|
||||
r_ret = get_shape_transform(idx);
|
||||
else if (what == "trigger")
|
||||
r_ret = is_shape_set_as_trigger(idx);
|
||||
|
||||
} else
|
||||
return false;
|
||||
|
|
@ -163,26 +159,24 @@ bool CollisionObject::_get(const StringName& p_name,Variant &r_ret) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void CollisionObject::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
void CollisionObject::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
|
||||
for(int i=0;i<shapes.size();i++) {
|
||||
String path="shapes/"+itos(i)+"/";
|
||||
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "shape_count", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
|
||||
|
||||
for (int i = 0; i < shapes.size(); i++) {
|
||||
String path = "shapes/" + itos(i) + "/";
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, path + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
|
||||
p_list->push_back(PropertyInfo(Variant::TRANSFORM, path + "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, path + "trigger", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CollisionObject::_input_event(Node *p_camera, const InputEvent& p_input_event, const Vector3& p_pos, const Vector3& p_normal, int p_shape) {
|
||||
void CollisionObject::_input_event(Node *p_camera, const InputEvent &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
|
||||
|
||||
if (get_script_instance()) {
|
||||
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_camera,p_input_event,p_pos,p_normal,p_shape);
|
||||
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
|
||||
}
|
||||
emit_signal(SceneStringNames::get_singleton()->input_event,p_camera,p_input_event,p_pos,p_normal,p_shape);
|
||||
emit_signal(SceneStringNames::get_singleton()->input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
|
||||
}
|
||||
|
||||
void CollisionObject::_mouse_enter() {
|
||||
|
|
@ -193,14 +187,12 @@ void CollisionObject::_mouse_enter() {
|
|||
emit_signal(SceneStringNames::get_singleton()->mouse_enter);
|
||||
}
|
||||
|
||||
|
||||
void CollisionObject::_mouse_exit() {
|
||||
|
||||
if (get_script_instance()) {
|
||||
get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit);
|
||||
}
|
||||
emit_signal(SceneStringNames::get_singleton()->mouse_exit);
|
||||
|
||||
}
|
||||
|
||||
void CollisionObject::_update_pickable() {
|
||||
|
|
@ -208,16 +200,15 @@ void CollisionObject::_update_pickable() {
|
|||
return;
|
||||
bool pickable = ray_pickable && is_inside_tree() && is_visible();
|
||||
if (area)
|
||||
PhysicsServer::get_singleton()->area_set_ray_pickable(rid,pickable);
|
||||
PhysicsServer::get_singleton()->area_set_ray_pickable(rid, pickable);
|
||||
else
|
||||
PhysicsServer::get_singleton()->body_set_ray_pickable(rid,pickable);
|
||||
PhysicsServer::get_singleton()->body_set_ray_pickable(rid, pickable);
|
||||
}
|
||||
|
||||
void CollisionObject::set_ray_pickable(bool p_ray_pickable) {
|
||||
|
||||
ray_pickable=p_ray_pickable;
|
||||
ray_pickable = p_ray_pickable;
|
||||
_update_pickable();
|
||||
|
||||
}
|
||||
|
||||
bool CollisionObject::is_ray_pickable() const {
|
||||
|
|
@ -225,80 +216,74 @@ bool CollisionObject::is_ray_pickable() const {
|
|||
return ray_pickable;
|
||||
}
|
||||
|
||||
|
||||
void CollisionObject::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_shape","shape:Shape","transform"),&CollisionObject::add_shape,DEFVAL(Transform()));
|
||||
ObjectTypeDB::bind_method(_MD("get_shape_count"),&CollisionObject::get_shape_count);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape","shape_idx","shape:Shape"),&CollisionObject::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape_transform","shape_idx","transform"),&CollisionObject::set_shape_transform);
|
||||
// ObjectTypeDB::bind_method(_MD("set_shape_transform","shape_idx","transform"),&CollisionObject::set_shape_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape_as_trigger","shape_idx","enable"),&CollisionObject::set_shape_as_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("is_shape_set_as_trigger","shape_idx"),&CollisionObject::is_shape_set_as_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape:Shape","shape_idx"),&CollisionObject::get_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape_transform","shape_idx"),&CollisionObject::get_shape_transform);
|
||||
ObjectTypeDB::bind_method(_MD("remove_shape","shape_idx"),&CollisionObject::remove_shape);
|
||||
ObjectTypeDB::bind_method(_MD("clear_shapes"),&CollisionObject::clear_shapes);
|
||||
ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&CollisionObject::set_ray_pickable);
|
||||
ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&CollisionObject::is_ray_pickable);
|
||||
ObjectTypeDB::bind_method(_MD("set_capture_input_on_drag","enable"),&CollisionObject::set_capture_input_on_drag);
|
||||
ObjectTypeDB::bind_method(_MD("get_capture_input_on_drag"),&CollisionObject::get_capture_input_on_drag);
|
||||
ObjectTypeDB::bind_method(_MD("get_rid"),&CollisionObject::get_rid);
|
||||
BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
|
||||
ObjectTypeDB::bind_method(_MD("add_shape", "shape:Shape", "transform"), &CollisionObject::add_shape, DEFVAL(Transform()));
|
||||
ObjectTypeDB::bind_method(_MD("get_shape_count"), &CollisionObject::get_shape_count);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape", "shape_idx", "shape:Shape"), &CollisionObject::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape_transform", "shape_idx", "transform"), &CollisionObject::set_shape_transform);
|
||||
// ObjectTypeDB::bind_method(_MD("set_shape_transform","shape_idx","transform"),&CollisionObject::set_shape_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape_as_trigger", "shape_idx", "enable"), &CollisionObject::set_shape_as_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("is_shape_set_as_trigger", "shape_idx"), &CollisionObject::is_shape_set_as_trigger);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape:Shape", "shape_idx"), &CollisionObject::get_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape_transform", "shape_idx"), &CollisionObject::get_shape_transform);
|
||||
ObjectTypeDB::bind_method(_MD("remove_shape", "shape_idx"), &CollisionObject::remove_shape);
|
||||
ObjectTypeDB::bind_method(_MD("clear_shapes"), &CollisionObject::clear_shapes);
|
||||
ObjectTypeDB::bind_method(_MD("set_ray_pickable", "ray_pickable"), &CollisionObject::set_ray_pickable);
|
||||
ObjectTypeDB::bind_method(_MD("is_ray_pickable"), &CollisionObject::is_ray_pickable);
|
||||
ObjectTypeDB::bind_method(_MD("set_capture_input_on_drag", "enable"), &CollisionObject::set_capture_input_on_drag);
|
||||
ObjectTypeDB::bind_method(_MD("get_capture_input_on_drag"), &CollisionObject::get_capture_input_on_drag);
|
||||
ObjectTypeDB::bind_method(_MD("get_rid"), &CollisionObject::get_rid);
|
||||
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
||||
|
||||
ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
|
||||
ADD_SIGNAL( MethodInfo("mouse_enter"));
|
||||
ADD_SIGNAL( MethodInfo("mouse_exit"));
|
||||
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
||||
ADD_SIGNAL(MethodInfo("mouse_enter"));
|
||||
ADD_SIGNAL(MethodInfo("mouse_exit"));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"input/ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"input/capture_on_drag"),_SCS("set_capture_input_on_drag"),_SCS("get_capture_input_on_drag"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input/ray_pickable"), _SCS("set_ray_pickable"), _SCS("is_ray_pickable"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input/capture_on_drag"), _SCS("set_capture_input_on_drag"), _SCS("get_capture_input_on_drag"));
|
||||
}
|
||||
|
||||
|
||||
void CollisionObject::add_shape(const Ref<Shape>& p_shape, const Transform& p_transform) {
|
||||
void CollisionObject::add_shape(const Ref<Shape> &p_shape, const Transform &p_transform) {
|
||||
|
||||
ShapeData sdata;
|
||||
sdata.shape=p_shape;
|
||||
sdata.xform=p_transform;
|
||||
sdata.shape = p_shape;
|
||||
sdata.xform = p_transform;
|
||||
shapes.push_back(sdata);
|
||||
_update_shapes();
|
||||
|
||||
}
|
||||
int CollisionObject::get_shape_count() const {
|
||||
|
||||
return shapes.size();
|
||||
|
||||
}
|
||||
void CollisionObject::set_shape(int p_shape_idx, const Ref<Shape>& p_shape) {
|
||||
void CollisionObject::set_shape(int p_shape_idx, const Ref<Shape> &p_shape) {
|
||||
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
shapes[p_shape_idx].shape=p_shape;
|
||||
ERR_FAIL_INDEX(p_shape_idx, shapes.size());
|
||||
shapes[p_shape_idx].shape = p_shape;
|
||||
_update_shapes();
|
||||
}
|
||||
|
||||
void CollisionObject::set_shape_transform(int p_shape_idx, const Transform& p_transform) {
|
||||
void CollisionObject::set_shape_transform(int p_shape_idx, const Transform &p_transform) {
|
||||
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
shapes[p_shape_idx].xform=p_transform;
|
||||
ERR_FAIL_INDEX(p_shape_idx, shapes.size());
|
||||
shapes[p_shape_idx].xform = p_transform;
|
||||
|
||||
_update_shapes();
|
||||
}
|
||||
|
||||
Ref<Shape> CollisionObject::get_shape(int p_shape_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_shape_idx,shapes.size(),Ref<Shape>());
|
||||
ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), Ref<Shape>());
|
||||
return shapes[p_shape_idx].shape;
|
||||
|
||||
}
|
||||
Transform CollisionObject::get_shape_transform(int p_shape_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_shape_idx,shapes.size(),Transform());
|
||||
ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), Transform());
|
||||
return shapes[p_shape_idx].xform;
|
||||
|
||||
}
|
||||
void CollisionObject::remove_shape(int p_shape_idx) {
|
||||
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
ERR_FAIL_INDEX(p_shape_idx, shapes.size());
|
||||
shapes.remove(p_shape_idx);
|
||||
|
||||
_update_shapes();
|
||||
|
|
@ -313,40 +298,37 @@ void CollisionObject::clear_shapes() {
|
|||
|
||||
void CollisionObject::set_shape_as_trigger(int p_shape_idx, bool p_trigger) {
|
||||
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
shapes[p_shape_idx].trigger=p_trigger;
|
||||
if (!area && rid.is_valid()) {
|
||||
ERR_FAIL_INDEX(p_shape_idx, shapes.size());
|
||||
shapes[p_shape_idx].trigger = p_trigger;
|
||||
if (!area && rid.is_valid()) {
|
||||
|
||||
PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,p_shape_idx,p_trigger);
|
||||
|
||||
}
|
||||
PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid, p_shape_idx, p_trigger);
|
||||
}
|
||||
}
|
||||
|
||||
bool CollisionObject::is_shape_set_as_trigger(int p_shape_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_shape_idx,shapes.size(),false);
|
||||
return shapes[p_shape_idx].trigger;
|
||||
ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), false);
|
||||
return shapes[p_shape_idx].trigger;
|
||||
}
|
||||
|
||||
CollisionObject::CollisionObject(RID p_rid, bool p_area) {
|
||||
|
||||
rid=p_rid;
|
||||
area=p_area;
|
||||
capture_input_on_drag=false;
|
||||
ray_pickable=true;
|
||||
rid = p_rid;
|
||||
area = p_area;
|
||||
capture_input_on_drag = false;
|
||||
ray_pickable = true;
|
||||
if (p_area) {
|
||||
PhysicsServer::get_singleton()->area_attach_object_instance_ID(rid,get_instance_ID());
|
||||
PhysicsServer::get_singleton()->area_attach_object_instance_ID(rid, get_instance_ID());
|
||||
} else {
|
||||
PhysicsServer::get_singleton()->body_attach_object_instance_ID(rid,get_instance_ID());
|
||||
PhysicsServer::get_singleton()->body_attach_object_instance_ID(rid, get_instance_ID());
|
||||
}
|
||||
// set_transform_notify(true);
|
||||
|
||||
// set_transform_notify(true);
|
||||
}
|
||||
|
||||
void CollisionObject::set_capture_input_on_drag(bool p_capture) {
|
||||
|
||||
capture_input_on_drag=p_capture;
|
||||
|
||||
capture_input_on_drag = p_capture;
|
||||
}
|
||||
|
||||
bool CollisionObject::get_capture_input_on_drag() const {
|
||||
|
|
@ -354,12 +336,10 @@ bool CollisionObject::get_capture_input_on_drag() const {
|
|||
return capture_input_on_drag;
|
||||
}
|
||||
|
||||
|
||||
CollisionObject::CollisionObject() {
|
||||
|
||||
|
||||
capture_input_on_drag=false;
|
||||
ray_pickable=true;
|
||||
capture_input_on_drag = false;
|
||||
ray_pickable = true;
|
||||
|
||||
//owner=
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
class CollisionObject : public Spatial {
|
||||
|
||||
OBJ_TYPE( CollisionObject, Spatial );
|
||||
OBJ_TYPE(CollisionObject, Spatial);
|
||||
|
||||
bool area;
|
||||
RID rid;
|
||||
|
|
@ -42,12 +42,11 @@ class CollisionObject : public Spatial {
|
|||
struct ShapeData {
|
||||
Transform xform;
|
||||
Ref<Shape> shape;
|
||||
bool trigger;
|
||||
|
||||
ShapeData() {
|
||||
trigger=false;
|
||||
}
|
||||
bool trigger;
|
||||
|
||||
ShapeData() {
|
||||
trigger = false;
|
||||
}
|
||||
};
|
||||
|
||||
bool capture_input_on_drag;
|
||||
|
|
@ -57,30 +56,28 @@ class CollisionObject : public Spatial {
|
|||
void _update_pickable();
|
||||
void _update_shapes();
|
||||
|
||||
friend class CollisionShape;
|
||||
friend class CollisionPolygon;
|
||||
friend class CollisionShape;
|
||||
friend class CollisionPolygon;
|
||||
void _update_shapes_from_children();
|
||||
protected:
|
||||
|
||||
protected:
|
||||
CollisionObject(RID p_rid, bool p_area);
|
||||
|
||||
void _notification(int p_what);
|
||||
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;
|
||||
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 void _bind_methods();
|
||||
friend class Viewport;
|
||||
virtual void _input_event(Node* p_camera,const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape);
|
||||
friend class Viewport;
|
||||
virtual void _input_event(Node *p_camera, const InputEvent &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
|
||||
virtual void _mouse_enter();
|
||||
virtual void _mouse_exit();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void add_shape(const Ref<Shape>& p_shape, const Transform& p_transform=Transform());
|
||||
void add_shape(const Ref<Shape> &p_shape, const Transform &p_transform = Transform());
|
||||
int get_shape_count() const;
|
||||
void set_shape(int p_shape_idx, const Ref<Shape>& p_shape);
|
||||
void set_shape_transform(int p_shape_idx, const Transform& p_transform);
|
||||
void set_shape(int p_shape_idx, const Ref<Shape> &p_shape);
|
||||
void set_shape_transform(int p_shape_idx, const Transform &p_transform);
|
||||
Ref<Shape> get_shape(int p_shape_idx) const;
|
||||
Transform get_shape_transform(int p_shape_idx) const;
|
||||
void remove_shape(int p_shape_idx);
|
||||
|
|
@ -94,7 +91,6 @@ public:
|
|||
void set_capture_input_on_drag(bool p_capture);
|
||||
bool get_capture_input_on_drag() const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ RID get_rid() const { return rid; }
|
||||
|
||||
CollisionObject();
|
||||
|
|
|
|||
|
|
@ -40,44 +40,43 @@ void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
|
|||
CollisionObject *co = p_obj->cast_to<CollisionObject>();
|
||||
ERR_FAIL_COND(!co);
|
||||
|
||||
if (polygon.size()==0)
|
||||
if (polygon.size() == 0)
|
||||
return;
|
||||
|
||||
bool solids=build_mode==BUILD_SOLIDS;
|
||||
bool solids = build_mode == BUILD_SOLIDS;
|
||||
|
||||
Vector< Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
|
||||
if (decomp.size()==0)
|
||||
Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
|
||||
if (decomp.size() == 0)
|
||||
return;
|
||||
|
||||
if (true || solids) {
|
||||
|
||||
//here comes the sun, lalalala
|
||||
//decompose concave into multiple convex polygons and add them
|
||||
shape_from=co->get_shape_count();
|
||||
for(int i=0;i<decomp.size();i++) {
|
||||
Ref<ConvexPolygonShape> convex = memnew( ConvexPolygonShape );
|
||||
shape_from = co->get_shape_count();
|
||||
for (int i = 0; i < decomp.size(); i++) {
|
||||
Ref<ConvexPolygonShape> convex = memnew(ConvexPolygonShape);
|
||||
DVector<Vector3> cp;
|
||||
int cs = decomp[i].size();
|
||||
cp.resize(cs*2);
|
||||
cp.resize(cs * 2);
|
||||
{
|
||||
DVector<Vector3>::Write w = cp.write();
|
||||
int idx=0;
|
||||
for(int j=0;j<cs;j++) {
|
||||
int idx = 0;
|
||||
for (int j = 0; j < cs; j++) {
|
||||
|
||||
Vector2 d = decomp[i][j];
|
||||
w[idx++]=Vector3(d.x,d.y,depth*0.5);
|
||||
w[idx++]=Vector3(d.x,d.y,-depth*0.5);
|
||||
w[idx++] = Vector3(d.x, d.y, depth * 0.5);
|
||||
w[idx++] = Vector3(d.x, d.y, -depth * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
convex->set_points(cp);
|
||||
co->add_shape(convex,get_transform());
|
||||
|
||||
co->add_shape(convex, get_transform());
|
||||
}
|
||||
shape_to=co->get_shape_count()-1;
|
||||
if (shape_to<shape_from) {
|
||||
shape_from=-1;
|
||||
shape_to=-1;
|
||||
shape_to = co->get_shape_count() - 1;
|
||||
if (shape_to < shape_from) {
|
||||
shape_from = -1;
|
||||
shape_to = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -100,9 +99,7 @@ void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
//co->add_shape(shape,get_transform());
|
||||
|
||||
}
|
||||
|
||||
void CollisionPolygon::_update_parent() {
|
||||
|
|
@ -119,29 +116,28 @@ void CollisionPolygon::_update_parent() {
|
|||
co->_update_shapes_from_children();
|
||||
}
|
||||
|
||||
void CollisionPolygon::_set_shape_range(const Vector2& p_range) {
|
||||
void CollisionPolygon::_set_shape_range(const Vector2 &p_range) {
|
||||
|
||||
shape_from=p_range.x;
|
||||
shape_to=p_range.y;
|
||||
shape_from = p_range.x;
|
||||
shape_to = p_range.y;
|
||||
}
|
||||
|
||||
Vector2 CollisionPolygon::_get_shape_range() const {
|
||||
|
||||
return Vector2(shape_from,shape_to);
|
||||
return Vector2(shape_from, shape_to);
|
||||
}
|
||||
|
||||
void CollisionPolygon::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
can_update_body=get_tree()->is_editor_hint();
|
||||
can_update_body = get_tree()->is_editor_hint();
|
||||
set_notify_local_transform(!can_update_body);
|
||||
|
||||
//indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
can_update_body=false;
|
||||
can_update_body = false;
|
||||
set_notify_local_transform(false);
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
|
@ -154,12 +150,12 @@ void CollisionPolygon::_notification(int p_what) {
|
|||
|
||||
} break;
|
||||
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
|
||||
if (!can_update_body && shape_from>=0 && shape_to>=0) {
|
||||
if (!can_update_body && shape_from >= 0 && shape_to >= 0) {
|
||||
|
||||
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
|
||||
if (co) {
|
||||
for(int i=shape_from;i<=shape_to;i++) {
|
||||
co->set_shape_transform(i,get_transform());
|
||||
for (int i = shape_from; i <= shape_to; i++) {
|
||||
co->set_shape_transform(i, get_transform());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,31 +186,29 @@ void CollisionPolygon::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
void CollisionPolygon::set_polygon(const Vector<Point2>& p_polygon) {
|
||||
void CollisionPolygon::set_polygon(const Vector<Point2> &p_polygon) {
|
||||
|
||||
polygon=p_polygon;
|
||||
polygon = p_polygon;
|
||||
if (can_update_body) {
|
||||
|
||||
for(int i=0;i<polygon.size();i++) {
|
||||
for (int i = 0; i < polygon.size(); i++) {
|
||||
|
||||
Vector3 p1(polygon[i].x,polygon[i].y,depth*0.5);
|
||||
Vector3 p1(polygon[i].x, polygon[i].y, depth * 0.5);
|
||||
|
||||
if (i==0)
|
||||
aabb=AABB(p1,Vector3());
|
||||
if (i == 0)
|
||||
aabb = AABB(p1, Vector3());
|
||||
else
|
||||
aabb.expand_to(p1);
|
||||
|
||||
Vector3 p2(polygon[i].x,polygon[i].y,-depth*0.5);
|
||||
Vector3 p2(polygon[i].x, polygon[i].y, -depth * 0.5);
|
||||
aabb.expand_to(p2);
|
||||
|
||||
|
||||
}
|
||||
if (aabb==AABB()) {
|
||||
if (aabb == AABB()) {
|
||||
|
||||
aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
|
||||
aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
} else {
|
||||
aabb.pos-=aabb.size*0.3;
|
||||
aabb.size+=aabb.size*0.6;
|
||||
aabb.pos -= aabb.size * 0.3;
|
||||
aabb.size += aabb.size * 0.6;
|
||||
}
|
||||
_update_parent();
|
||||
}
|
||||
|
|
@ -228,14 +222,14 @@ Vector<Point2> CollisionPolygon::get_polygon() const {
|
|||
|
||||
void CollisionPolygon::set_build_mode(BuildMode p_mode) {
|
||||
|
||||
ERR_FAIL_INDEX(p_mode,2);
|
||||
build_mode=p_mode;
|
||||
ERR_FAIL_INDEX(p_mode, 2);
|
||||
build_mode = p_mode;
|
||||
if (!can_update_body)
|
||||
return;
|
||||
_update_parent();
|
||||
}
|
||||
|
||||
CollisionPolygon::BuildMode CollisionPolygon::get_build_mode() const{
|
||||
CollisionPolygon::BuildMode CollisionPolygon::get_build_mode() const {
|
||||
|
||||
return build_mode;
|
||||
}
|
||||
|
|
@ -247,7 +241,7 @@ AABB CollisionPolygon::get_item_rect() const {
|
|||
|
||||
void CollisionPolygon::set_depth(float p_depth) {
|
||||
|
||||
depth=p_depth;
|
||||
depth = p_depth;
|
||||
if (!can_update_body)
|
||||
return;
|
||||
_update_parent();
|
||||
|
|
@ -267,7 +261,6 @@ String CollisionPolygon::get_configuration_warning() const {
|
|||
|
||||
if (polygon.empty()) {
|
||||
return TTR("An empty CollisionPolygon has no effect on collision.");
|
||||
|
||||
}
|
||||
|
||||
return String();
|
||||
|
|
@ -275,37 +268,36 @@ String CollisionPolygon::get_configuration_warning() const {
|
|||
|
||||
void CollisionPolygon::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"),&CollisionPolygon::_add_to_collision_object);
|
||||
ObjectTypeDB::bind_method(_MD("_add_to_collision_object"), &CollisionPolygon::_add_to_collision_object);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_build_mode","build_mode"),&CollisionPolygon::set_build_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_build_mode"),&CollisionPolygon::get_build_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_build_mode", "build_mode"), &CollisionPolygon::set_build_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_build_mode"), &CollisionPolygon::get_build_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_depth","depth"),&CollisionPolygon::set_depth);
|
||||
ObjectTypeDB::bind_method(_MD("get_depth"),&CollisionPolygon::get_depth);
|
||||
ObjectTypeDB::bind_method(_MD("set_depth", "depth"), &CollisionPolygon::set_depth);
|
||||
ObjectTypeDB::bind_method(_MD("get_depth"), &CollisionPolygon::get_depth);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&CollisionPolygon::set_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon"),&CollisionPolygon::get_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("set_polygon", "polygon"), &CollisionPolygon::set_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon"), &CollisionPolygon::get_polygon);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_shape_range","shape_range"),&CollisionPolygon::_set_shape_range);
|
||||
ObjectTypeDB::bind_method(_MD("_get_shape_range"),&CollisionPolygon::_get_shape_range);
|
||||
ObjectTypeDB::bind_method(_MD("_set_shape_range", "shape_range"), &CollisionPolygon::_set_shape_range);
|
||||
ObjectTypeDB::bind_method(_MD("_get_shape_range"), &CollisionPolygon::_get_shape_range);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_first_shape"),&CollisionPolygon::get_collision_object_first_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_last_shape"),&CollisionPolygon::get_collision_object_last_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_first_shape"), &CollisionPolygon::get_collision_object_first_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_object_last_shape"), &CollisionPolygon::get_collision_object_last_shape);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"build_mode",PROPERTY_HINT_ENUM,"Solids,Triangles"),_SCS("set_build_mode"),_SCS("get_build_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"depth"),_SCS("set_depth"),_SCS("get_depth"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"shape_range",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_shape_range"),_SCS("_get_shape_range"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Triangles"), _SCS("set_build_mode"), _SCS("get_build_mode"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth"), _SCS("set_depth"), _SCS("get_depth"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2_ARRAY, "polygon"), _SCS("set_polygon"), _SCS("get_polygon"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shape_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), _SCS("_set_shape_range"), _SCS("_get_shape_range"));
|
||||
}
|
||||
|
||||
CollisionPolygon::CollisionPolygon() {
|
||||
|
||||
shape_from=-1;
|
||||
shape_to=-1;
|
||||
can_update_body=false;
|
||||
|
||||
aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
|
||||
build_mode=BUILD_SOLIDS;
|
||||
depth=1.0;
|
||||
shape_from = -1;
|
||||
shape_to = -1;
|
||||
can_update_body = false;
|
||||
|
||||
aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
build_mode = BUILD_SOLIDS;
|
||||
depth = 1.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,27 +32,22 @@
|
|||
#include "scene/3d/spatial.h"
|
||||
#include "scene/resources/shape.h"
|
||||
|
||||
|
||||
|
||||
class CollisionPolygon : public Spatial {
|
||||
|
||||
OBJ_TYPE(CollisionPolygon,Spatial);
|
||||
public:
|
||||
OBJ_TYPE(CollisionPolygon, Spatial);
|
||||
|
||||
public:
|
||||
enum BuildMode {
|
||||
BUILD_SOLIDS,
|
||||
BUILD_TRIANGLES,
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
float depth;
|
||||
AABB aabb;
|
||||
BuildMode build_mode;
|
||||
Vector<Point2> polygon;
|
||||
|
||||
|
||||
void _add_to_collision_object(Object *p_obj);
|
||||
void _update_parent();
|
||||
|
||||
|
|
@ -60,22 +55,21 @@ protected:
|
|||
int shape_from;
|
||||
int shape_to;
|
||||
|
||||
void _set_shape_range(const Vector2& p_range);
|
||||
void _set_shape_range(const Vector2 &p_range);
|
||||
Vector2 _get_shape_range() const;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_build_mode(BuildMode p_mode);
|
||||
BuildMode get_build_mode() const;
|
||||
|
||||
void set_depth(float p_depth);
|
||||
float get_depth() const;
|
||||
|
||||
void set_polygon(const Vector<Point2>& p_polygon);
|
||||
void set_polygon(const Vector<Point2> &p_polygon);
|
||||
Vector<Point2> get_polygon() const;
|
||||
|
||||
virtual AABB get_item_rect() const;
|
||||
|
|
@ -88,5 +82,5 @@ public:
|
|||
CollisionPolygon();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( CollisionPolygon::BuildMode );
|
||||
VARIANT_ENUM_CAST(CollisionPolygon::BuildMode);
|
||||
#endif // COLLISION_POLYGON_H
|
||||
|
|
|
|||
|
|
@ -28,68 +28,60 @@
|
|||
/*************************************************************************/
|
||||
#include "immediate_geometry.h"
|
||||
|
||||
void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture) {
|
||||
|
||||
void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture) {
|
||||
|
||||
VS::get_singleton()->immediate_begin(im,(VS::PrimitiveType)p_primitive,p_texture.is_valid()?p_texture->get_rid():RID());
|
||||
VS::get_singleton()->immediate_begin(im, (VS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
|
||||
if (p_texture.is_valid())
|
||||
cached_textures.push_back(p_texture);
|
||||
|
||||
}
|
||||
|
||||
void ImmediateGeometry::set_normal(const Vector3& p_normal){
|
||||
void ImmediateGeometry::set_normal(const Vector3 &p_normal) {
|
||||
|
||||
VS::get_singleton()->immediate_normal(im,p_normal);
|
||||
VS::get_singleton()->immediate_normal(im, p_normal);
|
||||
}
|
||||
|
||||
void ImmediateGeometry::set_tangent(const Plane& p_tangent){
|
||||
|
||||
VS::get_singleton()->immediate_tangent(im,p_tangent);
|
||||
void ImmediateGeometry::set_tangent(const Plane &p_tangent) {
|
||||
|
||||
VS::get_singleton()->immediate_tangent(im, p_tangent);
|
||||
}
|
||||
|
||||
void ImmediateGeometry::set_color(const Color& p_color){
|
||||
|
||||
VS::get_singleton()->immediate_color(im,p_color);
|
||||
void ImmediateGeometry::set_color(const Color &p_color) {
|
||||
|
||||
VS::get_singleton()->immediate_color(im, p_color);
|
||||
}
|
||||
|
||||
void ImmediateGeometry::set_uv(const Vector2& p_uv){
|
||||
|
||||
VS::get_singleton()->immediate_uv(im,p_uv);
|
||||
void ImmediateGeometry::set_uv(const Vector2 &p_uv) {
|
||||
|
||||
VS::get_singleton()->immediate_uv(im, p_uv);
|
||||
}
|
||||
|
||||
void ImmediateGeometry::set_uv2(const Vector2& p_uv2){
|
||||
|
||||
VS::get_singleton()->immediate_uv2(im,p_uv2);
|
||||
void ImmediateGeometry::set_uv2(const Vector2 &p_uv2) {
|
||||
|
||||
VS::get_singleton()->immediate_uv2(im, p_uv2);
|
||||
}
|
||||
|
||||
void ImmediateGeometry::add_vertex(const Vector3& p_vertex){
|
||||
void ImmediateGeometry::add_vertex(const Vector3 &p_vertex) {
|
||||
|
||||
VS::get_singleton()->immediate_vertex(im,p_vertex);
|
||||
VS::get_singleton()->immediate_vertex(im, p_vertex);
|
||||
if (empty) {
|
||||
aabb.pos=p_vertex;
|
||||
aabb.size=Vector3();
|
||||
empty=false;
|
||||
aabb.pos = p_vertex;
|
||||
aabb.size = Vector3();
|
||||
empty = false;
|
||||
} else {
|
||||
aabb.expand_to(p_vertex);
|
||||
}
|
||||
}
|
||||
|
||||
void ImmediateGeometry::end(){
|
||||
void ImmediateGeometry::end() {
|
||||
|
||||
VS::get_singleton()->immediate_end(im);
|
||||
|
||||
}
|
||||
|
||||
void ImmediateGeometry::clear(){
|
||||
void ImmediateGeometry::clear() {
|
||||
|
||||
VS::get_singleton()->immediate_clear(im);
|
||||
empty=true;
|
||||
empty = true;
|
||||
cached_textures.clear();
|
||||
|
||||
}
|
||||
|
||||
AABB ImmediateGeometry::get_aabb() const {
|
||||
|
|
@ -101,44 +93,41 @@ DVector<Face3> ImmediateGeometry::get_faces(uint32_t p_usage_flags) const {
|
|||
return DVector<Face3>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
|
||||
|
||||
for(int i = 1; i <= p_lats; i++) {
|
||||
double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats);
|
||||
double z0 = Math::sin(lat0);
|
||||
double zr0 = Math::cos(lat0);
|
||||
for (int i = 1; i <= p_lats; i++) {
|
||||
double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
|
||||
double z0 = Math::sin(lat0);
|
||||
double zr0 = Math::cos(lat0);
|
||||
|
||||
double lat1 = Math_PI * (-0.5 + (double) i / p_lats);
|
||||
double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
|
||||
double z1 = Math::sin(lat1);
|
||||
double zr1 = Math::cos(lat1);
|
||||
|
||||
for(int j = p_lons; j >= 1; j--) {
|
||||
for (int j = p_lons; j >= 1; j--) {
|
||||
|
||||
double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons;
|
||||
double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
|
||||
double x0 = Math::cos(lng0);
|
||||
double y0 = Math::sin(lng0);
|
||||
|
||||
double lng1 = 2 * Math_PI * (double) (j) / p_lons;
|
||||
double lng1 = 2 * Math_PI * (double)(j) / p_lons;
|
||||
double x1 = Math::cos(lng1);
|
||||
double y1 = Math::sin(lng1);
|
||||
|
||||
|
||||
Vector3 v[4]={
|
||||
Vector3(x1 * zr0, z0, y1 *zr0),
|
||||
Vector3(x1 * zr1, z1, y1 *zr1),
|
||||
Vector3(x0 * zr1, z1, y0 *zr1),
|
||||
Vector3(x0 * zr0, z0, y0 *zr0)
|
||||
Vector3 v[4] = {
|
||||
Vector3(x1 * zr0, z0, y1 * zr0),
|
||||
Vector3(x1 * zr1, z1, y1 * zr1),
|
||||
Vector3(x0 * zr1, z1, y0 * zr1),
|
||||
Vector3(x0 * zr0, z0, y0 * zr0)
|
||||
};
|
||||
|
||||
#define ADD_POINT(m_idx)\
|
||||
if (p_add_uv) {\
|
||||
set_uv(Vector2(Math::atan2(v[m_idx].x,v[m_idx].z)/Math_PI * 0.5+0.5,v[m_idx].y*0.5+0.5));\
|
||||
set_tangent(Plane(Vector3(-v[m_idx].z,v[m_idx].y,v[m_idx].x),1)); \
|
||||
}\
|
||||
set_normal(v[m_idx]);\
|
||||
add_vertex(v[m_idx]*p_radius);
|
||||
#define ADD_POINT(m_idx) \
|
||||
if (p_add_uv) { \
|
||||
set_uv(Vector2(Math::atan2(v[m_idx].x, v[m_idx].z) / Math_PI * 0.5 + 0.5, v[m_idx].y * 0.5 + 0.5)); \
|
||||
set_tangent(Plane(Vector3(-v[m_idx].z, v[m_idx].y, v[m_idx].x), 1)); \
|
||||
} \
|
||||
set_normal(v[m_idx]); \
|
||||
add_vertex(v[m_idx] * p_radius);
|
||||
|
||||
ADD_POINT(0);
|
||||
ADD_POINT(1);
|
||||
|
|
@ -149,37 +138,30 @@ void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool
|
|||
ADD_POINT(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ImmediateGeometry::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("begin","primitive","texture:Texture"),&ImmediateGeometry::begin,DEFVAL(Ref<Texture>()));
|
||||
ObjectTypeDB::bind_method(_MD("set_normal","normal"),&ImmediateGeometry::set_normal);
|
||||
ObjectTypeDB::bind_method(_MD("set_tangent","tangent"),&ImmediateGeometry::set_tangent);
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color"),&ImmediateGeometry::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("set_uv","uv"),&ImmediateGeometry::set_uv);
|
||||
ObjectTypeDB::bind_method(_MD("set_uv2","uv"),&ImmediateGeometry::set_uv2);
|
||||
ObjectTypeDB::bind_method(_MD("add_vertex","pos"),&ImmediateGeometry::add_vertex);
|
||||
ObjectTypeDB::bind_method(_MD("add_sphere","lats","lons","radius","add_uv"),&ImmediateGeometry::add_sphere,DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("end"),&ImmediateGeometry::end);
|
||||
ObjectTypeDB::bind_method(_MD("clear"),&ImmediateGeometry::clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("begin", "primitive", "texture:Texture"), &ImmediateGeometry::begin, DEFVAL(Ref<Texture>()));
|
||||
ObjectTypeDB::bind_method(_MD("set_normal", "normal"), &ImmediateGeometry::set_normal);
|
||||
ObjectTypeDB::bind_method(_MD("set_tangent", "tangent"), &ImmediateGeometry::set_tangent);
|
||||
ObjectTypeDB::bind_method(_MD("set_color", "color"), &ImmediateGeometry::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("set_uv", "uv"), &ImmediateGeometry::set_uv);
|
||||
ObjectTypeDB::bind_method(_MD("set_uv2", "uv"), &ImmediateGeometry::set_uv2);
|
||||
ObjectTypeDB::bind_method(_MD("add_vertex", "pos"), &ImmediateGeometry::add_vertex);
|
||||
ObjectTypeDB::bind_method(_MD("add_sphere", "lats", "lons", "radius", "add_uv"), &ImmediateGeometry::add_sphere, DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("end"), &ImmediateGeometry::end);
|
||||
ObjectTypeDB::bind_method(_MD("clear"), &ImmediateGeometry::clear);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ImmediateGeometry::ImmediateGeometry() {
|
||||
|
||||
im = VisualServer::get_singleton()->immediate_create();
|
||||
set_base(im);
|
||||
empty=true;
|
||||
|
||||
empty = true;
|
||||
}
|
||||
|
||||
|
||||
ImmediateGeometry::~ImmediateGeometry() {
|
||||
|
||||
VisualServer::get_singleton()->free(im);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@
|
|||
|
||||
class ImmediateGeometry : public GeometryInstance {
|
||||
|
||||
OBJ_TYPE(ImmediateGeometry,GeometryInstance);
|
||||
|
||||
OBJ_TYPE(ImmediateGeometry, GeometryInstance);
|
||||
|
||||
RID im;
|
||||
//a list of texures drawn need to be kept, to avoid references
|
||||
|
|
@ -43,28 +42,24 @@ class ImmediateGeometry : public GeometryInstance {
|
|||
List<Ref<Texture> > cached_textures;
|
||||
bool empty;
|
||||
AABB aabb;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture = Ref<Texture>());
|
||||
void set_normal(const Vector3 &p_normal);
|
||||
void set_tangent(const Plane &p_tangent);
|
||||
void set_color(const Color &p_color);
|
||||
void set_uv(const Vector2 &tex_uv);
|
||||
void set_uv2(const Vector2 &tex_uv);
|
||||
|
||||
|
||||
void begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& p_texture=Ref<Texture>());
|
||||
void set_normal(const Vector3& p_normal);
|
||||
void set_tangent(const Plane& p_tangent);
|
||||
void set_color(const Color& p_color);
|
||||
void set_uv(const Vector2& tex_uv);
|
||||
void set_uv2(const Vector2& tex_uv);
|
||||
|
||||
void add_vertex(const Vector3& p_vertex);
|
||||
void add_vertex(const Vector3 &p_vertex);
|
||||
|
||||
void end();
|
||||
void clear();
|
||||
|
||||
|
||||
void add_sphere(int p_lats,int p_lons,float p_radius,bool p_add_uv=true);
|
||||
|
||||
|
||||
void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true);
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@
|
|||
/*************************************************************************/
|
||||
#include "interpolated_camera.h"
|
||||
|
||||
|
||||
void InterpolatedCamera::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
if (get_tree()->is_editor_hint() && enabled)
|
||||
|
|
@ -48,32 +47,30 @@ void InterpolatedCamera::_notification(int p_what) {
|
|||
if (!node)
|
||||
break;
|
||||
|
||||
float delta = speed*get_process_delta_time();
|
||||
float delta = speed * get_process_delta_time();
|
||||
Transform target_xform = node->get_global_transform();
|
||||
Transform local_transform = get_global_transform();
|
||||
local_transform = local_transform.interpolate_with(target_xform,delta);
|
||||
local_transform = local_transform.interpolate_with(target_xform, delta);
|
||||
set_global_transform(local_transform);
|
||||
|
||||
if (node->cast_to<Camera>()) {
|
||||
Camera *cam = node->cast_to<Camera>();
|
||||
if (cam->get_projection()==get_projection()) {
|
||||
if (cam->get_projection() == get_projection()) {
|
||||
|
||||
float new_near = Math::lerp(get_znear(),cam->get_znear(),delta);
|
||||
float new_far = Math::lerp(get_zfar(),cam->get_zfar(),delta);
|
||||
float new_near = Math::lerp(get_znear(), cam->get_znear(), delta);
|
||||
float new_far = Math::lerp(get_zfar(), cam->get_zfar(), delta);
|
||||
|
||||
if (cam->get_projection()==PROJECTION_ORTHOGONAL) {
|
||||
if (cam->get_projection() == PROJECTION_ORTHOGONAL) {
|
||||
|
||||
float size = Math::lerp(get_size(),cam->get_size(),delta);
|
||||
set_orthogonal(size,new_near,new_far);
|
||||
float size = Math::lerp(get_size(), cam->get_size(), delta);
|
||||
set_orthogonal(size, new_near, new_far);
|
||||
} else {
|
||||
|
||||
float fov = Math::lerp(get_fov(),cam->get_fov(),delta);
|
||||
set_perspective(fov,new_near,new_far);
|
||||
float fov = Math::lerp(get_fov(), cam->get_fov(), delta);
|
||||
set_perspective(fov, new_near, new_far);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} break;
|
||||
|
|
@ -89,25 +86,24 @@ void InterpolatedCamera::_set_target(const Object *p_target) {
|
|||
void InterpolatedCamera::set_target(const Spatial *p_target) {
|
||||
|
||||
ERR_FAIL_NULL(p_target);
|
||||
target=get_path_to(p_target);
|
||||
target = get_path_to(p_target);
|
||||
}
|
||||
|
||||
void InterpolatedCamera::set_target_path(const NodePath &p_path) {
|
||||
|
||||
void InterpolatedCamera::set_target_path(const NodePath& p_path){
|
||||
|
||||
target=p_path;
|
||||
target = p_path;
|
||||
}
|
||||
|
||||
NodePath InterpolatedCamera::get_target_path() const{
|
||||
NodePath InterpolatedCamera::get_target_path() const {
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void InterpolatedCamera::set_interpolation_enabled(bool p_enable) {
|
||||
|
||||
if (enabled==p_enable)
|
||||
if (enabled == p_enable)
|
||||
return;
|
||||
enabled=p_enable;
|
||||
enabled = p_enable;
|
||||
if (p_enable) {
|
||||
if (is_inside_tree() && get_tree()->is_editor_hint())
|
||||
return;
|
||||
|
|
@ -123,7 +119,7 @@ bool InterpolatedCamera::is_interpolation_enabled() const {
|
|||
|
||||
void InterpolatedCamera::set_speed(real_t p_speed) {
|
||||
|
||||
speed=p_speed;
|
||||
speed = p_speed;
|
||||
}
|
||||
|
||||
real_t InterpolatedCamera::get_speed() const {
|
||||
|
|
@ -131,27 +127,25 @@ real_t InterpolatedCamera::get_speed() const {
|
|||
return speed;
|
||||
}
|
||||
|
||||
|
||||
void InterpolatedCamera::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_target_path","target_path"),&InterpolatedCamera::set_target_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_target_path"),&InterpolatedCamera::get_target_path);
|
||||
ObjectTypeDB::bind_method(_MD("set_target","target:Camera"),&InterpolatedCamera::_set_target);
|
||||
ObjectTypeDB::bind_method(_MD("set_target_path", "target_path"), &InterpolatedCamera::set_target_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_target_path"), &InterpolatedCamera::get_target_path);
|
||||
ObjectTypeDB::bind_method(_MD("set_target", "target:Camera"), &InterpolatedCamera::_set_target);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_speed","speed"),&InterpolatedCamera::set_speed);
|
||||
ObjectTypeDB::bind_method(_MD("get_speed"),&InterpolatedCamera::get_speed);
|
||||
ObjectTypeDB::bind_method(_MD("set_speed", "speed"), &InterpolatedCamera::set_speed);
|
||||
ObjectTypeDB::bind_method(_MD("get_speed"), &InterpolatedCamera::get_speed);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_interpolation_enabled","target_path"),&InterpolatedCamera::set_interpolation_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_interpolation_enabled"),&InterpolatedCamera::is_interpolation_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("set_interpolation_enabled", "target_path"), &InterpolatedCamera::set_interpolation_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_interpolation_enabled"), &InterpolatedCamera::is_interpolation_enabled);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::NODE_PATH,"target"), _SCS("set_target_path"), _SCS("get_target_path") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"speed"), _SCS("set_speed"), _SCS("get_speed") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"), _SCS("set_interpolation_enabled"), _SCS("is_interpolation_enabled") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), _SCS("set_target_path"), _SCS("get_target_path"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), _SCS("set_speed"), _SCS("get_speed"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), _SCS("set_interpolation_enabled"), _SCS("is_interpolation_enabled"));
|
||||
}
|
||||
|
||||
InterpolatedCamera::InterpolatedCamera() {
|
||||
|
||||
enabled=false;
|
||||
speed=1;
|
||||
|
||||
enabled = false;
|
||||
speed = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,21 +33,20 @@
|
|||
|
||||
class InterpolatedCamera : public Camera {
|
||||
|
||||
OBJ_TYPE(InterpolatedCamera,Camera);
|
||||
OBJ_TYPE(InterpolatedCamera, Camera);
|
||||
|
||||
bool enabled;
|
||||
real_t speed;
|
||||
NodePath target;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
void _set_target(const Object *p_target);
|
||||
|
||||
public:
|
||||
|
||||
void set_target(const Spatial *p_target);
|
||||
void set_target_path(const NodePath& p_path);
|
||||
void set_target_path(const NodePath &p_path);
|
||||
NodePath get_target_path() const;
|
||||
|
||||
void set_speed(real_t p_speed);
|
||||
|
|
@ -56,7 +55,6 @@ public:
|
|||
void set_interpolation_enabled(bool p_enable);
|
||||
bool is_interpolation_enabled() const;
|
||||
|
||||
|
||||
InterpolatedCamera();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@
|
|||
#include "globals.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
|
||||
static const char* _light_param_names[VS::LIGHT_PARAM_MAX]={
|
||||
static const char *_light_param_names[VS::LIGHT_PARAM_MAX] = {
|
||||
"params/spot_attenuation",
|
||||
"params/spot_angle",
|
||||
"params/radius",
|
||||
|
|
@ -48,40 +47,36 @@ static const char* _light_param_names[VS::LIGHT_PARAM_MAX]={
|
|||
void Light::set_parameter(Parameter p_param, float p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_param, PARAM_MAX);
|
||||
vars[p_param]=p_value;
|
||||
VisualServer::get_singleton()->light_set_param(light,(VisualServer::LightParam)p_param,p_value);
|
||||
if (p_param==PARAM_RADIUS || p_param==PARAM_SPOT_ANGLE)
|
||||
vars[p_param] = p_value;
|
||||
VisualServer::get_singleton()->light_set_param(light, (VisualServer::LightParam)p_param, p_value);
|
||||
if (p_param == PARAM_RADIUS || p_param == PARAM_SPOT_ANGLE)
|
||||
update_gizmo();
|
||||
_change_notify(_light_param_names[p_param]);
|
||||
// _change_notify(_param_names[p_param]);
|
||||
// _change_notify(_param_names[p_param]);
|
||||
}
|
||||
|
||||
float Light::get_parameter(Parameter p_param) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
|
||||
return vars[p_param];
|
||||
|
||||
}
|
||||
|
||||
void Light::set_color(LightColor p_color, const Color& p_value) {
|
||||
void Light::set_color(LightColor p_color, const Color &p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_color, 3);
|
||||
colors[p_color]=p_value;
|
||||
VisualServer::get_singleton()->light_set_color(light,(VisualServer::LightColor)p_color,p_value);
|
||||
colors[p_color] = p_value;
|
||||
VisualServer::get_singleton()->light_set_color(light, (VisualServer::LightColor)p_color, p_value);
|
||||
//_change_notify(_color_names[p_color]);
|
||||
|
||||
}
|
||||
Color Light::get_color(LightColor p_color) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_color, 3, Color());
|
||||
return colors[p_color];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Light::set_project_shadows(bool p_enabled) {
|
||||
|
||||
shadows=p_enabled;
|
||||
shadows = p_enabled;
|
||||
VisualServer::get_singleton()->light_set_shadow(light, p_enabled);
|
||||
_change_notify("shadow");
|
||||
}
|
||||
|
|
@ -90,10 +85,10 @@ bool Light::has_project_shadows() const {
|
|||
return shadows;
|
||||
}
|
||||
|
||||
void Light::set_projector(const Ref<Texture>& p_projector) {
|
||||
void Light::set_projector(const Ref<Texture> &p_projector) {
|
||||
|
||||
projector=p_projector;
|
||||
VisualServer::get_singleton()->light_set_projector(light, projector.is_null()?RID():projector->get_rid());
|
||||
projector = p_projector;
|
||||
VisualServer::get_singleton()->light_set_projector(light, projector.is_null() ? RID() : projector->get_rid());
|
||||
}
|
||||
|
||||
Ref<Texture> Light::get_projector() const {
|
||||
|
|
@ -101,48 +96,44 @@ Ref<Texture> Light::get_projector() const {
|
|||
return projector;
|
||||
}
|
||||
|
||||
|
||||
bool Light::_can_gizmo_scale() const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceTool> p_tool) {
|
||||
|
||||
static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceTool> p_tool) {
|
||||
|
||||
p_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
|
||||
for(int i = 1; i <= p_lats; i++) {
|
||||
double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats);
|
||||
double z0 = Math::sin(lat0);
|
||||
double zr0 = Math::cos(lat0);
|
||||
for (int i = 1; i <= p_lats; i++) {
|
||||
double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
|
||||
double z0 = Math::sin(lat0);
|
||||
double zr0 = Math::cos(lat0);
|
||||
|
||||
double lat1 = Math_PI * (-0.5 + (double) i / p_lats);
|
||||
double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
|
||||
double z1 = Math::sin(lat1);
|
||||
double zr1 = Math::cos(lat1);
|
||||
|
||||
for(int j = p_lons; j >= 1; j--) {
|
||||
for (int j = p_lons; j >= 1; j--) {
|
||||
|
||||
double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons;
|
||||
double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
|
||||
double x0 = Math::cos(lng0);
|
||||
double y0 = Math::sin(lng0);
|
||||
|
||||
double lng1 = 2 * Math_PI * (double) (j) / p_lons;
|
||||
double lng1 = 2 * Math_PI * (double)(j) / p_lons;
|
||||
double x1 = Math::cos(lng1);
|
||||
double y1 = Math::sin(lng1);
|
||||
|
||||
|
||||
Vector3 v[4]={
|
||||
Vector3(x1 * zr0, z0, y1 *zr0),
|
||||
Vector3(x1 * zr1, z1, y1 *zr1),
|
||||
Vector3(x0 * zr1, z1, y0 *zr1),
|
||||
Vector3(x0 * zr0, z0, y0 *zr0)
|
||||
Vector3 v[4] = {
|
||||
Vector3(x1 * zr0, z0, y1 * zr0),
|
||||
Vector3(x1 * zr1, z1, y1 * zr1),
|
||||
Vector3(x0 * zr1, z1, y0 * zr1),
|
||||
Vector3(x0 * zr0, z0, y0 * zr0)
|
||||
};
|
||||
|
||||
#define ADD_POINT(m_idx) \
|
||||
p_tool->add_normal(v[m_idx]);\
|
||||
p_tool->add_vertex(v[m_idx]*p_radius);
|
||||
#define ADD_POINT(m_idx) \
|
||||
p_tool->add_normal(v[m_idx]); \
|
||||
p_tool->add_vertex(v[m_idx] * p_radius);
|
||||
|
||||
ADD_POINT(0);
|
||||
ADD_POINT(1);
|
||||
|
|
@ -153,76 +144,70 @@ static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceToo
|
|||
ADD_POINT(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RES Light::_get_gizmo_geometry() const {
|
||||
|
||||
Ref<FixedMaterial> mat_area(memnew(FixedMaterial));
|
||||
|
||||
Ref<FixedMaterial> mat_area( memnew( FixedMaterial ));
|
||||
mat_area->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.7, 0.6, 0.0, 0.05));
|
||||
mat_area->set_parameter(FixedMaterial::PARAM_EMISSION, Color(0.7, 0.7, 0.7));
|
||||
mat_area->set_blend_mode(Material::BLEND_MODE_ADD);
|
||||
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
// mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.7,0.6,0.0,0.05) );
|
||||
mat_area->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.7,0.7,0.7) );
|
||||
mat_area->set_blend_mode( Material::BLEND_MODE_ADD );
|
||||
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
// mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
Ref<FixedMaterial> mat_light(memnew(FixedMaterial));
|
||||
|
||||
Ref<FixedMaterial> mat_light( memnew( FixedMaterial ));
|
||||
mat_light->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(1.0, 1.0, 0.8, 0.9));
|
||||
mat_light->set_flag(Material::FLAG_UNSHADED, true);
|
||||
|
||||
mat_light->set_parameter( FixedMaterial::PARAM_DIFFUSE, Color(1.0,1.0,0.8,0.9) );
|
||||
mat_light->set_flag(Material::FLAG_UNSHADED,true);
|
||||
Ref<Mesh> mesh;
|
||||
|
||||
Ref< Mesh > mesh;
|
||||
Ref<SurfaceTool> surftool(memnew(SurfaceTool));
|
||||
|
||||
Ref<SurfaceTool> surftool( memnew( SurfaceTool ));
|
||||
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
|
||||
case VisualServer::LIGHT_DIRECTIONAL: {
|
||||
|
||||
mat_area->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.9, 0.8, 0.1, 0.8));
|
||||
mat_area->set_blend_mode(Material::BLEND_MODE_MIX);
|
||||
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED, false);
|
||||
mat_area->set_flag(Material::FLAG_UNSHADED, true);
|
||||
|
||||
mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.9,0.8,0.1,0.8) );
|
||||
mat_area->set_blend_mode( Material::BLEND_MODE_MIX);
|
||||
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,false);
|
||||
mat_area->set_flag(Material::FLAG_UNSHADED,true);
|
||||
|
||||
_make_sphere( 5,5,0.6, surftool );
|
||||
_make_sphere(5, 5, 0.6, surftool);
|
||||
surftool->set_material(mat_light);
|
||||
mesh=surftool->commit(mesh);
|
||||
mesh = surftool->commit(mesh);
|
||||
|
||||
// float radius=1;
|
||||
// float radius=1;
|
||||
|
||||
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
|
||||
const int arrow_points=5;
|
||||
Vector3 arrow[arrow_points]={
|
||||
Vector3(0,0,2),
|
||||
Vector3(1,1,2),
|
||||
Vector3(1,1,-1),
|
||||
Vector3(2,2,-1),
|
||||
Vector3(0,0,-3)
|
||||
const int arrow_points = 5;
|
||||
Vector3 arrow[arrow_points] = {
|
||||
Vector3(0, 0, 2),
|
||||
Vector3(1, 1, 2),
|
||||
Vector3(1, 1, -1),
|
||||
Vector3(2, 2, -1),
|
||||
Vector3(0, 0, -3)
|
||||
};
|
||||
|
||||
int arrow_sides=4;
|
||||
int arrow_sides = 4;
|
||||
|
||||
for (int i = 0; i < arrow_sides; i++) {
|
||||
|
||||
for(int i = 0; i < arrow_sides ; i++) {
|
||||
Matrix3 ma(Vector3(0, 0, 1), Math_PI * 2 * float(i) / arrow_sides);
|
||||
Matrix3 mb(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / arrow_sides);
|
||||
|
||||
for (int j = 0; j < arrow_points - 1; j++) {
|
||||
|
||||
Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/arrow_sides);
|
||||
Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/arrow_sides);
|
||||
|
||||
|
||||
for(int j=0;j<arrow_points-1;j++) {
|
||||
|
||||
Vector3 points[4]={
|
||||
Vector3 points[4] = {
|
||||
ma.xform(arrow[j]),
|
||||
mb.xform(arrow[j]),
|
||||
mb.xform(arrow[j+1]),
|
||||
ma.xform(arrow[j+1]),
|
||||
mb.xform(arrow[j + 1]),
|
||||
ma.xform(arrow[j + 1]),
|
||||
};
|
||||
|
||||
Vector3 n = Plane(points[0],points[1],points[2]).normal;
|
||||
Vector3 n = Plane(points[0], points[1], points[2]).normal;
|
||||
|
||||
surftool->add_normal(n);
|
||||
surftool->add_vertex(points[0]);
|
||||
|
|
@ -237,58 +222,50 @@ RES Light::_get_gizmo_geometry() const {
|
|||
surftool->add_vertex(points[2]);
|
||||
surftool->add_normal(n);
|
||||
surftool->add_vertex(points[3]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
surftool->set_material(mat_area);
|
||||
mesh=surftool->commit(mesh);
|
||||
|
||||
|
||||
mesh = surftool->commit(mesh);
|
||||
|
||||
} break;
|
||||
case VisualServer::LIGHT_OMNI: {
|
||||
|
||||
|
||||
_make_sphere( 20,20,vars[PARAM_RADIUS], surftool );
|
||||
_make_sphere(20, 20, vars[PARAM_RADIUS], surftool);
|
||||
surftool->set_material(mat_area);
|
||||
mesh=surftool->commit(mesh);
|
||||
_make_sphere(5,5, 0.1, surftool );
|
||||
mesh = surftool->commit(mesh);
|
||||
_make_sphere(5, 5, 0.1, surftool);
|
||||
surftool->set_material(mat_light);
|
||||
mesh=surftool->commit(mesh);
|
||||
mesh = surftool->commit(mesh);
|
||||
} break;
|
||||
|
||||
case VisualServer::LIGHT_SPOT: {
|
||||
|
||||
_make_sphere( 5,5,0.1, surftool );
|
||||
_make_sphere(5, 5, 0.1, surftool);
|
||||
surftool->set_material(mat_light);
|
||||
mesh=surftool->commit(mesh);
|
||||
mesh = surftool->commit(mesh);
|
||||
|
||||
// make cone
|
||||
int points=24;
|
||||
float len=vars[PARAM_RADIUS];
|
||||
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
|
||||
int points = 24;
|
||||
float len = vars[PARAM_RADIUS];
|
||||
float size = Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE])) * len;
|
||||
|
||||
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
|
||||
for(int i = 0; i < points; i++) {
|
||||
for (int i = 0; i < points; i++) {
|
||||
|
||||
float x0=Math::sin(i * Math_PI * 2 / points);
|
||||
float y0=Math::cos(i * Math_PI * 2 / points);
|
||||
float x1=Math::sin((i+1) * Math_PI * 2 / points);
|
||||
float y1=Math::cos((i+1) * Math_PI * 2 / points);
|
||||
float x0 = Math::sin(i * Math_PI * 2 / points);
|
||||
float y0 = Math::cos(i * Math_PI * 2 / points);
|
||||
float x1 = Math::sin((i + 1) * Math_PI * 2 / points);
|
||||
float y1 = Math::cos((i + 1) * Math_PI * 2 / points);
|
||||
|
||||
Vector3 v1=Vector3(x0*size,y0*size,-len).normalized()*len;
|
||||
Vector3 v2=Vector3(x1*size,y1*size,-len).normalized()*len;
|
||||
Vector3 v1 = Vector3(x0 * size, y0 * size, -len).normalized() * len;
|
||||
Vector3 v2 = Vector3(x1 * size, y1 * size, -len).normalized() * len;
|
||||
|
||||
Vector3 v3=Vector3(0,0,0);
|
||||
Vector3 v4=Vector3(0,0,v1.z);
|
||||
|
||||
Vector3 n = Plane(v1,v2,v3).normal;
|
||||
Vector3 v3 = Vector3(0, 0, 0);
|
||||
Vector3 v4 = Vector3(0, 0, v1.z);
|
||||
|
||||
Vector3 n = Plane(v1, v2, v3).normal;
|
||||
|
||||
surftool->add_normal(n);
|
||||
surftool->add_vertex(v1);
|
||||
|
|
@ -297,7 +274,7 @@ RES Light::_get_gizmo_geometry() const {
|
|||
surftool->add_normal(n);
|
||||
surftool->add_vertex(v3);
|
||||
|
||||
n=Vector3(0,0,-1);
|
||||
n = Vector3(0, 0, -1);
|
||||
|
||||
surftool->add_normal(n);
|
||||
surftool->add_vertex(v1);
|
||||
|
|
@ -305,13 +282,10 @@ RES Light::_get_gizmo_geometry() const {
|
|||
surftool->add_vertex(v2);
|
||||
surftool->add_normal(n);
|
||||
surftool->add_vertex(v4);
|
||||
|
||||
|
||||
}
|
||||
|
||||
surftool->set_material(mat_area);
|
||||
mesh=surftool->commit(mesh);
|
||||
|
||||
mesh = surftool->commit(mesh);
|
||||
|
||||
} break;
|
||||
}
|
||||
|
|
@ -319,22 +293,21 @@ RES Light::_get_gizmo_geometry() const {
|
|||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
AABB Light::get_aabb() const {
|
||||
|
||||
if (type==VisualServer::LIGHT_DIRECTIONAL) {
|
||||
if (type == VisualServer::LIGHT_DIRECTIONAL) {
|
||||
|
||||
return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
|
||||
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
|
||||
} else if (type==VisualServer::LIGHT_OMNI) {
|
||||
} else if (type == VisualServer::LIGHT_OMNI) {
|
||||
|
||||
return AABB( Vector3(-1,-1,-1) * vars[PARAM_RADIUS], Vector3(2, 2, 2 ) * vars[PARAM_RADIUS]);
|
||||
return AABB(Vector3(-1, -1, -1) * vars[PARAM_RADIUS], Vector3(2, 2, 2) * vars[PARAM_RADIUS]);
|
||||
|
||||
} else if (type==VisualServer::LIGHT_SPOT) {
|
||||
} else if (type == VisualServer::LIGHT_SPOT) {
|
||||
|
||||
float len=vars[PARAM_RADIUS];
|
||||
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
|
||||
return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
|
||||
float len = vars[PARAM_RADIUS];
|
||||
float size = Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE])) * len;
|
||||
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
|
||||
}
|
||||
|
||||
return AABB();
|
||||
|
|
@ -345,17 +318,15 @@ DVector<Face3> Light::get_faces(uint32_t p_usage_flags) const {
|
|||
return DVector<Face3>();
|
||||
}
|
||||
|
||||
|
||||
void Light::set_operator(Operator p_op) {
|
||||
ERR_FAIL_INDEX(p_op,2);
|
||||
op=p_op;
|
||||
VisualServer::get_singleton()->light_set_operator(light,VS::LightOp(op));
|
||||
|
||||
ERR_FAIL_INDEX(p_op, 2);
|
||||
op = p_op;
|
||||
VisualServer::get_singleton()->light_set_operator(light, VS::LightOp(op));
|
||||
}
|
||||
|
||||
void Light::set_bake_mode(BakeMode p_bake_mode) {
|
||||
|
||||
bake_mode=p_bake_mode;
|
||||
bake_mode = p_bake_mode;
|
||||
}
|
||||
|
||||
Light::BakeMode Light::get_bake_mode() const {
|
||||
|
|
@ -363,49 +334,46 @@ Light::BakeMode Light::get_bake_mode() const {
|
|||
return bake_mode;
|
||||
}
|
||||
|
||||
|
||||
Light::Operator Light::get_operator() const {
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void Light::approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic,float p_radius_treshold) {
|
||||
void Light::approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic, float p_radius_treshold) {
|
||||
|
||||
//this is horrible and must never be used
|
||||
|
||||
float a = p_quadratic * p_radius_treshold;
|
||||
float b = p_linear * p_radius_treshold;
|
||||
float c = p_constant * p_radius_treshold -1;
|
||||
float a = p_quadratic * p_radius_treshold;
|
||||
float b = p_linear * p_radius_treshold;
|
||||
float c = p_constant * p_radius_treshold - 1;
|
||||
|
||||
float radius=10000;
|
||||
float radius = 10000;
|
||||
|
||||
if(a == 0) { // solve linear
|
||||
float d = Math::abs(-c/b);
|
||||
if(d<radius)
|
||||
radius=d;
|
||||
if (a == 0) { // solve linear
|
||||
float d = Math::abs(-c / b);
|
||||
if (d < radius)
|
||||
radius = d;
|
||||
|
||||
|
||||
} else { // solve quadratic
|
||||
} else { // solve quadratic
|
||||
// now ad^2 + bd + c = 0, solve quadratic equation:
|
||||
|
||||
float denominator = 2*a;
|
||||
float denominator = 2 * a;
|
||||
|
||||
if(denominator != 0) {
|
||||
if (denominator != 0) {
|
||||
|
||||
float root = b * b - 4 * a * c;
|
||||
|
||||
float root = b*b - 4*a*c;
|
||||
|
||||
if(root >=0) {
|
||||
if (root >= 0) {
|
||||
|
||||
root = sqrt(root);
|
||||
|
||||
float solution1 = fabs( (-b + root) / denominator);
|
||||
float solution2 = fabs( (-b - root) / denominator);
|
||||
float solution1 = fabs((-b + root) / denominator);
|
||||
float solution2 = fabs((-b - root) / denominator);
|
||||
|
||||
if(solution1 > radius)
|
||||
if (solution1 > radius)
|
||||
solution1 = radius;
|
||||
|
||||
if(solution2 > radius)
|
||||
if (solution2 > radius)
|
||||
solution2 = radius;
|
||||
|
||||
radius = (solution1 > solution2 ? solution1 : solution2);
|
||||
|
|
@ -413,7 +381,7 @@ void Light::approximate_opengl_attenuation(float p_constant, float p_linear, flo
|
|||
}
|
||||
}
|
||||
|
||||
float energy=1.0;
|
||||
float energy = 1.0;
|
||||
|
||||
/*if (p_constant>0)
|
||||
energy=1.0/p_constant; //energy is this
|
||||
|
|
@ -421,97 +389,90 @@ void Light::approximate_opengl_attenuation(float p_constant, float p_linear, flo
|
|||
energy=8.0; // some high number..
|
||||
*/
|
||||
|
||||
if (radius==10000)
|
||||
radius=100; //bug?
|
||||
|
||||
set_parameter(PARAM_RADIUS,radius);
|
||||
set_parameter(PARAM_ENERGY,energy);
|
||||
if (radius == 10000)
|
||||
radius = 100; //bug?
|
||||
|
||||
set_parameter(PARAM_RADIUS, radius);
|
||||
set_parameter(PARAM_ENERGY, energy);
|
||||
}
|
||||
|
||||
|
||||
void Light::_update_visibility() {
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
|
||||
bool editor_ok=true;
|
||||
bool editor_ok = true;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (editor_only) {
|
||||
if (!get_tree()->is_editor_hint()) {
|
||||
editor_ok=false;
|
||||
editor_ok = false;
|
||||
} else {
|
||||
editor_ok = (get_tree()->get_edited_scene_root() && (this==get_tree()->get_edited_scene_root() || get_owner()==get_tree()->get_edited_scene_root()));
|
||||
editor_ok = (get_tree()->get_edited_scene_root() && (this == get_tree()->get_edited_scene_root() || get_owner() == get_tree()->get_edited_scene_root()));
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (editor_only) {
|
||||
editor_ok=false;
|
||||
editor_ok = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && enabled && editor_ok);
|
||||
VS::get_singleton()->instance_light_set_enabled(get_instance(), is_visible() && enabled && editor_ok);
|
||||
_change_notify("geometry/visible");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Light::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE || p_what==NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
_update_visibility();
|
||||
}
|
||||
}
|
||||
|
||||
void Light::set_enabled(bool p_enabled) {
|
||||
|
||||
enabled=p_enabled;
|
||||
enabled = p_enabled;
|
||||
_update_visibility();
|
||||
}
|
||||
|
||||
bool Light::is_enabled() const{
|
||||
bool Light::is_enabled() const {
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void Light::set_editor_only(bool p_editor_only) {
|
||||
|
||||
editor_only=p_editor_only;
|
||||
editor_only = p_editor_only;
|
||||
_update_visibility();
|
||||
}
|
||||
|
||||
bool Light::is_editor_only() const{
|
||||
bool Light::is_editor_only() const {
|
||||
|
||||
return editor_only;
|
||||
}
|
||||
|
||||
|
||||
void Light::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_parameter","variable","value"), &Light::set_parameter );
|
||||
ObjectTypeDB::bind_method(_MD("get_parameter","variable"), &Light::get_parameter );
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color","value"), &Light::set_color );
|
||||
ObjectTypeDB::bind_method(_MD("get_color","color"), &Light::get_color );
|
||||
ObjectTypeDB::bind_method(_MD("set_project_shadows","enable"), &Light::set_project_shadows );
|
||||
ObjectTypeDB::bind_method(_MD("has_project_shadows"), &Light::has_project_shadows );
|
||||
ObjectTypeDB::bind_method(_MD("set_projector","projector:Texture"), &Light::set_projector );
|
||||
ObjectTypeDB::bind_method(_MD("get_projector:Texture"), &Light::get_projector );
|
||||
ObjectTypeDB::bind_method(_MD("set_operator","operator"), &Light::set_operator );
|
||||
ObjectTypeDB::bind_method(_MD("get_operator"), &Light::get_operator );
|
||||
ObjectTypeDB::bind_method(_MD("set_bake_mode","bake_mode"), &Light::set_bake_mode );
|
||||
ObjectTypeDB::bind_method(_MD("get_bake_mode"), &Light::get_bake_mode );
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"), &Light::set_enabled );
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"), &Light::is_enabled );
|
||||
ObjectTypeDB::bind_method(_MD("set_editor_only","editor_only"), &Light::set_editor_only );
|
||||
ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only );
|
||||
ObjectTypeDB::bind_method(_MD("set_parameter", "variable", "value"), &Light::set_parameter);
|
||||
ObjectTypeDB::bind_method(_MD("get_parameter", "variable"), &Light::get_parameter);
|
||||
ObjectTypeDB::bind_method(_MD("set_color", "color", "value"), &Light::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color", "color"), &Light::get_color);
|
||||
ObjectTypeDB::bind_method(_MD("set_project_shadows", "enable"), &Light::set_project_shadows);
|
||||
ObjectTypeDB::bind_method(_MD("has_project_shadows"), &Light::has_project_shadows);
|
||||
ObjectTypeDB::bind_method(_MD("set_projector", "projector:Texture"), &Light::set_projector);
|
||||
ObjectTypeDB::bind_method(_MD("get_projector:Texture"), &Light::get_projector);
|
||||
ObjectTypeDB::bind_method(_MD("set_operator", "operator"), &Light::set_operator);
|
||||
ObjectTypeDB::bind_method(_MD("get_operator"), &Light::get_operator);
|
||||
ObjectTypeDB::bind_method(_MD("set_bake_mode", "bake_mode"), &Light::set_bake_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_bake_mode"), &Light::get_bake_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled", "enabled"), &Light::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"), &Light::is_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("set_editor_only", "editor_only"), &Light::set_editor_only);
|
||||
ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only);
|
||||
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "params/bake_mode",PROPERTY_HINT_ENUM,"Disabled,Indirect,Indirect+Shadows,Full"), _SCS("set_bake_mode"), _SCS("get_bake_mode"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/energy", PROPERTY_HINT_EXP_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ENERGY );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params/enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "params/bake_mode", PROPERTY_HINT_ENUM, "Disabled,Indirect,Indirect+Shadows,Full"), _SCS("set_bake_mode"), _SCS("get_bake_mode"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/energy", PROPERTY_HINT_EXP_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ENERGY);
|
||||
/*
|
||||
if (type == VisualServer::LIGHT_OMNI || type == VisualServer::LIGHT_SPOT) {
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"));
|
||||
|
|
@ -524,76 +485,67 @@ void Light::_bind_methods() {
|
|||
|
||||
}*/
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/diffuse"), _SCS("set_color"), _SCS("get_color"),COLOR_DIFFUSE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/specular"), _SCS("set_color"), _SCS("get_color"),COLOR_SPECULAR);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/shadow"), _SCS("set_project_shadows"), _SCS("has_project_shadows"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkening", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_DARKENING );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_offset", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_OFFSET);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_slope_scale", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_SLOPE_SCALE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/esm_multiplier", PROPERTY_HINT_RANGE, "1.0,512.0,0.1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_ESM_MULTIPLIER);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::INT, "shadow/blur_passes", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_BLUR_PASSES);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "projector",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_projector"), _SCS("get_projector"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "operator",PROPERTY_HINT_ENUM,"Add,Sub"), _SCS("set_operator"), _SCS("get_operator"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::COLOR, "colors/diffuse"), _SCS("set_color"), _SCS("get_color"), COLOR_DIFFUSE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::COLOR, "colors/specular"), _SCS("set_color"), _SCS("get_color"), COLOR_SPECULAR);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow/shadow"), _SCS("set_project_shadows"), _SCS("has_project_shadows"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/darkening", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_DARKENING);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/z_offset", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_OFFSET);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/z_slope_scale", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_SLOPE_SCALE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/esm_multiplier", PROPERTY_HINT_RANGE, "1.0,512.0,0.1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_ESM_MULTIPLIER);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow/blur_passes", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_BLUR_PASSES);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_projector"), _SCS("get_projector"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub"), _SCS("set_operator"), _SCS("get_operator"));
|
||||
|
||||
BIND_CONSTANT(PARAM_RADIUS);
|
||||
BIND_CONSTANT(PARAM_ENERGY);
|
||||
BIND_CONSTANT(PARAM_ATTENUATION);
|
||||
BIND_CONSTANT(PARAM_SPOT_ANGLE);
|
||||
BIND_CONSTANT(PARAM_SPOT_ATTENUATION);
|
||||
BIND_CONSTANT(PARAM_SHADOW_DARKENING);
|
||||
BIND_CONSTANT(PARAM_SHADOW_Z_OFFSET);
|
||||
|
||||
BIND_CONSTANT( PARAM_RADIUS );
|
||||
BIND_CONSTANT( PARAM_ENERGY );
|
||||
BIND_CONSTANT( PARAM_ATTENUATION );
|
||||
BIND_CONSTANT( PARAM_SPOT_ANGLE );
|
||||
BIND_CONSTANT( PARAM_SPOT_ATTENUATION );
|
||||
BIND_CONSTANT( PARAM_SHADOW_DARKENING );
|
||||
BIND_CONSTANT( PARAM_SHADOW_Z_OFFSET );
|
||||
|
||||
|
||||
BIND_CONSTANT( COLOR_DIFFUSE );
|
||||
BIND_CONSTANT( COLOR_SPECULAR );
|
||||
|
||||
BIND_CONSTANT( BAKE_MODE_DISABLED );
|
||||
BIND_CONSTANT( BAKE_MODE_INDIRECT );
|
||||
BIND_CONSTANT( BAKE_MODE_INDIRECT_AND_SHADOWS );
|
||||
BIND_CONSTANT( BAKE_MODE_FULL );
|
||||
|
||||
BIND_CONSTANT(COLOR_DIFFUSE);
|
||||
BIND_CONSTANT(COLOR_SPECULAR);
|
||||
|
||||
BIND_CONSTANT(BAKE_MODE_DISABLED);
|
||||
BIND_CONSTANT(BAKE_MODE_INDIRECT);
|
||||
BIND_CONSTANT(BAKE_MODE_INDIRECT_AND_SHADOWS);
|
||||
BIND_CONSTANT(BAKE_MODE_FULL);
|
||||
}
|
||||
|
||||
|
||||
Light::Light(VisualServer::LightType p_type) {
|
||||
|
||||
type=p_type;
|
||||
light=VisualServer::get_singleton()->light_create(p_type);
|
||||
type = p_type;
|
||||
light = VisualServer::get_singleton()->light_create(p_type);
|
||||
|
||||
set_parameter(PARAM_SPOT_ATTENUATION,1.0);
|
||||
set_parameter(PARAM_SPOT_ANGLE,30.0);
|
||||
set_parameter(PARAM_RADIUS,2.0);
|
||||
set_parameter(PARAM_ENERGY,1.0);
|
||||
set_parameter(PARAM_ATTENUATION,1.0);
|
||||
set_parameter(PARAM_SHADOW_DARKENING,0.0);
|
||||
set_parameter(PARAM_SHADOW_Z_OFFSET,0.05);
|
||||
set_parameter(PARAM_SHADOW_Z_SLOPE_SCALE,0);
|
||||
set_parameter(PARAM_SHADOW_ESM_MULTIPLIER,60);
|
||||
set_parameter(PARAM_SHADOW_BLUR_PASSES,1);
|
||||
set_parameter(PARAM_SPOT_ATTENUATION, 1.0);
|
||||
set_parameter(PARAM_SPOT_ANGLE, 30.0);
|
||||
set_parameter(PARAM_RADIUS, 2.0);
|
||||
set_parameter(PARAM_ENERGY, 1.0);
|
||||
set_parameter(PARAM_ATTENUATION, 1.0);
|
||||
set_parameter(PARAM_SHADOW_DARKENING, 0.0);
|
||||
set_parameter(PARAM_SHADOW_Z_OFFSET, 0.05);
|
||||
set_parameter(PARAM_SHADOW_Z_SLOPE_SCALE, 0);
|
||||
set_parameter(PARAM_SHADOW_ESM_MULTIPLIER, 60);
|
||||
set_parameter(PARAM_SHADOW_BLUR_PASSES, 1);
|
||||
|
||||
set_color(COLOR_DIFFUSE, Color(1, 1, 1));
|
||||
set_color(COLOR_SPECULAR, Color(1, 1, 1));
|
||||
|
||||
set_color( COLOR_DIFFUSE, Color(1,1,1));
|
||||
set_color( COLOR_SPECULAR, Color(1,1,1));
|
||||
|
||||
op=OPERATOR_ADD;
|
||||
set_project_shadows( false );
|
||||
op = OPERATOR_ADD;
|
||||
set_project_shadows(false);
|
||||
set_base(light);
|
||||
enabled=true;
|
||||
editor_only=false;
|
||||
bake_mode=BAKE_MODE_DISABLED;
|
||||
|
||||
enabled = true;
|
||||
editor_only = false;
|
||||
bake_mode = BAKE_MODE_DISABLED;
|
||||
}
|
||||
|
||||
|
||||
Light::Light() {
|
||||
|
||||
type=VisualServer::LIGHT_DIRECTIONAL;
|
||||
type = VisualServer::LIGHT_DIRECTIONAL;
|
||||
ERR_PRINT("Light shouldn't be instanced dircetly, use the subtypes.");
|
||||
}
|
||||
|
||||
|
||||
Light::~Light() {
|
||||
|
||||
if (light.is_valid())
|
||||
|
|
@ -601,78 +553,70 @@ Light::~Light() {
|
|||
}
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
void DirectionalLight::set_shadow_mode(ShadowMode p_mode) {
|
||||
|
||||
shadow_mode=p_mode;
|
||||
VS::get_singleton()->light_directional_set_shadow_mode(light,(VS::LightDirectionalShadowMode)p_mode);
|
||||
|
||||
shadow_mode = p_mode;
|
||||
VS::get_singleton()->light_directional_set_shadow_mode(light, (VS::LightDirectionalShadowMode)p_mode);
|
||||
}
|
||||
|
||||
DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const{
|
||||
DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
|
||||
|
||||
return shadow_mode;
|
||||
}
|
||||
|
||||
void DirectionalLight::set_shadow_param(ShadowParam p_param, float p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_param,3);
|
||||
shadow_param[p_param]=p_value;
|
||||
VS::get_singleton()->light_directional_set_shadow_param(light,VS::LightDirectionalShadowParam(p_param),p_value);
|
||||
ERR_FAIL_INDEX(p_param, 3);
|
||||
shadow_param[p_param] = p_value;
|
||||
VS::get_singleton()->light_directional_set_shadow_param(light, VS::LightDirectionalShadowParam(p_param), p_value);
|
||||
}
|
||||
|
||||
float DirectionalLight::get_shadow_param(ShadowParam p_param) const {
|
||||
ERR_FAIL_INDEX_V(p_param,3,0);
|
||||
ERR_FAIL_INDEX_V(p_param, 3, 0);
|
||||
return shadow_param[p_param];
|
||||
}
|
||||
|
||||
void DirectionalLight::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_mode","mode"),&DirectionalLight::set_shadow_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_mode"),&DirectionalLight::get_shadow_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param);
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_mode", "mode"), &DirectionalLight::set_shadow_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_mode"), &DirectionalLight::get_shadow_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_param", "param", "value"), &DirectionalLight::set_shadow_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_param", "param"), &DirectionalLight::get_shadow_param);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
|
||||
|
||||
BIND_CONSTANT( SHADOW_ORTHOGONAL );
|
||||
BIND_CONSTANT( SHADOW_PERSPECTIVE );
|
||||
BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
|
||||
BIND_CONSTANT( SHADOW_PARALLEL_4_SPLITS );
|
||||
BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE );
|
||||
BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT );
|
||||
BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow/mode", PROPERTY_HINT_ENUM, "Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/max_distance", PROPERTY_HINT_EXP_RANGE, "0.00,99999,0.01"), _SCS("set_shadow_param"), _SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/split_weight", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"), _SCS("set_shadow_param"), _SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow/zoffset_scale", PROPERTY_HINT_RANGE, "0.01,1024.0,0.01"), _SCS("set_shadow_param"), _SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
|
||||
|
||||
BIND_CONSTANT(SHADOW_ORTHOGONAL);
|
||||
BIND_CONSTANT(SHADOW_PERSPECTIVE);
|
||||
BIND_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
|
||||
BIND_CONSTANT(SHADOW_PARALLEL_4_SPLITS);
|
||||
BIND_CONSTANT(SHADOW_PARAM_MAX_DISTANCE);
|
||||
BIND_CONSTANT(SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
|
||||
BIND_CONSTANT(SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
|
||||
}
|
||||
|
||||
DirectionalLight::DirectionalLight()
|
||||
: Light(VisualServer::LIGHT_DIRECTIONAL) {
|
||||
|
||||
DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL ) {
|
||||
|
||||
shadow_mode=SHADOW_ORTHOGONAL;
|
||||
shadow_param[SHADOW_PARAM_MAX_DISTANCE]=0;
|
||||
shadow_param[SHADOW_PARAM_PSSM_SPLIT_WEIGHT]=0.5;
|
||||
shadow_param[SHADOW_PARAM_PSSM_ZOFFSET_SCALE]=2.0;
|
||||
|
||||
|
||||
shadow_mode = SHADOW_ORTHOGONAL;
|
||||
shadow_param[SHADOW_PARAM_MAX_DISTANCE] = 0;
|
||||
shadow_param[SHADOW_PARAM_PSSM_SPLIT_WEIGHT] = 0.5;
|
||||
shadow_param[SHADOW_PARAM_PSSM_ZOFFSET_SCALE] = 2.0;
|
||||
}
|
||||
|
||||
|
||||
void OmniLight::_bind_methods() {
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
|
||||
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION);
|
||||
}
|
||||
|
||||
void SpotLight::_bind_methods() {
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "spot_attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION );
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION);
|
||||
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "spot_attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#ifndef LIGHT_H
|
||||
#define LIGHT_H
|
||||
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
|
@ -39,30 +38,28 @@
|
|||
*/
|
||||
class Light : public VisualInstance {
|
||||
|
||||
OBJ_TYPE( Light, VisualInstance );
|
||||
OBJ_TYPE(Light, VisualInstance);
|
||||
OBJ_CATEGORY("3D Light Nodes");
|
||||
|
||||
public:
|
||||
|
||||
enum Parameter {
|
||||
PARAM_RADIUS=VisualServer::LIGHT_PARAM_RADIUS,
|
||||
PARAM_ENERGY=VisualServer::LIGHT_PARAM_ENERGY,
|
||||
PARAM_ATTENUATION=VisualServer::LIGHT_PARAM_ATTENUATION,
|
||||
PARAM_SPOT_ANGLE=VisualServer::LIGHT_PARAM_SPOT_ANGLE,
|
||||
PARAM_SPOT_ATTENUATION=VisualServer::LIGHT_PARAM_SPOT_ATTENUATION,
|
||||
PARAM_SHADOW_DARKENING=VisualServer::LIGHT_PARAM_SHADOW_DARKENING,
|
||||
PARAM_SHADOW_Z_OFFSET=VisualServer::LIGHT_PARAM_SHADOW_Z_OFFSET,
|
||||
PARAM_SHADOW_Z_SLOPE_SCALE=VisualServer::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE,
|
||||
PARAM_SHADOW_ESM_MULTIPLIER=VisualServer::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER,
|
||||
PARAM_SHADOW_BLUR_PASSES=VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES,
|
||||
PARAM_MAX=VisualServer::LIGHT_PARAM_MAX
|
||||
PARAM_RADIUS = VisualServer::LIGHT_PARAM_RADIUS,
|
||||
PARAM_ENERGY = VisualServer::LIGHT_PARAM_ENERGY,
|
||||
PARAM_ATTENUATION = VisualServer::LIGHT_PARAM_ATTENUATION,
|
||||
PARAM_SPOT_ANGLE = VisualServer::LIGHT_PARAM_SPOT_ANGLE,
|
||||
PARAM_SPOT_ATTENUATION = VisualServer::LIGHT_PARAM_SPOT_ATTENUATION,
|
||||
PARAM_SHADOW_DARKENING = VisualServer::LIGHT_PARAM_SHADOW_DARKENING,
|
||||
PARAM_SHADOW_Z_OFFSET = VisualServer::LIGHT_PARAM_SHADOW_Z_OFFSET,
|
||||
PARAM_SHADOW_Z_SLOPE_SCALE = VisualServer::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE,
|
||||
PARAM_SHADOW_ESM_MULTIPLIER = VisualServer::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER,
|
||||
PARAM_SHADOW_BLUR_PASSES = VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES,
|
||||
PARAM_MAX = VisualServer::LIGHT_PARAM_MAX
|
||||
};
|
||||
|
||||
|
||||
enum LightColor {
|
||||
|
||||
COLOR_DIFFUSE=VisualServer::LIGHT_COLOR_DIFFUSE,
|
||||
COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR
|
||||
COLOR_DIFFUSE = VisualServer::LIGHT_COLOR_DIFFUSE,
|
||||
COLOR_SPECULAR = VisualServer::LIGHT_COLOR_SPECULAR
|
||||
};
|
||||
|
||||
enum BakeMode {
|
||||
|
|
@ -74,20 +71,17 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
enum Operator {
|
||||
|
||||
OPERATOR_ADD,
|
||||
OPERATOR_SUB
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Ref<Texture> projector;
|
||||
float vars[PARAM_MAX];
|
||||
Color colors[3];
|
||||
|
||||
|
||||
BakeMode bake_mode;
|
||||
VisualServer::LightType type;
|
||||
bool shadows;
|
||||
|
|
@ -96,10 +90,9 @@ private:
|
|||
Operator op;
|
||||
|
||||
void _update_visibility();
|
||||
// bind helpers
|
||||
// bind helpers
|
||||
|
||||
protected:
|
||||
|
||||
RID light;
|
||||
|
||||
virtual bool _can_gizmo_scale() const;
|
||||
|
|
@ -108,22 +101,21 @@ protected:
|
|||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
|
||||
Light(VisualServer::LightType p_type);
|
||||
public:
|
||||
|
||||
public:
|
||||
VS::LightType get_light_type() const { return type; }
|
||||
|
||||
void set_parameter(Parameter p_var, float p_value);
|
||||
float get_parameter(Parameter p_var) const;
|
||||
|
||||
void set_color(LightColor p_color,const Color& p_value);
|
||||
void set_color(LightColor p_color, const Color &p_value);
|
||||
Color get_color(LightColor p_color) const;
|
||||
|
||||
void set_project_shadows(bool p_enabled);
|
||||
bool has_project_shadows() const;
|
||||
|
||||
void set_projector(const Ref<Texture>& p_projector);
|
||||
void set_projector(const Ref<Texture> &p_projector);
|
||||
Ref<Texture> get_projector() const;
|
||||
|
||||
void set_operator(Operator p_op);
|
||||
|
|
@ -141,25 +133,22 @@ public:
|
|||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
void approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic, float p_radius_treshold=0.5);
|
||||
void approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic, float p_radius_treshold = 0.5);
|
||||
|
||||
Light();
|
||||
~Light();
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( Light::Parameter );
|
||||
VARIANT_ENUM_CAST( Light::LightColor );
|
||||
VARIANT_ENUM_CAST( Light::Operator );
|
||||
VARIANT_ENUM_CAST( Light::BakeMode);
|
||||
|
||||
VARIANT_ENUM_CAST(Light::Parameter);
|
||||
VARIANT_ENUM_CAST(Light::LightColor);
|
||||
VARIANT_ENUM_CAST(Light::Operator);
|
||||
VARIANT_ENUM_CAST(Light::BakeMode);
|
||||
|
||||
class DirectionalLight : public Light {
|
||||
|
||||
OBJ_TYPE( DirectionalLight, Light );
|
||||
OBJ_TYPE(DirectionalLight, Light);
|
||||
|
||||
public:
|
||||
|
||||
enum ShadowMode {
|
||||
SHADOW_ORTHOGONAL,
|
||||
SHADOW_PERSPECTIVE,
|
||||
|
|
@ -175,10 +164,11 @@ public:
|
|||
private:
|
||||
ShadowMode shadow_mode;
|
||||
float shadow_param[3];
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_shadow_mode(ShadowMode p_mode);
|
||||
ShadowMode get_shadow_mode() const;
|
||||
|
||||
|
|
@ -190,32 +180,31 @@ public:
|
|||
DirectionalLight();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( DirectionalLight::ShadowMode );
|
||||
VARIANT_ENUM_CAST( DirectionalLight::ShadowParam );
|
||||
|
||||
VARIANT_ENUM_CAST(DirectionalLight::ShadowMode);
|
||||
VARIANT_ENUM_CAST(DirectionalLight::ShadowParam);
|
||||
|
||||
class OmniLight : public Light {
|
||||
|
||||
OBJ_TYPE( OmniLight, Light );
|
||||
OBJ_TYPE(OmniLight, Light);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
OmniLight() : Light( VisualServer::LIGHT_OMNI ) { set_parameter(PARAM_SHADOW_Z_OFFSET,0.001);}
|
||||
OmniLight()
|
||||
: Light(VisualServer::LIGHT_OMNI) { set_parameter(PARAM_SHADOW_Z_OFFSET, 0.001); }
|
||||
};
|
||||
|
||||
class SpotLight : public Light {
|
||||
|
||||
OBJ_TYPE( SpotLight, Light );
|
||||
OBJ_TYPE(SpotLight, Light);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
SpotLight() : Light( VisualServer::LIGHT_SPOT ) {}
|
||||
SpotLight()
|
||||
: Light(VisualServer::LIGHT_SPOT) {}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
#include "scene/resources/mesh.h"
|
||||
|
||||
void Listener::_update_audio_listener_state() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Listener::_request_listener_update() {
|
||||
|
|
@ -12,53 +10,48 @@ void Listener::_request_listener_update() {
|
|||
_update_listener();
|
||||
}
|
||||
|
||||
bool Listener::_set(const StringName& p_name, const Variant& p_value) {
|
||||
bool Listener::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
if (p_name == "current") {
|
||||
if (p_value.operator bool()) {
|
||||
make_current();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool Listener::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool Listener::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (p_name == "current") {
|
||||
if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
|
||||
r_ret = current;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
r_ret = is_current();
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Listener::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
void Listener::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "current" ) );
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "current"));
|
||||
}
|
||||
|
||||
void Listener::_update_listener() {
|
||||
|
||||
if (is_inside_tree() && is_current()) {
|
||||
get_viewport()->_listener_transform_changed_notify();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Listener::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
bool first_listener = get_viewport()->_listener_add(this);
|
||||
|
|
@ -73,24 +66,19 @@ void Listener::_notification(int p_what) {
|
|||
if (!get_tree()->is_node_being_edited(this)) {
|
||||
if (is_current()) {
|
||||
clear_current();
|
||||
current=true; //keep it true
|
||||
current = true; //keep it true
|
||||
|
||||
} else {
|
||||
current=false;
|
||||
current = false;
|
||||
}
|
||||
}
|
||||
|
||||
get_viewport()->_listener_remove(this);
|
||||
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Transform Listener::get_listener_transform() const {
|
||||
|
||||
return get_global_transform().orthonormalized();
|
||||
|
|
@ -98,7 +86,7 @@ Transform Listener::get_listener_transform() const {
|
|||
|
||||
void Listener::make_current() {
|
||||
|
||||
current=true;
|
||||
current = true;
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
|
@ -106,27 +94,23 @@ void Listener::make_current() {
|
|||
get_viewport()->_listener_set(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Listener::clear_current() {
|
||||
|
||||
current=false;
|
||||
current = false;
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
if (get_viewport()->get_listener()==this) {
|
||||
if (get_viewport()->get_listener() == this) {
|
||||
get_viewport()->_listener_set(NULL);
|
||||
get_viewport()->_listener_make_next_current(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Listener::is_current() const {
|
||||
|
||||
if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
|
||||
|
||||
return get_viewport()->get_listener()==this;
|
||||
return get_viewport()->get_listener() == this;
|
||||
} else
|
||||
return current;
|
||||
|
||||
|
|
@ -146,22 +130,18 @@ RES Listener::_get_gizmo_geometry() const {
|
|||
|
||||
void Listener::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method( _MD("make_current"),&Listener::make_current );
|
||||
ObjectTypeDB::bind_method( _MD("clear_current"),&Listener::clear_current );
|
||||
ObjectTypeDB::bind_method( _MD("is_current"),&Listener::is_current );
|
||||
ObjectTypeDB::bind_method( _MD("get_listener_transform"),&Listener::get_listener_transform );
|
||||
ObjectTypeDB::bind_method(_MD("make_current"), &Listener::make_current);
|
||||
ObjectTypeDB::bind_method(_MD("clear_current"), &Listener::clear_current);
|
||||
ObjectTypeDB::bind_method(_MD("is_current"), &Listener::is_current);
|
||||
ObjectTypeDB::bind_method(_MD("get_listener_transform"), &Listener::get_listener_transform);
|
||||
}
|
||||
|
||||
Listener::Listener() {
|
||||
|
||||
current=false;
|
||||
force_change=false;
|
||||
current = false;
|
||||
force_change = false;
|
||||
//active=false;
|
||||
}
|
||||
|
||||
|
||||
Listener::~Listener() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
#ifndef LISTENER_H
|
||||
#define LISTENER_H
|
||||
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/main/viewport.h"
|
||||
|
||||
class Listener : public Spatial {
|
||||
|
||||
OBJ_TYPE(Listener, Spatial);
|
||||
private:
|
||||
|
||||
private:
|
||||
bool force_change;
|
||||
bool current;
|
||||
|
||||
|
|
@ -18,22 +17,21 @@ private:
|
|||
virtual bool _can_gizmo_scale() const;
|
||||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
friend class Viewport;
|
||||
friend class Viewport;
|
||||
void _update_audio_listener_state();
|
||||
protected:
|
||||
|
||||
protected:
|
||||
void _update_listener();
|
||||
virtual void _request_listener_update();
|
||||
|
||||
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;
|
||||
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;
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void make_current();
|
||||
void clear_current();
|
||||
bool is_current() const;
|
||||
|
|
@ -47,7 +45,6 @@ public:
|
|||
|
||||
Listener();
|
||||
~Listener();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@
|
|||
/*************************************************************************/
|
||||
#include "mesh_instance.h"
|
||||
|
||||
#include "skeleton.h"
|
||||
#include "physics_body.h"
|
||||
#include "body_shape.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "core_string_names.h"
|
||||
bool MeshInstance::_set(const StringName& p_name, const Variant& p_value) {
|
||||
#include "physics_body.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "skeleton.h"
|
||||
bool MeshInstance::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
//this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else.
|
||||
//add to it that it's probably found on first call to _set anyway.
|
||||
|
|
@ -41,97 +41,91 @@ bool MeshInstance::_set(const StringName& p_name, const Variant& p_value) {
|
|||
if (!get_instance().is_valid())
|
||||
return false;
|
||||
|
||||
|
||||
Map<StringName,MorphTrack>::Element *E = morph_tracks.find(p_name);
|
||||
Map<StringName, MorphTrack>::Element *E = morph_tracks.find(p_name);
|
||||
if (E) {
|
||||
E->get().value=p_value;
|
||||
VisualServer::get_singleton()->instance_set_morph_target_weight(get_instance(),E->get().idx,E->get().value);
|
||||
E->get().value = p_value;
|
||||
VisualServer::get_singleton()->instance_set_morph_target_weight(get_instance(), E->get().idx, E->get().value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p_name.operator String().begins_with("material/")) {
|
||||
int idx = p_name.operator String().get_slicec('/',1).to_int();
|
||||
if (idx>=materials.size() || idx<0)
|
||||
int idx = p_name.operator String().get_slicec('/', 1).to_int();
|
||||
if (idx >= materials.size() || idx < 0)
|
||||
return false;
|
||||
|
||||
set_surface_material(idx,p_value);
|
||||
set_surface_material(idx, p_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MeshInstance::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
bool MeshInstance::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (!get_instance().is_valid())
|
||||
return false;
|
||||
|
||||
const Map<StringName,MorphTrack>::Element *E = morph_tracks.find(p_name);
|
||||
const Map<StringName, MorphTrack>::Element *E = morph_tracks.find(p_name);
|
||||
if (E) {
|
||||
r_ret = E->get().value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p_name.operator String().begins_with("material/")) {
|
||||
int idx = p_name.operator String().get_slicec('/',1).to_int();
|
||||
if (idx>=materials.size() || idx<0)
|
||||
int idx = p_name.operator String().get_slicec('/', 1).to_int();
|
||||
if (idx >= materials.size() || idx < 0)
|
||||
return false;
|
||||
r_ret=materials[idx];
|
||||
r_ret = materials[idx];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MeshInstance::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
void MeshInstance::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
List<String> ls;
|
||||
for(const Map<StringName,MorphTrack>::Element *E=morph_tracks.front();E;E=E->next()) {
|
||||
for (const Map<StringName, MorphTrack>::Element *E = morph_tracks.front(); E; E = E->next()) {
|
||||
|
||||
ls.push_back(E->key());
|
||||
}
|
||||
|
||||
ls.sort();
|
||||
|
||||
for(List<String>::Element *E=ls.front();E;E=E->next()) {
|
||||
p_list->push_back( PropertyInfo(Variant::REAL,E->get(),PROPERTY_HINT_RANGE,"0,1,0.01"));
|
||||
for (List<String>::Element *E = ls.front(); E; E = E->next()) {
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, E->get(), PROPERTY_HINT_RANGE, "0,1,0.01"));
|
||||
}
|
||||
|
||||
if (mesh.is_valid()) {
|
||||
for(int i=0;i<mesh->get_surface_count();i++) {
|
||||
p_list->push_back( PropertyInfo(Variant::OBJECT, "material/"+itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Material"));
|
||||
for (int i = 0; i < mesh->get_surface_count(); i++) {
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Material"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshInstance::set_mesh(const Ref<Mesh> &p_mesh) {
|
||||
|
||||
|
||||
|
||||
void MeshInstance::set_mesh(const Ref<Mesh>& p_mesh) {
|
||||
|
||||
if (mesh==p_mesh)
|
||||
if (mesh == p_mesh)
|
||||
return;
|
||||
|
||||
if (mesh.is_valid()) {
|
||||
mesh->disconnect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_mesh_changed);
|
||||
mesh->disconnect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed);
|
||||
materials.clear();
|
||||
}
|
||||
|
||||
mesh=p_mesh;
|
||||
mesh = p_mesh;
|
||||
|
||||
morph_tracks.clear();
|
||||
if (mesh.is_valid()) {
|
||||
|
||||
|
||||
for(int i=0;i<mesh->get_morph_target_count();i++) {
|
||||
for (int i = 0; i < mesh->get_morph_target_count(); i++) {
|
||||
|
||||
MorphTrack mt;
|
||||
mt.idx=i;
|
||||
mt.value=0;
|
||||
morph_tracks["morph/"+String(mesh->get_morph_target_name(i))]=mt;
|
||||
mt.idx = i;
|
||||
mt.value = 0;
|
||||
morph_tracks["morph/" + String(mesh->get_morph_target_name(i))] = mt;
|
||||
}
|
||||
|
||||
mesh->connect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_mesh_changed);
|
||||
mesh->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed);
|
||||
materials.resize(mesh->get_surface_count());
|
||||
|
||||
set_base(mesh->get_rid());
|
||||
|
|
@ -147,14 +141,14 @@ Ref<Mesh> MeshInstance::get_mesh() const {
|
|||
return mesh;
|
||||
}
|
||||
|
||||
void MeshInstance::_resolve_skeleton_path(){
|
||||
void MeshInstance::_resolve_skeleton_path() {
|
||||
|
||||
if (skeleton_path.is_empty())
|
||||
return;
|
||||
|
||||
Skeleton *skeleton=get_node(skeleton_path)?get_node(skeleton_path)->cast_to<Skeleton>():NULL;
|
||||
Skeleton *skeleton = get_node(skeleton_path) ? get_node(skeleton_path)->cast_to<Skeleton>() : NULL;
|
||||
if (skeleton)
|
||||
VisualServer::get_singleton()->instance_attach_skeleton( get_instance(), skeleton->get_skeleton() );
|
||||
VisualServer::get_singleton()->instance_attach_skeleton(get_instance(), skeleton->get_skeleton());
|
||||
}
|
||||
|
||||
void MeshInstance::set_skeleton_path(const NodePath &p_skeleton) {
|
||||
|
|
@ -179,7 +173,7 @@ AABB MeshInstance::get_aabb() const {
|
|||
|
||||
DVector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
if (!(p_usage_flags&(FACES_SOLID|FACES_ENCLOSING)))
|
||||
if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING)))
|
||||
return DVector<Face3>();
|
||||
|
||||
if (mesh.is_null())
|
||||
|
|
@ -188,8 +182,7 @@ DVector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const {
|
|||
return mesh->get_faces();
|
||||
}
|
||||
|
||||
|
||||
Node* MeshInstance::create_trimesh_collision_node() {
|
||||
Node *MeshInstance::create_trimesh_collision_node() {
|
||||
|
||||
if (mesh.is_null())
|
||||
return NULL;
|
||||
|
|
@ -198,32 +191,28 @@ Node* MeshInstance::create_trimesh_collision_node() {
|
|||
if (shape.is_null())
|
||||
return NULL;
|
||||
|
||||
StaticBody * static_body = memnew( StaticBody );
|
||||
static_body->add_shape( shape );
|
||||
StaticBody *static_body = memnew(StaticBody);
|
||||
static_body->add_shape(shape);
|
||||
return static_body;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MeshInstance::create_trimesh_collision() {
|
||||
|
||||
|
||||
StaticBody* static_body = create_trimesh_collision_node()->cast_to<StaticBody>();
|
||||
StaticBody *static_body = create_trimesh_collision_node()->cast_to<StaticBody>();
|
||||
ERR_FAIL_COND(!static_body);
|
||||
static_body->set_name( String(get_name()) + "_col" );
|
||||
static_body->set_name(String(get_name()) + "_col");
|
||||
|
||||
add_child(static_body);
|
||||
if (get_owner())
|
||||
static_body->set_owner( get_owner() );
|
||||
CollisionShape *cshape = memnew( CollisionShape );
|
||||
static_body->set_owner(get_owner());
|
||||
CollisionShape *cshape = memnew(CollisionShape);
|
||||
cshape->set_shape(static_body->get_shape(0));
|
||||
static_body->add_child(cshape);
|
||||
if (get_owner())
|
||||
cshape->set_owner( get_owner() );
|
||||
|
||||
cshape->set_owner(get_owner());
|
||||
}
|
||||
|
||||
Node* MeshInstance::create_convex_collision_node() {
|
||||
Node *MeshInstance::create_convex_collision_node() {
|
||||
|
||||
if (mesh.is_null())
|
||||
return NULL;
|
||||
|
|
@ -232,90 +221,77 @@ Node* MeshInstance::create_convex_collision_node() {
|
|||
if (shape.is_null())
|
||||
return NULL;
|
||||
|
||||
StaticBody * static_body = memnew( StaticBody );
|
||||
static_body->add_shape( shape );
|
||||
StaticBody *static_body = memnew(StaticBody);
|
||||
static_body->add_shape(shape);
|
||||
return static_body;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MeshInstance::create_convex_collision() {
|
||||
|
||||
|
||||
StaticBody* static_body = create_convex_collision_node()->cast_to<StaticBody>();
|
||||
StaticBody *static_body = create_convex_collision_node()->cast_to<StaticBody>();
|
||||
ERR_FAIL_COND(!static_body);
|
||||
static_body->set_name( String(get_name()) + "_col" );
|
||||
static_body->set_name(String(get_name()) + "_col");
|
||||
|
||||
add_child(static_body);
|
||||
if (get_owner())
|
||||
static_body->set_owner( get_owner() );
|
||||
CollisionShape *cshape = memnew( CollisionShape );
|
||||
static_body->set_owner(get_owner());
|
||||
CollisionShape *cshape = memnew(CollisionShape);
|
||||
cshape->set_shape(static_body->get_shape(0));
|
||||
static_body->add_child(cshape);
|
||||
if (get_owner())
|
||||
cshape->set_owner( get_owner() );
|
||||
|
||||
|
||||
cshape->set_owner(get_owner());
|
||||
}
|
||||
|
||||
void MeshInstance::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
_resolve_skeleton_path();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshInstance::set_surface_material(int p_surface, const Ref<Material> &p_material) {
|
||||
|
||||
void MeshInstance::set_surface_material(int p_surface,const Ref<Material>& p_material) {
|
||||
ERR_FAIL_INDEX(p_surface, materials.size());
|
||||
|
||||
ERR_FAIL_INDEX(p_surface,materials.size());
|
||||
|
||||
materials[p_surface]=p_material;
|
||||
materials[p_surface] = p_material;
|
||||
|
||||
if (materials[p_surface].is_valid())
|
||||
VS::get_singleton()->instance_set_surface_material(get_instance(),p_surface,materials[p_surface]->get_rid());
|
||||
VS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, materials[p_surface]->get_rid());
|
||||
else
|
||||
VS::get_singleton()->instance_set_surface_material(get_instance(),p_surface,RID());
|
||||
|
||||
VS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, RID());
|
||||
}
|
||||
|
||||
Ref<Material> MeshInstance::get_surface_material(int p_surface) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_surface,materials.size(),Ref<Material>());
|
||||
ERR_FAIL_INDEX_V(p_surface, materials.size(), Ref<Material>());
|
||||
|
||||
return materials[p_surface];
|
||||
}
|
||||
|
||||
|
||||
void MeshInstance::_mesh_changed() {
|
||||
|
||||
materials.resize( mesh->get_surface_count() );
|
||||
materials.resize(mesh->get_surface_count());
|
||||
}
|
||||
|
||||
void MeshInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_mesh","mesh:Mesh"),&MeshInstance::set_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_mesh:Mesh"),&MeshInstance::get_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("set_skeleton_path","skeleton_path:NodePath"),&MeshInstance::set_skeleton_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_skeleton_path:NodePath"),&MeshInstance::get_skeleton_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"),&MeshInstance::get_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("create_trimesh_collision"),&MeshInstance::create_trimesh_collision);
|
||||
ObjectTypeDB::set_method_flags("MeshInstance","create_trimesh_collision",METHOD_FLAGS_DEFAULT);
|
||||
ObjectTypeDB::bind_method(_MD("create_convex_collision"),&MeshInstance::create_convex_collision);
|
||||
ObjectTypeDB::set_method_flags("MeshInstance","create_convex_collision",METHOD_FLAGS_DEFAULT);
|
||||
ObjectTypeDB::bind_method(_MD("_mesh_changed"),&MeshInstance::_mesh_changed);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "mesh/mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh" ), _SCS("set_mesh"), _SCS("get_mesh"));
|
||||
ADD_PROPERTY( PropertyInfo (Variant::NODE_PATH, "mesh/skeleton"), _SCS("set_skeleton_path"), _SCS("get_skeleton_path"));
|
||||
ObjectTypeDB::bind_method(_MD("set_mesh", "mesh:Mesh"), &MeshInstance::set_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_mesh:Mesh"), &MeshInstance::get_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("set_skeleton_path", "skeleton_path:NodePath"), &MeshInstance::set_skeleton_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_skeleton_path:NodePath"), &MeshInstance::get_skeleton_path);
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"), &MeshInstance::get_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("create_trimesh_collision"), &MeshInstance::create_trimesh_collision);
|
||||
ObjectTypeDB::set_method_flags("MeshInstance", "create_trimesh_collision", METHOD_FLAGS_DEFAULT);
|
||||
ObjectTypeDB::bind_method(_MD("create_convex_collision"), &MeshInstance::create_convex_collision);
|
||||
ObjectTypeDB::set_method_flags("MeshInstance", "create_convex_collision", METHOD_FLAGS_DEFAULT);
|
||||
ObjectTypeDB::bind_method(_MD("_mesh_changed"), &MeshInstance::_mesh_changed);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh/mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), _SCS("set_mesh"), _SCS("get_mesh"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "mesh/skeleton"), _SCS("set_skeleton_path"), _SCS("get_skeleton_path"));
|
||||
}
|
||||
|
||||
MeshInstance::MeshInstance()
|
||||
{
|
||||
skeleton_path=NodePath("..");
|
||||
MeshInstance::MeshInstance() {
|
||||
skeleton_path = NodePath("..");
|
||||
}
|
||||
|
||||
|
||||
MeshInstance::~MeshInstance() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
class MeshInstance : public GeometryInstance {
|
||||
|
||||
OBJ_TYPE( MeshInstance, GeometryInstance );
|
||||
OBJ_TYPE(MeshInstance, GeometryInstance);
|
||||
|
||||
Ref<Mesh> mesh;
|
||||
NodePath skeleton_path;
|
||||
|
|
@ -46,38 +46,40 @@ class MeshInstance : public GeometryInstance {
|
|||
|
||||
int idx;
|
||||
float value;
|
||||
MorphTrack() { idx=0; value=0; }
|
||||
MorphTrack() {
|
||||
idx = 0;
|
||||
value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Map<StringName,MorphTrack> morph_tracks;
|
||||
Map<StringName, MorphTrack> morph_tracks;
|
||||
Vector<Ref<Material> > materials;
|
||||
|
||||
void _mesh_changed();
|
||||
void _resolve_skeleton_path();
|
||||
|
||||
protected:
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_mesh(const Ref<Mesh>& p_mesh);
|
||||
public:
|
||||
void set_mesh(const Ref<Mesh> &p_mesh);
|
||||
Ref<Mesh> get_mesh() const;
|
||||
|
||||
void set_skeleton_path(const NodePath& p_skeleton);
|
||||
void set_skeleton_path(const NodePath &p_skeleton);
|
||||
NodePath get_skeleton_path();
|
||||
|
||||
void set_surface_material(int p_surface,const Ref<Material>& p_material);
|
||||
void set_surface_material(int p_surface, const Ref<Material> &p_material);
|
||||
Ref<Material> get_surface_material(int p_surface) const;
|
||||
|
||||
Node* create_trimesh_collision_node();
|
||||
Node *create_trimesh_collision_node();
|
||||
void create_trimesh_collision();
|
||||
|
||||
Node* create_convex_collision_node();
|
||||
Node *create_convex_collision_node();
|
||||
void create_convex_collision();
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
|
|
|
|||
|
|
@ -28,27 +28,20 @@
|
|||
/*************************************************************************/
|
||||
#include "multimesh_instance.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MultiMeshInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_multimesh","multimesh"),&MultiMeshInstance::set_multimesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_multimesh"),&MultiMeshInstance::get_multimesh);
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"multimesh",PROPERTY_HINT_RESOURCE_TYPE,"MultiMesh"), _SCS("set_multimesh"), _SCS("get_multimesh"));
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_multimesh", "multimesh"), &MultiMeshInstance::set_multimesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_multimesh"), &MultiMeshInstance::get_multimesh);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), _SCS("set_multimesh"), _SCS("get_multimesh"));
|
||||
}
|
||||
|
||||
void MultiMeshInstance::set_multimesh(const Ref<MultiMesh>& p_multimesh) {
|
||||
void MultiMeshInstance::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
|
||||
|
||||
multimesh=p_multimesh;
|
||||
multimesh = p_multimesh;
|
||||
if (multimesh.is_valid())
|
||||
set_base(multimesh->get_rid());
|
||||
else
|
||||
set_base(RID());
|
||||
|
||||
}
|
||||
|
||||
Ref<MultiMesh> MultiMeshInstance::get_multimesh() const {
|
||||
|
|
@ -56,8 +49,6 @@ Ref<MultiMesh> MultiMeshInstance::get_multimesh() const {
|
|||
return multimesh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DVector<Face3> MultiMeshInstance::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
return DVector<Face3>();
|
||||
|
|
@ -72,10 +63,7 @@ AABB MultiMeshInstance::get_aabb() const {
|
|||
}
|
||||
|
||||
MultiMeshInstance::MultiMeshInstance() {
|
||||
|
||||
}
|
||||
|
||||
MultiMeshInstance::~MultiMeshInstance() {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,21 +37,18 @@
|
|||
*/
|
||||
|
||||
class MultiMeshInstance : public GeometryInstance {
|
||||
OBJ_TYPE( MultiMeshInstance, GeometryInstance );
|
||||
|
||||
OBJ_TYPE(MultiMeshInstance, GeometryInstance);
|
||||
|
||||
Ref<MultiMesh> multimesh;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
static void _bind_methods();
|
||||
// bind helpers
|
||||
|
||||
public:
|
||||
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
void set_multimesh(const Ref<MultiMesh>& p_multimesh);
|
||||
void set_multimesh(const Ref<MultiMesh> &p_multimesh);
|
||||
Ref<MultiMesh> get_multimesh() const;
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
|
|
@ -61,4 +58,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // MULTIMESH_INSTANCE_H
|
||||
|
||||
|
|
|
|||
|
|
@ -31,60 +31,58 @@
|
|||
void Navigation::_navmesh_link(int p_id) {
|
||||
|
||||
ERR_FAIL_COND(!navmesh_map.has(p_id));
|
||||
NavMesh &nm=navmesh_map[p_id];
|
||||
NavMesh &nm = navmesh_map[p_id];
|
||||
ERR_FAIL_COND(nm.linked);
|
||||
|
||||
print_line("LINK");
|
||||
|
||||
DVector<Vector3> vertices=nm.navmesh->get_vertices();
|
||||
DVector<Vector3> vertices = nm.navmesh->get_vertices();
|
||||
int len = vertices.size();
|
||||
if (len==0)
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
DVector<Vector3>::Read r=vertices.read();
|
||||
DVector<Vector3>::Read r = vertices.read();
|
||||
|
||||
for(int i=0;i<nm.navmesh->get_polygon_count();i++) {
|
||||
for (int i = 0; i < nm.navmesh->get_polygon_count(); i++) {
|
||||
|
||||
//build
|
||||
|
||||
List<Polygon>::Element *P=nm.polygons.push_back(Polygon());
|
||||
Polygon &p=P->get();
|
||||
p.owner=&nm;
|
||||
List<Polygon>::Element *P = nm.polygons.push_back(Polygon());
|
||||
Polygon &p = P->get();
|
||||
p.owner = &nm;
|
||||
|
||||
Vector<int> poly = nm.navmesh->get_polygon(i);
|
||||
int plen=poly.size();
|
||||
const int *indices=poly.ptr();
|
||||
bool valid=true;
|
||||
int plen = poly.size();
|
||||
const int *indices = poly.ptr();
|
||||
bool valid = true;
|
||||
p.edges.resize(plen);
|
||||
|
||||
Vector3 center;
|
||||
float sum=0;
|
||||
float sum = 0;
|
||||
|
||||
for(int j=0;j<plen;j++) {
|
||||
for (int j = 0; j < plen; j++) {
|
||||
|
||||
int idx = indices[j];
|
||||
if (idx<0 || idx>=len) {
|
||||
valid=false;
|
||||
if (idx < 0 || idx >= len) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Polygon::Edge e;
|
||||
Vector3 ep=nm.xform.xform(r[idx]);
|
||||
center+=ep;
|
||||
e.point=_get_point(ep);
|
||||
p.edges[j]=e;
|
||||
Vector3 ep = nm.xform.xform(r[idx]);
|
||||
center += ep;
|
||||
e.point = _get_point(ep);
|
||||
p.edges[j] = e;
|
||||
|
||||
if (j>=2) {
|
||||
Vector3 epa = nm.xform.xform(r[indices[j-2]]);
|
||||
Vector3 epb = nm.xform.xform(r[indices[j-1]]);
|
||||
|
||||
sum+=up.dot((epb-epa).cross(ep-epa));
|
||||
if (j >= 2) {
|
||||
Vector3 epa = nm.xform.xform(r[indices[j - 2]]);
|
||||
Vector3 epb = nm.xform.xform(r[indices[j - 1]]);
|
||||
|
||||
sum += up.dot((epb - epa).cross(ep - epa));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p.clockwise=sum>0;
|
||||
p.clockwise = sum > 0;
|
||||
|
||||
if (!valid) {
|
||||
nm.polygons.pop_back();
|
||||
|
|
@ -93,110 +91,106 @@ void Navigation::_navmesh_link(int p_id) {
|
|||
}
|
||||
|
||||
p.center = center;
|
||||
if( plen != 0 ) {
|
||||
if (plen != 0) {
|
||||
p.center /= plen;
|
||||
}
|
||||
|
||||
|
||||
//connect
|
||||
|
||||
for(int j=0;j<plen;j++) {
|
||||
for (int j = 0; j < plen; j++) {
|
||||
|
||||
int next = (j+1)%plen;
|
||||
EdgeKey ek(p.edges[j].point,p.edges[next].point);
|
||||
int next = (j + 1) % plen;
|
||||
EdgeKey ek(p.edges[j].point, p.edges[next].point);
|
||||
|
||||
Map<EdgeKey,Connection>::Element *C=connections.find(ek);
|
||||
Map<EdgeKey, Connection>::Element *C = connections.find(ek);
|
||||
if (!C) {
|
||||
|
||||
Connection c;
|
||||
c.A=&p;
|
||||
c.A_edge=j;
|
||||
c.B=NULL;
|
||||
c.B_edge=-1;
|
||||
connections[ek]=c;
|
||||
c.A = &p;
|
||||
c.A_edge = j;
|
||||
c.B = NULL;
|
||||
c.B_edge = -1;
|
||||
connections[ek] = c;
|
||||
} else {
|
||||
|
||||
if (C->get().B!=NULL) {
|
||||
if (C->get().B != NULL) {
|
||||
ConnectionPending pending;
|
||||
pending.polygon=&p;
|
||||
pending.edge=j;
|
||||
p.edges[j].P=C->get().pending.push_back(pending);
|
||||
pending.polygon = &p;
|
||||
pending.edge = j;
|
||||
p.edges[j].P = C->get().pending.push_back(pending);
|
||||
continue;
|
||||
//print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
|
||||
}
|
||||
//ERR_CONTINUE(C->get().B!=NULL); //wut
|
||||
|
||||
C->get().B=&p;
|
||||
C->get().B_edge=j;
|
||||
C->get().A->edges[C->get().A_edge].C=&p;
|
||||
C->get().A->edges[C->get().A_edge].C_edge=j;
|
||||
p.edges[j].C=C->get().A;
|
||||
p.edges[j].C_edge=C->get().A_edge;
|
||||
C->get().B = &p;
|
||||
C->get().B_edge = j;
|
||||
C->get().A->edges[C->get().A_edge].C = &p;
|
||||
C->get().A->edges[C->get().A_edge].C_edge = j;
|
||||
p.edges[j].C = C->get().A;
|
||||
p.edges[j].C_edge = C->get().A_edge;
|
||||
//connection successful.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nm.linked=true;
|
||||
|
||||
nm.linked = true;
|
||||
}
|
||||
|
||||
|
||||
void Navigation::_navmesh_unlink(int p_id) {
|
||||
|
||||
ERR_FAIL_COND(!navmesh_map.has(p_id));
|
||||
NavMesh &nm=navmesh_map[p_id];
|
||||
NavMesh &nm = navmesh_map[p_id];
|
||||
ERR_FAIL_COND(!nm.linked);
|
||||
|
||||
print_line("UNLINK");
|
||||
|
||||
for (List<Polygon>::Element *E=nm.polygons.front();E;E=E->next()) {
|
||||
for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) {
|
||||
|
||||
|
||||
Polygon &p=E->get();
|
||||
Polygon &p = E->get();
|
||||
|
||||
int ec = p.edges.size();
|
||||
Polygon::Edge *edges=p.edges.ptr();
|
||||
Polygon::Edge *edges = p.edges.ptr();
|
||||
|
||||
for(int i=0;i<ec;i++) {
|
||||
int next = (i+1)%ec;
|
||||
for (int i = 0; i < ec; i++) {
|
||||
int next = (i + 1) % ec;
|
||||
|
||||
EdgeKey ek(edges[i].point,edges[next].point);
|
||||
Map<EdgeKey,Connection>::Element *C=connections.find(ek);
|
||||
EdgeKey ek(edges[i].point, edges[next].point);
|
||||
Map<EdgeKey, Connection>::Element *C = connections.find(ek);
|
||||
|
||||
ERR_CONTINUE(!C);
|
||||
|
||||
if (edges[i].P) {
|
||||
C->get().pending.erase(edges[i].P);
|
||||
edges[i].P=NULL;
|
||||
edges[i].P = NULL;
|
||||
} else if (C->get().B) {
|
||||
//disconnect
|
||||
|
||||
C->get().B->edges[C->get().B_edge].C=NULL;
|
||||
C->get().B->edges[C->get().B_edge].C_edge=-1;
|
||||
C->get().A->edges[C->get().A_edge].C=NULL;
|
||||
C->get().A->edges[C->get().A_edge].C_edge=-1;
|
||||
C->get().B->edges[C->get().B_edge].C = NULL;
|
||||
C->get().B->edges[C->get().B_edge].C_edge = -1;
|
||||
C->get().A->edges[C->get().A_edge].C = NULL;
|
||||
C->get().A->edges[C->get().A_edge].C_edge = -1;
|
||||
|
||||
if (C->get().A==&E->get()) {
|
||||
if (C->get().A == &E->get()) {
|
||||
|
||||
C->get().A=C->get().B;
|
||||
C->get().A_edge=C->get().B_edge;
|
||||
C->get().A = C->get().B;
|
||||
C->get().A_edge = C->get().B_edge;
|
||||
}
|
||||
C->get().B=NULL;
|
||||
C->get().B_edge=-1;
|
||||
C->get().B = NULL;
|
||||
C->get().B_edge = -1;
|
||||
|
||||
if (C->get().pending.size()) {
|
||||
//reconnect if something is pending
|
||||
ConnectionPending cp = C->get().pending.front()->get();
|
||||
C->get().pending.pop_front();
|
||||
|
||||
C->get().B=cp.polygon;
|
||||
C->get().B_edge=cp.edge;
|
||||
C->get().A->edges[C->get().A_edge].C=cp.polygon;
|
||||
C->get().A->edges[C->get().A_edge].C_edge=cp.edge;
|
||||
cp.polygon->edges[cp.edge].C=C->get().A;
|
||||
cp.polygon->edges[cp.edge].C_edge=C->get().A_edge;
|
||||
cp.polygon->edges[cp.edge].P=NULL;
|
||||
C->get().B = cp.polygon;
|
||||
C->get().B_edge = cp.edge;
|
||||
C->get().A->edges[C->get().A_edge].C = cp.polygon;
|
||||
C->get().A->edges[C->get().A_edge].C_edge = cp.edge;
|
||||
cp.polygon->edges[cp.edge].C = C->get().A;
|
||||
cp.polygon->edges[cp.edge].C_edge = C->get().A_edge;
|
||||
cp.polygon->edges[cp.edge].P = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -208,76 +202,68 @@ void Navigation::_navmesh_unlink(int p_id) {
|
|||
|
||||
nm.polygons.clear();
|
||||
|
||||
nm.linked=false;
|
||||
|
||||
|
||||
nm.linked = false;
|
||||
}
|
||||
|
||||
|
||||
int Navigation::navmesh_create(const Ref<NavigationMesh>& p_mesh, const Transform& p_xform, Object *p_owner) {
|
||||
int Navigation::navmesh_create(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner) {
|
||||
|
||||
int id = last_id++;
|
||||
NavMesh nm;
|
||||
nm.linked=false;
|
||||
nm.navmesh=p_mesh;
|
||||
nm.xform=p_xform;
|
||||
nm.owner=p_owner;
|
||||
navmesh_map[id]=nm;
|
||||
nm.linked = false;
|
||||
nm.navmesh = p_mesh;
|
||||
nm.xform = p_xform;
|
||||
nm.owner = p_owner;
|
||||
navmesh_map[id] = nm;
|
||||
|
||||
_navmesh_link(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Navigation::navmesh_set_transform(int p_id, const Transform& p_xform){
|
||||
void Navigation::navmesh_set_transform(int p_id, const Transform &p_xform) {
|
||||
|
||||
ERR_FAIL_COND(!navmesh_map.has(p_id));
|
||||
NavMesh &nm=navmesh_map[p_id];
|
||||
if (nm.xform==p_xform)
|
||||
NavMesh &nm = navmesh_map[p_id];
|
||||
if (nm.xform == p_xform)
|
||||
return; //bleh
|
||||
_navmesh_unlink(p_id);
|
||||
nm.xform=p_xform;
|
||||
nm.xform = p_xform;
|
||||
_navmesh_link(p_id);
|
||||
|
||||
|
||||
|
||||
}
|
||||
void Navigation::navmesh_remove(int p_id){
|
||||
void Navigation::navmesh_remove(int p_id) {
|
||||
|
||||
ERR_FAIL_COND(!navmesh_map.has(p_id));
|
||||
_navmesh_unlink(p_id);
|
||||
navmesh_map.erase(p_id);
|
||||
|
||||
}
|
||||
|
||||
void Navigation::_clip_path(Vector<Vector3>& path, Polygon *from_poly, const Vector3& p_to_point, Polygon* p_to_poly) {
|
||||
void Navigation::_clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly) {
|
||||
|
||||
Vector3 from = path[path.size()-1];
|
||||
Vector3 from = path[path.size() - 1];
|
||||
|
||||
if (from.distance_to(p_to_point)<CMP_EPSILON)
|
||||
if (from.distance_to(p_to_point) < CMP_EPSILON)
|
||||
return;
|
||||
Plane cut_plane;
|
||||
cut_plane.normal = (from-p_to_point).cross(up);
|
||||
if (cut_plane.normal==Vector3())
|
||||
cut_plane.normal = (from - p_to_point).cross(up);
|
||||
if (cut_plane.normal == Vector3())
|
||||
return;
|
||||
cut_plane.normal.normalize();
|
||||
cut_plane.d = cut_plane.normal.dot(from);
|
||||
|
||||
|
||||
while(from_poly!=p_to_poly) {
|
||||
while (from_poly != p_to_poly) {
|
||||
|
||||
int pe = from_poly->prev_edge;
|
||||
Vector3 a = _get_vertex(from_poly->edges[pe].point);
|
||||
Vector3 b = _get_vertex(from_poly->edges[(pe+1)%from_poly->edges.size()].point);
|
||||
Vector3 b = _get_vertex(from_poly->edges[(pe + 1) % from_poly->edges.size()].point);
|
||||
|
||||
from_poly=from_poly->edges[pe].C;
|
||||
from_poly = from_poly->edges[pe].C;
|
||||
ERR_FAIL_COND(!from_poly);
|
||||
|
||||
if (a.distance_to(b)>CMP_EPSILON) {
|
||||
if (a.distance_to(b) > CMP_EPSILON) {
|
||||
|
||||
Vector3 inters;
|
||||
if (cut_plane.intersects_segment(a,b,&inters)) {
|
||||
if (inters.distance_to(p_to_point)>CMP_EPSILON && inters.distance_to(path[path.size()-1])>CMP_EPSILON) {
|
||||
if (cut_plane.intersects_segment(a, b, &inters)) {
|
||||
if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) {
|
||||
path.push_back(inters);
|
||||
}
|
||||
}
|
||||
|
|
@ -285,149 +271,138 @@ void Navigation::_clip_path(Vector<Vector3>& path, Polygon *from_poly, const Vec
|
|||
}
|
||||
}
|
||||
|
||||
Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector3& p_end, bool p_optimize) {
|
||||
Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) {
|
||||
|
||||
|
||||
Polygon *begin_poly=NULL;
|
||||
Polygon *end_poly=NULL;
|
||||
Polygon *begin_poly = NULL;
|
||||
Polygon *end_poly = NULL;
|
||||
Vector3 begin_point;
|
||||
Vector3 end_point;
|
||||
float begin_d=1e20;
|
||||
float end_d=1e20;
|
||||
float begin_d = 1e20;
|
||||
float end_d = 1e20;
|
||||
|
||||
|
||||
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
|
||||
for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
|
||||
|
||||
if (!E->get().linked)
|
||||
continue;
|
||||
for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) {
|
||||
for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
|
||||
|
||||
Polygon &p=F->get();
|
||||
for(int i=2;i<p.edges.size();i++) {
|
||||
Polygon &p = F->get();
|
||||
for (int i = 2; i < p.edges.size(); i++) {
|
||||
|
||||
Face3 f(_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point));
|
||||
Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
|
||||
Vector3 spoint = f.get_closest_point_to(p_start);
|
||||
float dpoint = spoint.distance_to(p_start);
|
||||
if (dpoint<begin_d) {
|
||||
begin_d=dpoint;
|
||||
begin_poly=&p;
|
||||
begin_point=spoint;
|
||||
if (dpoint < begin_d) {
|
||||
begin_d = dpoint;
|
||||
begin_poly = &p;
|
||||
begin_point = spoint;
|
||||
}
|
||||
|
||||
spoint = f.get_closest_point_to(p_end);
|
||||
dpoint = spoint.distance_to(p_end);
|
||||
if (dpoint<end_d) {
|
||||
end_d=dpoint;
|
||||
end_poly=&p;
|
||||
end_point=spoint;
|
||||
if (dpoint < end_d) {
|
||||
end_d = dpoint;
|
||||
end_poly = &p;
|
||||
end_point = spoint;
|
||||
}
|
||||
}
|
||||
|
||||
p.prev_edge=-1;
|
||||
p.prev_edge = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!begin_poly || !end_poly) {
|
||||
|
||||
//print_line("No Path Path");
|
||||
return Vector<Vector3>(); //no path
|
||||
}
|
||||
|
||||
|
||||
if (begin_poly==end_poly) {
|
||||
if (begin_poly == end_poly) {
|
||||
|
||||
Vector<Vector3> path;
|
||||
path.resize(2);
|
||||
path[0]=begin_point;
|
||||
path[1]=end_point;
|
||||
path[0] = begin_point;
|
||||
path[1] = end_point;
|
||||
//print_line("Direct Path");
|
||||
return path;
|
||||
}
|
||||
|
||||
bool found_route = false;
|
||||
|
||||
bool found_route=false;
|
||||
List<Polygon *> open_list;
|
||||
|
||||
List<Polygon*> open_list;
|
||||
|
||||
for(int i=0;i<begin_poly->edges.size();i++) {
|
||||
for (int i = 0; i < begin_poly->edges.size(); i++) {
|
||||
|
||||
if (begin_poly->edges[i].C) {
|
||||
|
||||
begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge;
|
||||
begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center);
|
||||
begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge;
|
||||
begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center);
|
||||
open_list.push_back(begin_poly->edges[i].C);
|
||||
|
||||
if (begin_poly->edges[i].C==end_poly) {
|
||||
found_route=true;
|
||||
if (begin_poly->edges[i].C == end_poly) {
|
||||
found_route = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!found_route) {
|
||||
|
||||
while(!found_route) {
|
||||
|
||||
if (open_list.size()==0) {
|
||||
// print_line("NOU OPEN LIST");
|
||||
if (open_list.size() == 0) {
|
||||
// print_line("NOU OPEN LIST");
|
||||
break;
|
||||
}
|
||||
//check open list
|
||||
|
||||
List<Polygon*>::Element *least_cost_poly=NULL;
|
||||
float least_cost=1e30;
|
||||
List<Polygon *>::Element *least_cost_poly = NULL;
|
||||
float least_cost = 1e30;
|
||||
|
||||
//this could be faster (cache previous results)
|
||||
for (List<Polygon*>::Element *E=open_list.front();E;E=E->next()) {
|
||||
for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) {
|
||||
|
||||
Polygon *p=E->get();
|
||||
Polygon *p = E->get();
|
||||
|
||||
float cost = p->distance;
|
||||
cost += p->center.distance_to(end_point);
|
||||
|
||||
float cost=p->distance;
|
||||
cost+=p->center.distance_to(end_point);
|
||||
if (cost < least_cost) {
|
||||
|
||||
if (cost<least_cost) {
|
||||
|
||||
least_cost_poly=E;
|
||||
least_cost=cost;
|
||||
least_cost_poly = E;
|
||||
least_cost = cost;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Polygon *p=least_cost_poly->get();
|
||||
Polygon *p = least_cost_poly->get();
|
||||
//open the neighbours for search
|
||||
|
||||
for(int i=0;i<p->edges.size();i++) {
|
||||
for (int i = 0; i < p->edges.size(); i++) {
|
||||
|
||||
|
||||
Polygon::Edge &e=p->edges[i];
|
||||
Polygon::Edge &e = p->edges[i];
|
||||
|
||||
if (!e.C)
|
||||
continue;
|
||||
|
||||
float distance = p->center.distance_to(e.C->center) + p->distance;
|
||||
|
||||
if (e.C->prev_edge!=-1) {
|
||||
if (e.C->prev_edge != -1) {
|
||||
//oh this was visited already, can we win the cost?
|
||||
|
||||
if (e.C->distance>distance) {
|
||||
if (e.C->distance > distance) {
|
||||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
e.C->prev_edge = e.C_edge;
|
||||
e.C->distance = distance;
|
||||
}
|
||||
} else {
|
||||
//add to open neighbours
|
||||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
e.C->prev_edge = e.C_edge;
|
||||
e.C->distance = distance;
|
||||
open_list.push_back(e.C);
|
||||
|
||||
if (e.C==end_poly) {
|
||||
if (e.C == end_poly) {
|
||||
//oh my reached end! stop algorithm
|
||||
found_route=true;
|
||||
found_route = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -444,174 +419,164 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector
|
|||
if (p_optimize) {
|
||||
//string pulling
|
||||
|
||||
Polygon *apex_poly=end_poly;
|
||||
Vector3 apex_point=end_point;
|
||||
Vector3 portal_left=apex_point;
|
||||
Vector3 portal_right=apex_point;
|
||||
Polygon *left_poly=end_poly;
|
||||
Polygon *right_poly=end_poly;
|
||||
Polygon *p=end_poly;
|
||||
Polygon *apex_poly = end_poly;
|
||||
Vector3 apex_point = end_point;
|
||||
Vector3 portal_left = apex_point;
|
||||
Vector3 portal_right = apex_point;
|
||||
Polygon *left_poly = end_poly;
|
||||
Polygon *right_poly = end_poly;
|
||||
Polygon *p = end_poly;
|
||||
path.push_back(end_point);
|
||||
|
||||
while(p) {
|
||||
while (p) {
|
||||
|
||||
Vector3 left;
|
||||
Vector3 right;
|
||||
|
||||
#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) )
|
||||
#define CLOCK_TANGENT(m_a, m_b, m_c) (((m_a) - (m_c)).cross((m_a) - (m_b)))
|
||||
|
||||
if (p==begin_poly) {
|
||||
left=begin_point;
|
||||
right=begin_point;
|
||||
if (p == begin_poly) {
|
||||
left = begin_point;
|
||||
right = begin_point;
|
||||
} else {
|
||||
int prev = p->prev_edge;
|
||||
int prev_n = (p->prev_edge+1)%p->edges.size();
|
||||
int prev_n = (p->prev_edge + 1) % p->edges.size();
|
||||
left = _get_vertex(p->edges[prev].point);
|
||||
right = _get_vertex(p->edges[prev_n].point);
|
||||
|
||||
//if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
|
||||
if (p->clockwise) {
|
||||
SWAP(left,right);
|
||||
SWAP(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
bool skip=false;
|
||||
bool skip = false;
|
||||
|
||||
|
||||
if (CLOCK_TANGENT(apex_point,portal_left,left).dot(up) >= 0){
|
||||
if (CLOCK_TANGENT(apex_point, portal_left, left).dot(up) >= 0) {
|
||||
//process
|
||||
if (portal_left==apex_point || CLOCK_TANGENT(apex_point,left,portal_right).dot(up) > 0) {
|
||||
left_poly=p;
|
||||
portal_left=left;
|
||||
if (portal_left == apex_point || CLOCK_TANGENT(apex_point, left, portal_right).dot(up) > 0) {
|
||||
left_poly = p;
|
||||
portal_left = left;
|
||||
} else {
|
||||
|
||||
_clip_path(path,apex_poly,portal_right,right_poly);
|
||||
_clip_path(path, apex_poly, portal_right, right_poly);
|
||||
|
||||
apex_point=portal_right;
|
||||
p=right_poly;
|
||||
left_poly=p;
|
||||
apex_poly=p;
|
||||
portal_left=apex_point;
|
||||
portal_right=apex_point;
|
||||
apex_point = portal_right;
|
||||
p = right_poly;
|
||||
left_poly = p;
|
||||
apex_poly = p;
|
||||
portal_left = apex_point;
|
||||
portal_right = apex_point;
|
||||
path.push_back(apex_point);
|
||||
skip=true;
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip && CLOCK_TANGENT(apex_point,portal_right,right).dot(up) <= 0){
|
||||
if (!skip && CLOCK_TANGENT(apex_point, portal_right, right).dot(up) <= 0) {
|
||||
//process
|
||||
if (portal_right==apex_point || CLOCK_TANGENT(apex_point,right,portal_left).dot(up) < 0) {
|
||||
right_poly=p;
|
||||
portal_right=right;
|
||||
if (portal_right == apex_point || CLOCK_TANGENT(apex_point, right, portal_left).dot(up) < 0) {
|
||||
right_poly = p;
|
||||
portal_right = right;
|
||||
} else {
|
||||
|
||||
_clip_path(path,apex_poly,portal_left,left_poly);
|
||||
_clip_path(path, apex_poly, portal_left, left_poly);
|
||||
|
||||
apex_point=portal_left;
|
||||
p=left_poly;
|
||||
right_poly=p;
|
||||
apex_poly=p;
|
||||
portal_right=apex_point;
|
||||
portal_left=apex_point;
|
||||
apex_point = portal_left;
|
||||
p = left_poly;
|
||||
right_poly = p;
|
||||
apex_poly = p;
|
||||
portal_right = apex_point;
|
||||
portal_left = apex_point;
|
||||
path.push_back(apex_point);
|
||||
}
|
||||
}
|
||||
|
||||
if (p!=begin_poly)
|
||||
p=p->edges[p->prev_edge].C;
|
||||
if (p != begin_poly)
|
||||
p = p->edges[p->prev_edge].C;
|
||||
else
|
||||
p=NULL;
|
||||
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (path[path.size()-1]!=begin_point)
|
||||
if (path[path.size() - 1] != begin_point)
|
||||
path.push_back(begin_point);
|
||||
|
||||
path.invert();
|
||||
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
//midpoints
|
||||
Polygon *p=end_poly;
|
||||
Polygon *p = end_poly;
|
||||
|
||||
path.push_back(end_point);
|
||||
while(true) {
|
||||
while (true) {
|
||||
int prev = p->prev_edge;
|
||||
int prev_n = (p->prev_edge+1)%p->edges.size();
|
||||
Vector3 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point))*0.5;
|
||||
int prev_n = (p->prev_edge + 1) % p->edges.size();
|
||||
Vector3 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5;
|
||||
path.push_back(point);
|
||||
p = p->edges[prev].C;
|
||||
if (p==begin_poly)
|
||||
if (p == begin_poly)
|
||||
break;
|
||||
}
|
||||
|
||||
path.push_back(begin_point);
|
||||
|
||||
|
||||
path.invert();
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
return Vector<Vector3>();
|
||||
|
||||
}
|
||||
|
||||
Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vector3& p_to,const bool& p_use_collision) {
|
||||
Vector3 Navigation::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision) {
|
||||
|
||||
|
||||
bool use_collision=p_use_collision;
|
||||
bool use_collision = p_use_collision;
|
||||
Vector3 closest_point;
|
||||
float closest_point_d=1e20;
|
||||
NavMesh *closest_navmesh=NULL;
|
||||
float closest_point_d = 1e20;
|
||||
NavMesh *closest_navmesh = NULL;
|
||||
|
||||
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
|
||||
for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
|
||||
|
||||
if (!E->get().linked)
|
||||
continue;
|
||||
for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) {
|
||||
for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
|
||||
|
||||
Polygon &p=F->get();
|
||||
for(int i=2;i<p.edges.size();i++) {
|
||||
Polygon &p = F->get();
|
||||
for (int i = 2; i < p.edges.size(); i++) {
|
||||
|
||||
Face3 f(_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point));
|
||||
Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
|
||||
Vector3 inters;
|
||||
if (f.intersects_segment(p_from,p_to,&inters)) {
|
||||
if (f.intersects_segment(p_from, p_to, &inters)) {
|
||||
|
||||
if (!use_collision) {
|
||||
closest_point=inters;
|
||||
use_collision=true;
|
||||
closest_point_d=p_from.distance_to(inters);
|
||||
closest_navmesh=p.owner;
|
||||
} else if (closest_point_d > inters.distance_to(p_from)){
|
||||
closest_point = inters;
|
||||
use_collision = true;
|
||||
closest_point_d = p_from.distance_to(inters);
|
||||
closest_navmesh = p.owner;
|
||||
} else if (closest_point_d > inters.distance_to(p_from)) {
|
||||
|
||||
closest_point=inters;
|
||||
closest_point_d=p_from.distance_to(inters);
|
||||
closest_navmesh=p.owner;
|
||||
closest_point = inters;
|
||||
closest_point_d = p_from.distance_to(inters);
|
||||
closest_navmesh = p.owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_collision) {
|
||||
|
||||
for(int i=0;i<p.edges.size();i++) {
|
||||
for (int i = 0; i < p.edges.size(); i++) {
|
||||
|
||||
Vector3 a,b;
|
||||
Vector3 a, b;
|
||||
|
||||
Geometry::get_closest_points_between_segments(p_from,p_to,_get_vertex(p.edges[i].point),_get_vertex(p.edges[(i+1)%p.edges.size()].point),a,b);
|
||||
Geometry::get_closest_points_between_segments(p_from, p_to, _get_vertex(p.edges[i].point), _get_vertex(p.edges[(i + 1) % p.edges.size()].point), a, b);
|
||||
|
||||
float d = a.distance_to(b);
|
||||
if (d<closest_point_d) {
|
||||
if (d < closest_point_d) {
|
||||
|
||||
closest_point_d=d;
|
||||
closest_point=b;
|
||||
closest_navmesh=p.owner;
|
||||
closest_point_d = d;
|
||||
closest_point = b;
|
||||
closest_navmesh = p.owner;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -624,132 +589,126 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec
|
|||
return closest_point;
|
||||
}
|
||||
|
||||
Vector3 Navigation::get_closest_point(const Vector3& p_point) {
|
||||
Vector3 Navigation::get_closest_point(const Vector3 &p_point) {
|
||||
|
||||
Vector3 closest_point;
|
||||
float closest_point_d=1e20;
|
||||
float closest_point_d = 1e20;
|
||||
|
||||
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
|
||||
for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
|
||||
|
||||
if (!E->get().linked)
|
||||
continue;
|
||||
for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) {
|
||||
for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
|
||||
|
||||
Polygon &p=F->get();
|
||||
for(int i=2;i<p.edges.size();i++) {
|
||||
Polygon &p = F->get();
|
||||
for (int i = 2; i < p.edges.size(); i++) {
|
||||
|
||||
Face3 f(_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point));
|
||||
Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
|
||||
Vector3 inters = f.get_closest_point_to(p_point);
|
||||
float d = inters.distance_to(p_point);
|
||||
if (d<closest_point_d) {
|
||||
closest_point=inters;
|
||||
closest_point_d=d;
|
||||
if (d < closest_point_d) {
|
||||
closest_point = inters;
|
||||
closest_point_d = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest_point;
|
||||
|
||||
}
|
||||
|
||||
Vector3 Navigation::get_closest_point_normal(const Vector3& p_point){
|
||||
Vector3 Navigation::get_closest_point_normal(const Vector3 &p_point) {
|
||||
|
||||
Vector3 closest_point;
|
||||
Vector3 closest_normal;
|
||||
float closest_point_d=1e20;
|
||||
float closest_point_d = 1e20;
|
||||
|
||||
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
|
||||
for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
|
||||
|
||||
if (!E->get().linked)
|
||||
continue;
|
||||
for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) {
|
||||
for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
|
||||
|
||||
Polygon &p=F->get();
|
||||
for(int i=2;i<p.edges.size();i++) {
|
||||
Polygon &p = F->get();
|
||||
for (int i = 2; i < p.edges.size(); i++) {
|
||||
|
||||
Face3 f(_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point));
|
||||
Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
|
||||
Vector3 inters = f.get_closest_point_to(p_point);
|
||||
float d = inters.distance_to(p_point);
|
||||
if (d<closest_point_d) {
|
||||
closest_point=inters;
|
||||
closest_point_d=d;
|
||||
closest_normal=f.get_plane().normal;
|
||||
if (d < closest_point_d) {
|
||||
closest_point = inters;
|
||||
closest_point_d = d;
|
||||
closest_normal = f.get_plane().normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest_normal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Object* Navigation::get_closest_point_owner(const Vector3& p_point){
|
||||
Object *Navigation::get_closest_point_owner(const Vector3 &p_point) {
|
||||
|
||||
Vector3 closest_point;
|
||||
Object *owner=NULL;
|
||||
float closest_point_d=1e20;
|
||||
Object *owner = NULL;
|
||||
float closest_point_d = 1e20;
|
||||
|
||||
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
|
||||
for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) {
|
||||
|
||||
if (!E->get().linked)
|
||||
continue;
|
||||
for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) {
|
||||
for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) {
|
||||
|
||||
Polygon &p=F->get();
|
||||
for(int i=2;i<p.edges.size();i++) {
|
||||
Polygon &p = F->get();
|
||||
for (int i = 2; i < p.edges.size(); i++) {
|
||||
|
||||
Face3 f(_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point));
|
||||
Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point));
|
||||
Vector3 inters = f.get_closest_point_to(p_point);
|
||||
float d = inters.distance_to(p_point);
|
||||
if (d<closest_point_d) {
|
||||
closest_point=inters;
|
||||
closest_point_d=d;
|
||||
owner=E->get().owner;
|
||||
if (d < closest_point_d) {
|
||||
closest_point = inters;
|
||||
closest_point_d = d;
|
||||
owner = E->get().owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return owner;
|
||||
|
||||
}
|
||||
|
||||
void Navigation::set_up_vector(const Vector3& p_up) {
|
||||
void Navigation::set_up_vector(const Vector3 &p_up) {
|
||||
|
||||
|
||||
up=p_up;
|
||||
up = p_up;
|
||||
}
|
||||
|
||||
Vector3 Navigation::get_up_vector() const{
|
||||
Vector3 Navigation::get_up_vector() const {
|
||||
|
||||
return up;
|
||||
}
|
||||
|
||||
|
||||
void Navigation::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_create","mesh:NavigationMesh","xform","owner"),&Navigation::navmesh_create,DEFVAL(Variant()));
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_set_transform","id","xform"),&Navigation::navmesh_set_transform);
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_remove","id"),&Navigation::navmesh_remove);
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_create", "mesh:NavigationMesh", "xform", "owner"), &Navigation::navmesh_create, DEFVAL(Variant()));
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_set_transform", "id", "xform"), &Navigation::navmesh_set_transform);
|
||||
ObjectTypeDB::bind_method(_MD("navmesh_remove", "id"), &Navigation::navmesh_remove);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_simple_path","start","end","optimize"),&Navigation::get_simple_path,DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_to_segment","start","end","use_collision"),&Navigation::get_closest_point_to_segment,DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point","to_point"),&Navigation::get_closest_point);
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_normal","to_point"),&Navigation::get_closest_point_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_owner","to_point"),&Navigation::get_closest_point_owner);
|
||||
ObjectTypeDB::bind_method(_MD("get_simple_path", "start", "end", "optimize"), &Navigation::get_simple_path, DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation::get_closest_point_to_segment, DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point", "to_point"), &Navigation::get_closest_point);
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_normal", "to_point"), &Navigation::get_closest_point_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_closest_point_owner", "to_point"), &Navigation::get_closest_point_owner);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_up_vector","up"),&Navigation::set_up_vector);
|
||||
ObjectTypeDB::bind_method(_MD("get_up_vector"),&Navigation::get_up_vector);
|
||||
ObjectTypeDB::bind_method(_MD("set_up_vector", "up"), &Navigation::set_up_vector);
|
||||
ObjectTypeDB::bind_method(_MD("get_up_vector"), &Navigation::get_up_vector);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"up_vector"),_SCS("set_up_vector"),_SCS("get_up_vector"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), _SCS("set_up_vector"), _SCS("get_up_vector"));
|
||||
}
|
||||
|
||||
Navigation::Navigation() {
|
||||
|
||||
ERR_FAIL_COND( sizeof(Point)!=8 );
|
||||
cell_size=0.01; //one centimeter
|
||||
last_id=1;
|
||||
up=Vector3(0,1,0);
|
||||
ERR_FAIL_COND(sizeof(Point) != 8);
|
||||
cell_size = 0.01; //one centimeter
|
||||
last_id = 1;
|
||||
up = Vector3(0, 1, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,46 +29,43 @@
|
|||
#ifndef NAVIGATION_H
|
||||
#define NAVIGATION_H
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/3d/navigation_mesh.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
class Navigation : public Spatial {
|
||||
|
||||
OBJ_TYPE( Navigation, Spatial);
|
||||
|
||||
OBJ_TYPE(Navigation, Spatial);
|
||||
|
||||
union Point {
|
||||
|
||||
struct {
|
||||
int64_t x:21;
|
||||
int64_t y:22;
|
||||
int64_t z:21;
|
||||
int64_t x : 21;
|
||||
int64_t y : 22;
|
||||
int64_t z : 21;
|
||||
};
|
||||
|
||||
uint64_t key;
|
||||
bool operator<(const Point& p_key) const { return key < p_key.key; }
|
||||
bool operator<(const Point &p_key) const { return key < p_key.key; }
|
||||
};
|
||||
|
||||
|
||||
struct EdgeKey {
|
||||
|
||||
Point a;
|
||||
Point b;
|
||||
|
||||
bool operator<(const EdgeKey& p_key) const {
|
||||
return (a.key==p_key.a.key)?(b.key<p_key.b.key):(a.key<p_key.a.key);
|
||||
bool operator<(const EdgeKey &p_key) const {
|
||||
return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
|
||||
};
|
||||
|
||||
EdgeKey(const Point& p_a=Point(),const Point& p_b=Point()) {
|
||||
a=p_a;
|
||||
b=p_b;
|
||||
EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) {
|
||||
a = p_a;
|
||||
b = p_b;
|
||||
if (a.key > b.key) {
|
||||
SWAP(a,b);
|
||||
SWAP(a, b);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct NavMesh;
|
||||
struct Polygon;
|
||||
|
||||
|
|
@ -78,7 +75,6 @@ class Navigation : public Spatial {
|
|||
int edge;
|
||||
};
|
||||
|
||||
|
||||
struct Polygon {
|
||||
|
||||
struct Edge {
|
||||
|
|
@ -86,7 +82,11 @@ class Navigation : public Spatial {
|
|||
Polygon *C; //connection
|
||||
int C_edge;
|
||||
List<ConnectionPending>::Element *P;
|
||||
Edge() { C=NULL; C_edge=-1; P=NULL; }
|
||||
Edge() {
|
||||
C = NULL;
|
||||
C_edge = -1;
|
||||
P = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Edge> edges;
|
||||
|
|
@ -97,11 +97,9 @@ class Navigation : public Spatial {
|
|||
int prev_edge;
|
||||
bool clockwise;
|
||||
|
||||
|
||||
NavMesh *owner;
|
||||
};
|
||||
|
||||
|
||||
struct Connection {
|
||||
|
||||
Polygon *A;
|
||||
|
|
@ -111,11 +109,15 @@ class Navigation : public Spatial {
|
|||
|
||||
List<ConnectionPending> pending;
|
||||
|
||||
Connection() { A=NULL; B=NULL; A_edge=-1; B_edge=-1;}
|
||||
Connection() {
|
||||
A = NULL;
|
||||
B = NULL;
|
||||
A_edge = -1;
|
||||
B_edge = -1;
|
||||
}
|
||||
};
|
||||
|
||||
Map<EdgeKey,Connection> connections;
|
||||
|
||||
Map<EdgeKey, Connection> connections;
|
||||
|
||||
struct NavMesh {
|
||||
|
||||
|
|
@ -124,62 +126,54 @@ class Navigation : public Spatial {
|
|||
bool linked;
|
||||
Ref<NavigationMesh> navmesh;
|
||||
List<Polygon> polygons;
|
||||
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Point _get_point(const Vector3 &p_pos) const {
|
||||
|
||||
|
||||
_FORCE_INLINE_ Point _get_point(const Vector3& p_pos) const {
|
||||
|
||||
int x = int(Math::floor(p_pos.x/cell_size));
|
||||
int y = int(Math::floor(p_pos.y/cell_size));
|
||||
int z = int(Math::floor(p_pos.z/cell_size));
|
||||
int x = int(Math::floor(p_pos.x / cell_size));
|
||||
int y = int(Math::floor(p_pos.y / cell_size));
|
||||
int z = int(Math::floor(p_pos.z / cell_size));
|
||||
|
||||
Point p;
|
||||
p.key=0;
|
||||
p.x=x;
|
||||
p.y=y;
|
||||
p.z=z;
|
||||
p.key = 0;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
p.z = z;
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector3 _get_vertex(const Point& p_point) const {
|
||||
_FORCE_INLINE_ Vector3 _get_vertex(const Point &p_point) const {
|
||||
|
||||
return Vector3(p_point.x,p_point.y,p_point.z)*cell_size;
|
||||
return Vector3(p_point.x, p_point.y, p_point.z) * cell_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _navmesh_link(int p_id);
|
||||
void _navmesh_unlink(int p_id);
|
||||
|
||||
float cell_size;
|
||||
Map<int,NavMesh> navmesh_map;
|
||||
Map<int, NavMesh> navmesh_map;
|
||||
int last_id;
|
||||
|
||||
Vector3 up;
|
||||
void _clip_path(Vector<Vector3>& path,Polygon *from_poly, const Vector3& p_to_point, Polygon* p_to_poly);
|
||||
void _clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly);
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_up_vector(const Vector3& p_up);
|
||||
void set_up_vector(const Vector3 &p_up);
|
||||
Vector3 get_up_vector() const;
|
||||
|
||||
//API should be as dynamic as possible
|
||||
int navmesh_create(const Ref<NavigationMesh>& p_mesh,const Transform& p_xform,Object* p_owner=NULL);
|
||||
void navmesh_set_transform(int p_id, const Transform& p_xform);
|
||||
int navmesh_create(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner = NULL);
|
||||
void navmesh_set_transform(int p_id, const Transform &p_xform);
|
||||
void navmesh_remove(int p_id);
|
||||
|
||||
Vector<Vector3> get_simple_path(const Vector3& p_start, const Vector3& p_end,bool p_optimize=true);
|
||||
Vector3 get_closest_point_to_segment(const Vector3& p_from,const Vector3& p_to,const bool& p_use_collision=false);
|
||||
Vector3 get_closest_point(const Vector3& p_point);
|
||||
Vector3 get_closest_point_normal(const Vector3& p_point);
|
||||
Object* get_closest_point_owner(const Vector3& p_point);
|
||||
Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true);
|
||||
Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision = false);
|
||||
Vector3 get_closest_point(const Vector3 &p_point);
|
||||
Vector3 get_closest_point_normal(const Vector3 &p_point);
|
||||
Object *get_closest_point_owner(const Vector3 &p_point);
|
||||
|
||||
Navigation();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,23 +27,22 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "navigation_mesh.h"
|
||||
#include "navigation.h"
|
||||
#include "mesh_instance.h"
|
||||
#include "navigation.h"
|
||||
|
||||
void NavigationMesh::create_from_mesh(const Ref<Mesh>& p_mesh) {
|
||||
void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
|
||||
|
||||
|
||||
vertices=DVector<Vector3>();
|
||||
vertices = DVector<Vector3>();
|
||||
clear_polygons();
|
||||
|
||||
for(int i=0;i<p_mesh->get_surface_count();i++) {
|
||||
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
|
||||
|
||||
if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES)
|
||||
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
|
||||
continue;
|
||||
Array arr = p_mesh->surface_get_arrays(i);
|
||||
DVector<Vector3> varr = arr[Mesh::ARRAY_VERTEX];
|
||||
DVector<int> iarr = arr[Mesh::ARRAY_INDEX];
|
||||
if (varr.size()==0 || iarr.size()==0)
|
||||
if (varr.size() == 0 || iarr.size() == 0)
|
||||
continue;
|
||||
|
||||
int from = vertices.size();
|
||||
|
|
@ -51,34 +50,33 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh>& p_mesh) {
|
|||
int rlen = iarr.size();
|
||||
DVector<int>::Read r = iarr.read();
|
||||
|
||||
for(int j=0;j<rlen;j+=3) {
|
||||
for (int j = 0; j < rlen; j += 3) {
|
||||
Vector<int> vi;
|
||||
vi.resize(3);
|
||||
vi[0]=r[j+0]+from;
|
||||
vi[1]=r[j+1]+from;
|
||||
vi[2]=r[j+2]+from;
|
||||
vi[0] = r[j + 0] + from;
|
||||
vi[1] = r[j + 1] + from;
|
||||
vi[2] = r[j + 2] + from;
|
||||
|
||||
add_polygon(vi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMesh::set_vertices(const DVector<Vector3>& p_vertices) {
|
||||
void NavigationMesh::set_vertices(const DVector<Vector3> &p_vertices) {
|
||||
|
||||
vertices=p_vertices;
|
||||
vertices = p_vertices;
|
||||
}
|
||||
|
||||
DVector<Vector3> NavigationMesh::get_vertices() const{
|
||||
DVector<Vector3> NavigationMesh::get_vertices() const {
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
void NavigationMesh::_set_polygons(const Array& p_array) {
|
||||
void NavigationMesh::_set_polygons(const Array &p_array) {
|
||||
|
||||
polygons.resize(p_array.size());
|
||||
for(int i=0;i<p_array.size();i++) {
|
||||
polygons[i].indices=p_array[i];
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
polygons[i].indices = p_array[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,31 +84,29 @@ Array NavigationMesh::_get_polygons() const {
|
|||
|
||||
Array ret;
|
||||
ret.resize(polygons.size());
|
||||
for(int i=0;i<ret.size();i++) {
|
||||
ret[i]=polygons[i].indices;
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret[i] = polygons[i].indices;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void NavigationMesh::add_polygon(const Vector<int>& p_polygon){
|
||||
void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
|
||||
|
||||
Polygon polygon;
|
||||
polygon.indices=p_polygon;
|
||||
polygon.indices = p_polygon;
|
||||
polygons.push_back(polygon);
|
||||
|
||||
}
|
||||
int NavigationMesh::get_polygon_count() const{
|
||||
int NavigationMesh::get_polygon_count() const {
|
||||
|
||||
return polygons.size();
|
||||
}
|
||||
Vector<int> NavigationMesh::get_polygon(int p_idx){
|
||||
Vector<int> NavigationMesh::get_polygon(int p_idx) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,polygons.size(),Vector<int>());
|
||||
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
|
||||
return polygons[p_idx].indices;
|
||||
}
|
||||
void NavigationMesh::clear_polygons(){
|
||||
void NavigationMesh::clear_polygons() {
|
||||
|
||||
polygons.clear();
|
||||
}
|
||||
|
|
@ -120,64 +116,59 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
|
|||
if (debug_mesh.is_valid())
|
||||
return debug_mesh;
|
||||
|
||||
|
||||
|
||||
DVector<Vector3> vertices = get_vertices();
|
||||
DVector<Vector3>::Read vr=vertices.read();
|
||||
DVector<Vector3>::Read vr = vertices.read();
|
||||
List<Face3> faces;
|
||||
for(int i=0;i<get_polygon_count();i++) {
|
||||
for (int i = 0; i < get_polygon_count(); i++) {
|
||||
Vector<int> p = get_polygon(i);
|
||||
|
||||
for(int j=2;j<p.size();j++) {
|
||||
for (int j = 2; j < p.size(); j++) {
|
||||
Face3 f;
|
||||
f.vertex[0]=vr[p[0]];
|
||||
f.vertex[1]=vr[p[j-1]];
|
||||
f.vertex[2]=vr[p[j]];
|
||||
f.vertex[0] = vr[p[0]];
|
||||
f.vertex[1] = vr[p[j - 1]];
|
||||
f.vertex[2] = vr[p[j]];
|
||||
|
||||
faces.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Map<_EdgeKey,bool> edge_map;
|
||||
Map<_EdgeKey, bool> edge_map;
|
||||
DVector<Vector3> tmeshfaces;
|
||||
tmeshfaces.resize(faces.size()*3);
|
||||
tmeshfaces.resize(faces.size() * 3);
|
||||
|
||||
{
|
||||
DVector<Vector3>::Write tw=tmeshfaces.write();
|
||||
int tidx=0;
|
||||
DVector<Vector3>::Write tw = tmeshfaces.write();
|
||||
int tidx = 0;
|
||||
|
||||
|
||||
for(List<Face3>::Element *E=faces.front();E;E=E->next()) {
|
||||
for (List<Face3>::Element *E = faces.front(); E; E = E->next()) {
|
||||
|
||||
const Face3 &f = E->get();
|
||||
|
||||
for(int j=0;j<3;j++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
|
||||
tw[tidx++]=f.vertex[j];
|
||||
tw[tidx++] = f.vertex[j];
|
||||
_EdgeKey ek;
|
||||
ek.from=f.vertex[j].snapped(CMP_EPSILON);
|
||||
ek.to=f.vertex[(j+1)%3].snapped(CMP_EPSILON);
|
||||
if (ek.from<ek.to)
|
||||
SWAP(ek.from,ek.to);
|
||||
ek.from = f.vertex[j].snapped(CMP_EPSILON);
|
||||
ek.to = f.vertex[(j + 1) % 3].snapped(CMP_EPSILON);
|
||||
if (ek.from < ek.to)
|
||||
SWAP(ek.from, ek.to);
|
||||
|
||||
Map<_EdgeKey,bool>::Element *E=edge_map.find(ek);
|
||||
Map<_EdgeKey, bool>::Element *E = edge_map.find(ek);
|
||||
|
||||
if (E) {
|
||||
|
||||
E->get()=false;
|
||||
E->get() = false;
|
||||
|
||||
} else {
|
||||
|
||||
edge_map[ek]=true;
|
||||
edge_map[ek] = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Vector3> lines;
|
||||
|
||||
for(Map<_EdgeKey,bool>::Element *E=edge_map.front();E;E=E->next()) {
|
||||
for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
|
||||
|
||||
if (E->get()) {
|
||||
lines.push_back(E->key().from);
|
||||
|
|
@ -189,58 +180,57 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
|
|||
varr.resize(lines.size());
|
||||
{
|
||||
DVector<Vector3>::Write w = varr.write();
|
||||
int idx=0;
|
||||
for(List<Vector3>::Element *E=lines.front();E;E=E->next()) {
|
||||
w[idx++]=E->get();
|
||||
int idx = 0;
|
||||
for (List<Vector3>::Element *E = lines.front(); E; E = E->next()) {
|
||||
w[idx++] = E->get();
|
||||
}
|
||||
}
|
||||
|
||||
debug_mesh = Ref<Mesh>( memnew( Mesh ) );
|
||||
debug_mesh = Ref<Mesh>(memnew(Mesh));
|
||||
|
||||
Array arr;
|
||||
arr.resize(Mesh::ARRAY_MAX);
|
||||
arr[Mesh::ARRAY_VERTEX]=varr;
|
||||
arr[Mesh::ARRAY_VERTEX] = varr;
|
||||
|
||||
debug_mesh->add_surface(Mesh::PRIMITIVE_LINES,arr);
|
||||
debug_mesh->add_surface(Mesh::PRIMITIVE_LINES, arr);
|
||||
|
||||
return debug_mesh;
|
||||
}
|
||||
|
||||
void NavigationMesh::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_vertices","vertices"),&NavigationMesh::set_vertices);
|
||||
ObjectTypeDB::bind_method(_MD("get_vertices"),&NavigationMesh::get_vertices);
|
||||
ObjectTypeDB::bind_method(_MD("set_vertices", "vertices"), &NavigationMesh::set_vertices);
|
||||
ObjectTypeDB::bind_method(_MD("get_vertices"), &NavigationMesh::get_vertices);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_polygon","polygon"),&NavigationMesh::add_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon_count"),&NavigationMesh::get_polygon_count);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon","idx"),&NavigationMesh::get_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("clear_polygons"),&NavigationMesh::clear_polygons);
|
||||
ObjectTypeDB::bind_method(_MD("add_polygon", "polygon"), &NavigationMesh::add_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon_count"), &NavigationMesh::get_polygon_count);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon", "idx"), &NavigationMesh::get_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("clear_polygons"), &NavigationMesh::clear_polygons);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_polygons","polygons"),&NavigationMesh::_set_polygons);
|
||||
ObjectTypeDB::bind_method(_MD("_get_polygons"),&NavigationMesh::_get_polygons);
|
||||
ObjectTypeDB::bind_method(_MD("_set_polygons", "polygons"), &NavigationMesh::_set_polygons);
|
||||
ObjectTypeDB::bind_method(_MD("_get_polygons"), &NavigationMesh::_get_polygons);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3_ARRAY,"vertices",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_vertices"),_SCS("get_vertices"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY,"polygons",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_polygons"),_SCS("_get_polygons"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), _SCS("set_vertices"), _SCS("get_vertices"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), _SCS("_set_polygons"), _SCS("_get_polygons"));
|
||||
}
|
||||
|
||||
NavigationMesh::NavigationMesh() {
|
||||
|
||||
}
|
||||
|
||||
void NavigationMeshInstance::set_enabled(bool p_enabled) {
|
||||
|
||||
if (enabled==p_enabled)
|
||||
if (enabled == p_enabled)
|
||||
return;
|
||||
enabled=p_enabled;
|
||||
enabled = p_enabled;
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
if (!enabled) {
|
||||
|
||||
if (nav_id!=-1) {
|
||||
if (nav_id != -1) {
|
||||
navigation->navmesh_remove(nav_id);
|
||||
nav_id=-1;
|
||||
nav_id = -1;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
|
@ -248,20 +238,18 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) {
|
|||
|
||||
if (navmesh.is_valid()) {
|
||||
|
||||
nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
|
||||
nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (debug_view) {
|
||||
MeshInstance *dm=debug_view->cast_to<MeshInstance>();
|
||||
MeshInstance *dm = debug_view->cast_to<MeshInstance>();
|
||||
if (is_enabled()) {
|
||||
dm->set_material_override( get_tree()->get_debug_navigation_material() );
|
||||
dm->set_material_override(get_tree()->get_debug_navigation_material());
|
||||
} else {
|
||||
dm->set_material_override( get_tree()->get_debug_navigation_disabled_material() );
|
||||
dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update_gizmo();
|
||||
|
|
@ -269,104 +257,96 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) {
|
|||
|
||||
bool NavigationMeshInstance::is_enabled() const {
|
||||
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
void NavigationMeshInstance::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
Spatial *c=this;
|
||||
while(c) {
|
||||
Spatial *c = this;
|
||||
while (c) {
|
||||
|
||||
navigation=c->cast_to<Navigation>();
|
||||
navigation = c->cast_to<Navigation>();
|
||||
if (navigation) {
|
||||
|
||||
if (enabled && navmesh.is_valid()) {
|
||||
|
||||
nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
|
||||
nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
c=c->get_parent_spatial();
|
||||
c = c->get_parent_spatial();
|
||||
}
|
||||
|
||||
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
|
||||
|
||||
MeshInstance *dm = memnew( MeshInstance );
|
||||
dm->set_mesh( navmesh->get_debug_mesh() );
|
||||
MeshInstance *dm = memnew(MeshInstance);
|
||||
dm->set_mesh(navmesh->get_debug_mesh());
|
||||
if (is_enabled()) {
|
||||
dm->set_material_override( get_tree()->get_debug_navigation_material() );
|
||||
dm->set_material_override(get_tree()->get_debug_navigation_material());
|
||||
} else {
|
||||
dm->set_material_override( get_tree()->get_debug_navigation_disabled_material() );
|
||||
dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
|
||||
}
|
||||
add_child(dm);
|
||||
debug_view=dm;
|
||||
debug_view = dm;
|
||||
}
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
if (navigation && nav_id!=-1) {
|
||||
navigation->navmesh_set_transform(nav_id,get_relative_transform(navigation));
|
||||
if (navigation && nav_id != -1) {
|
||||
navigation->navmesh_set_transform(nav_id, get_relative_transform(navigation));
|
||||
}
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
||||
if (navigation) {
|
||||
|
||||
if (nav_id!=-1) {
|
||||
if (nav_id != -1) {
|
||||
navigation->navmesh_remove(nav_id);
|
||||
nav_id=-1;
|
||||
nav_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_view) {
|
||||
debug_view->queue_delete();
|
||||
debug_view=NULL;
|
||||
debug_view = NULL;
|
||||
}
|
||||
navigation=NULL;
|
||||
navigation = NULL;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) {
|
||||
|
||||
void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh>& p_navmesh) {
|
||||
|
||||
if (p_navmesh==navmesh)
|
||||
if (p_navmesh == navmesh)
|
||||
return;
|
||||
|
||||
if (navigation && nav_id!=-1) {
|
||||
if (navigation && nav_id != -1) {
|
||||
navigation->navmesh_remove(nav_id);
|
||||
nav_id=-1;
|
||||
nav_id = -1;
|
||||
}
|
||||
navmesh=p_navmesh;
|
||||
navmesh = p_navmesh;
|
||||
|
||||
if (navigation && navmesh.is_valid() && enabled) {
|
||||
nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
|
||||
nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this);
|
||||
}
|
||||
|
||||
|
||||
if (debug_view && navmesh.is_valid()) {
|
||||
debug_view->cast_to<MeshInstance>()->set_mesh( navmesh->get_debug_mesh() );
|
||||
debug_view->cast_to<MeshInstance>()->set_mesh(navmesh->get_debug_mesh());
|
||||
}
|
||||
|
||||
|
||||
update_gizmo();
|
||||
update_configuration_warning();
|
||||
|
||||
}
|
||||
|
||||
Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const{
|
||||
Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const {
|
||||
|
||||
return navmesh;
|
||||
}
|
||||
|
|
@ -379,36 +359,34 @@ String NavigationMeshInstance::get_configuration_warning() const {
|
|||
if (!navmesh.is_valid()) {
|
||||
return TTR("A NavigationMesh resource must be set or created for this node to work.");
|
||||
}
|
||||
const Spatial *c=this;
|
||||
while(c) {
|
||||
const Spatial *c = this;
|
||||
while (c) {
|
||||
|
||||
if (c->cast_to<Navigation>())
|
||||
return String();
|
||||
|
||||
c=c->get_parent()->cast_to<Spatial>();
|
||||
c = c->get_parent()->cast_to<Spatial>();
|
||||
}
|
||||
|
||||
return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data.");
|
||||
}
|
||||
|
||||
|
||||
void NavigationMeshInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_navigation_mesh","navmesh"),&NavigationMeshInstance::set_navigation_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_navigation_mesh"),&NavigationMeshInstance::get_navigation_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh);
|
||||
ObjectTypeDB::bind_method(_MD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&NavigationMeshInstance::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"),&NavigationMeshInstance::is_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"), &NavigationMeshInstance::is_enabled);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"navmesh",PROPERTY_HINT_RESOURCE_TYPE,"NavigationMesh"),_SCS("set_navigation_mesh"),_SCS("get_navigation_mesh"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), _SCS("set_navigation_mesh"), _SCS("get_navigation_mesh"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
|
||||
}
|
||||
|
||||
NavigationMeshInstance::NavigationMeshInstance() {
|
||||
|
||||
debug_view=NULL;
|
||||
navigation=NULL;
|
||||
nav_id=-1;
|
||||
enabled=true;
|
||||
|
||||
debug_view = NULL;
|
||||
navigation = NULL;
|
||||
nav_id = -1;
|
||||
enabled = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@
|
|||
|
||||
class Mesh;
|
||||
|
||||
class NavigationMesh : public Resource {
|
||||
class NavigationMesh : public Resource {
|
||||
|
||||
OBJ_TYPE( NavigationMesh, Resource );
|
||||
OBJ_TYPE(NavigationMesh, Resource);
|
||||
|
||||
DVector<Vector3> vertices;
|
||||
struct Polygon {
|
||||
|
|
@ -50,25 +50,22 @@ class NavigationMesh : public Resource {
|
|||
Vector3 from;
|
||||
Vector3 to;
|
||||
|
||||
bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; }
|
||||
bool operator<(const _EdgeKey &p_with) const { return from == p_with.from ? to < p_with.to : from < p_with.from; }
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
void _set_polygons(const Array& p_array);
|
||||
void _set_polygons(const Array &p_array);
|
||||
Array _get_polygons() const;
|
||||
|
||||
public:
|
||||
void create_from_mesh(const Ref<Mesh> &p_mesh);
|
||||
|
||||
void create_from_mesh(const Ref<Mesh>& p_mesh);
|
||||
|
||||
void set_vertices(const DVector<Vector3>& p_vertices);
|
||||
void set_vertices(const DVector<Vector3> &p_vertices);
|
||||
DVector<Vector3> get_vertices() const;
|
||||
|
||||
void add_polygon(const Vector<int>& p_polygon);
|
||||
void add_polygon(const Vector<int> &p_polygon);
|
||||
int get_polygon_count() const;
|
||||
Vector<int> get_polygon(int p_idx);
|
||||
void clear_polygons();
|
||||
|
|
@ -78,12 +75,11 @@ public:
|
|||
NavigationMesh();
|
||||
};
|
||||
|
||||
|
||||
class Navigation;
|
||||
|
||||
class NavigationMeshInstance : public Spatial {
|
||||
|
||||
OBJ_TYPE(NavigationMeshInstance,Spatial);
|
||||
OBJ_TYPE(NavigationMeshInstance, Spatial);
|
||||
|
||||
bool enabled;
|
||||
int nav_id;
|
||||
|
|
@ -93,17 +89,14 @@ class NavigationMeshInstance : public Spatial {
|
|||
Node *debug_view;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void set_navigation_mesh(const Ref<NavigationMesh>& p_navmesh);
|
||||
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
|
||||
Ref<NavigationMesh> get_navigation_mesh() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
|
@ -111,5 +104,4 @@ public:
|
|||
NavigationMeshInstance();
|
||||
};
|
||||
|
||||
|
||||
#endif // NAVIGATION_MESH_H
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "particles.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
/*
|
||||
static const char* _var_names[Particles::VAR_MAX]={
|
||||
|
|
@ -47,7 +47,7 @@ static const char* _var_names[Particles::VAR_MAX]={
|
|||
"vars/height_speed_scale",
|
||||
};
|
||||
*/
|
||||
static const char* _rand_names[Particles::VAR_MAX]={
|
||||
static const char *_rand_names[Particles::VAR_MAX] = {
|
||||
"rand/lifetime",
|
||||
"rand/spread",
|
||||
"rand/gravity",
|
||||
|
|
@ -64,7 +64,7 @@ static const char* _rand_names[Particles::VAR_MAX]={
|
|||
"rand/height_speed_scale",
|
||||
};
|
||||
|
||||
static const Particles::Variable _var_indices[Particles::VAR_MAX]={
|
||||
static const Particles::Variable _var_indices[Particles::VAR_MAX] = {
|
||||
Particles::VAR_LIFETIME,
|
||||
Particles::VAR_SPREAD,
|
||||
Particles::VAR_GRAVITY,
|
||||
|
|
@ -81,23 +81,20 @@ static const Particles::Variable _var_indices[Particles::VAR_MAX]={
|
|||
Particles::VAR_HEIGHT_SPEED_SCALE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
AABB Particles::get_aabb() const {
|
||||
|
||||
return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
|
||||
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
}
|
||||
DVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
return DVector<Face3>();
|
||||
}
|
||||
|
||||
|
||||
void Particles::set_amount(int p_amount) {
|
||||
|
||||
ERR_FAIL_INDEX(p_amount,1024);
|
||||
amount=p_amount;
|
||||
VisualServer::get_singleton()->particles_set_amount(particles,p_amount);
|
||||
ERR_FAIL_INDEX(p_amount, 1024);
|
||||
amount = p_amount;
|
||||
VisualServer::get_singleton()->particles_set_amount(particles, p_amount);
|
||||
}
|
||||
int Particles::get_amount() const {
|
||||
|
||||
|
|
@ -106,8 +103,8 @@ int Particles::get_amount() const {
|
|||
|
||||
void Particles::set_emitting(bool p_emitting) {
|
||||
|
||||
emitting=p_emitting;
|
||||
VisualServer::get_singleton()->particles_set_emitting(particles,p_emitting);
|
||||
emitting = p_emitting;
|
||||
VisualServer::get_singleton()->particles_set_emitting(particles, p_emitting);
|
||||
|
||||
setup_timer();
|
||||
}
|
||||
|
|
@ -116,23 +113,21 @@ bool Particles::is_emitting() const {
|
|||
return emitting;
|
||||
}
|
||||
|
||||
void Particles::set_visibility_aabb(const AABB& p_aabb) {
|
||||
void Particles::set_visibility_aabb(const AABB &p_aabb) {
|
||||
|
||||
visibility_aabb=p_aabb;
|
||||
VisualServer::get_singleton()->particles_set_visibility_aabb(particles,p_aabb);
|
||||
visibility_aabb = p_aabb;
|
||||
VisualServer::get_singleton()->particles_set_visibility_aabb(particles, p_aabb);
|
||||
update_gizmo();
|
||||
|
||||
}
|
||||
AABB Particles::get_visibility_aabb() const {
|
||||
|
||||
return visibility_aabb;
|
||||
}
|
||||
|
||||
|
||||
void Particles::set_emission_points(const DVector<Vector3>& p_points) {
|
||||
void Particles::set_emission_points(const DVector<Vector3> &p_points) {
|
||||
|
||||
using_points = p_points.size();
|
||||
VisualServer::get_singleton()->particles_set_emission_points(particles,p_points);
|
||||
VisualServer::get_singleton()->particles_set_emission_points(particles, p_points);
|
||||
}
|
||||
|
||||
DVector<Vector3> Particles::get_emission_points() const {
|
||||
|
|
@ -141,14 +136,12 @@ DVector<Vector3> Particles::get_emission_points() const {
|
|||
return DVector<Vector3>();
|
||||
|
||||
return VisualServer::get_singleton()->particles_get_emission_points(particles);
|
||||
|
||||
}
|
||||
|
||||
void Particles::set_emission_half_extents(const Vector3& p_half_extents) {
|
||||
|
||||
emission_half_extents=p_half_extents;
|
||||
VisualServer::get_singleton()->particles_set_emission_half_extents(particles,p_half_extents);
|
||||
void Particles::set_emission_half_extents(const Vector3 &p_half_extents) {
|
||||
|
||||
emission_half_extents = p_half_extents;
|
||||
VisualServer::get_singleton()->particles_set_emission_half_extents(particles, p_half_extents);
|
||||
}
|
||||
|
||||
Vector3 Particles::get_emission_half_extents() const {
|
||||
|
|
@ -156,11 +149,10 @@ Vector3 Particles::get_emission_half_extents() const {
|
|||
return emission_half_extents;
|
||||
}
|
||||
|
||||
void Particles::set_emission_base_velocity(const Vector3& p_base_velocity) {
|
||||
|
||||
emission_base_velocity=p_base_velocity;
|
||||
VisualServer::get_singleton()->particles_set_emission_base_velocity(particles,p_base_velocity);
|
||||
void Particles::set_emission_base_velocity(const Vector3 &p_base_velocity) {
|
||||
|
||||
emission_base_velocity = p_base_velocity;
|
||||
VisualServer::get_singleton()->particles_set_emission_base_velocity(particles, p_base_velocity);
|
||||
}
|
||||
|
||||
Vector3 Particles::get_emission_base_velocity() const {
|
||||
|
|
@ -168,84 +160,76 @@ Vector3 Particles::get_emission_base_velocity() const {
|
|||
return emission_base_velocity;
|
||||
}
|
||||
|
||||
void Particles::set_gravity_normal(const Vector3& p_normal) {
|
||||
void Particles::set_gravity_normal(const Vector3 &p_normal) {
|
||||
|
||||
gravity_normal=p_normal;
|
||||
VisualServer::get_singleton()->particles_set_gravity_normal(particles,p_normal);
|
||||
gravity_normal = p_normal;
|
||||
VisualServer::get_singleton()->particles_set_gravity_normal(particles, p_normal);
|
||||
}
|
||||
|
||||
Vector3 Particles::get_gravity_normal() const {
|
||||
|
||||
return gravity_normal;
|
||||
|
||||
}
|
||||
|
||||
void Particles::set_variable(Variable p_variable,float p_value) {
|
||||
void Particles::set_variable(Variable p_variable, float p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_variable,VAR_MAX);
|
||||
var[p_variable]=p_value;
|
||||
VisualServer::get_singleton()->particles_set_variable(particles,(VS::ParticleVariable)p_variable,p_value);
|
||||
if (p_variable==VAR_SPREAD)
|
||||
ERR_FAIL_INDEX(p_variable, VAR_MAX);
|
||||
var[p_variable] = p_value;
|
||||
VisualServer::get_singleton()->particles_set_variable(particles, (VS::ParticleVariable)p_variable, p_value);
|
||||
if (p_variable == VAR_SPREAD)
|
||||
update_gizmo();
|
||||
}
|
||||
|
||||
float Particles::get_variable(Variable p_variable) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_variable,VAR_MAX,-1);
|
||||
ERR_FAIL_INDEX_V(p_variable, VAR_MAX, -1);
|
||||
return var[p_variable];
|
||||
|
||||
}
|
||||
|
||||
void Particles::set_randomness(Variable p_variable,float p_randomness) {
|
||||
|
||||
ERR_FAIL_INDEX(p_variable,VAR_MAX);
|
||||
var_random[p_variable]=p_randomness;
|
||||
VisualServer::get_singleton()->particles_set_randomness(particles,(VS::ParticleVariable)p_variable,p_randomness);
|
||||
void Particles::set_randomness(Variable p_variable, float p_randomness) {
|
||||
|
||||
ERR_FAIL_INDEX(p_variable, VAR_MAX);
|
||||
var_random[p_variable] = p_randomness;
|
||||
VisualServer::get_singleton()->particles_set_randomness(particles, (VS::ParticleVariable)p_variable, p_randomness);
|
||||
}
|
||||
float Particles::get_randomness(Variable p_variable) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_variable,VAR_MAX,-1);
|
||||
ERR_FAIL_INDEX_V(p_variable, VAR_MAX, -1);
|
||||
return var_random[p_variable];
|
||||
|
||||
}
|
||||
|
||||
void Particles::set_color_phase_pos(int p_phase, float p_pos) {
|
||||
|
||||
ERR_FAIL_INDEX(p_phase,VS::MAX_PARTICLE_COLOR_PHASES);
|
||||
color_phase[p_phase].pos=p_pos;
|
||||
VisualServer::get_singleton()->particles_set_color_phase_pos(particles,p_phase,p_pos);
|
||||
|
||||
ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
|
||||
color_phase[p_phase].pos = p_pos;
|
||||
VisualServer::get_singleton()->particles_set_color_phase_pos(particles, p_phase, p_pos);
|
||||
}
|
||||
float Particles::get_color_phase_pos(int p_phase) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_phase,VS::MAX_PARTICLE_COLOR_PHASES,-1);
|
||||
ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, -1);
|
||||
return color_phase[p_phase].pos;
|
||||
}
|
||||
|
||||
void Particles::set_color_phase_color(int p_phase, const Color& p_color) {
|
||||
|
||||
ERR_FAIL_INDEX(p_phase,VS::MAX_PARTICLE_COLOR_PHASES);
|
||||
color_phase[p_phase].color=p_color;
|
||||
VisualServer::get_singleton()->particles_set_color_phase_color(particles,p_phase,p_color);
|
||||
void Particles::set_color_phase_color(int p_phase, const Color &p_color) {
|
||||
|
||||
ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
|
||||
color_phase[p_phase].color = p_color;
|
||||
VisualServer::get_singleton()->particles_set_color_phase_color(particles, p_phase, p_color);
|
||||
}
|
||||
Color Particles::get_color_phase_color(int p_phase) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_phase,VS::MAX_PARTICLE_COLOR_PHASES,Color());
|
||||
ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, Color());
|
||||
return color_phase[p_phase].color;
|
||||
|
||||
}
|
||||
|
||||
void Particles::set_material(const Ref<Material>& p_material) {
|
||||
void Particles::set_material(const Ref<Material> &p_material) {
|
||||
|
||||
material=p_material;
|
||||
if(material.is_null()) {
|
||||
VisualServer::get_singleton()->particles_set_material(particles,RID());
|
||||
material = p_material;
|
||||
if (material.is_null()) {
|
||||
VisualServer::get_singleton()->particles_set_material(particles, RID());
|
||||
} else {
|
||||
VisualServer::get_singleton()->particles_set_material(particles,material->get_rid());
|
||||
VisualServer::get_singleton()->particles_set_material(particles, material->get_rid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Particles::setup_timer() {
|
||||
|
|
@ -269,7 +253,6 @@ float Particles::get_emit_timeout() const {
|
|||
return emit_timeout;
|
||||
};
|
||||
|
||||
|
||||
Ref<Material> Particles::get_material() const {
|
||||
|
||||
return material;
|
||||
|
|
@ -277,8 +260,8 @@ Ref<Material> Particles::get_material() const {
|
|||
|
||||
void Particles::set_height_from_velocity(bool p_enable) {
|
||||
|
||||
height_from_velocity=p_enable;
|
||||
VisualServer::get_singleton()->particles_set_height_from_velocity(particles,height_from_velocity);
|
||||
height_from_velocity = p_enable;
|
||||
VisualServer::get_singleton()->particles_set_height_from_velocity(particles, height_from_velocity);
|
||||
}
|
||||
|
||||
bool Particles::has_height_from_velocity() const {
|
||||
|
|
@ -288,11 +271,11 @@ bool Particles::has_height_from_velocity() const {
|
|||
|
||||
void Particles::set_color_phases(int p_phases) {
|
||||
|
||||
color_phase_count=p_phases;
|
||||
VisualServer::get_singleton()->particles_set_color_phases(particles,p_phases);
|
||||
color_phase_count = p_phases;
|
||||
VisualServer::get_singleton()->particles_set_color_phases(particles, p_phases);
|
||||
}
|
||||
|
||||
int Particles::get_color_phases() const{
|
||||
int Particles::get_color_phases() const {
|
||||
|
||||
return color_phase_count;
|
||||
}
|
||||
|
|
@ -304,53 +287,51 @@ bool Particles::_can_gizmo_scale() const {
|
|||
|
||||
void Particles::set_use_local_coordinates(bool p_use) {
|
||||
|
||||
local_coordinates=p_use;
|
||||
VisualServer::get_singleton()->particles_set_use_local_coordinates(particles,local_coordinates);
|
||||
local_coordinates = p_use;
|
||||
VisualServer::get_singleton()->particles_set_use_local_coordinates(particles, local_coordinates);
|
||||
}
|
||||
|
||||
bool Particles::is_using_local_coordinates() const{
|
||||
bool Particles::is_using_local_coordinates() const {
|
||||
|
||||
return local_coordinates;
|
||||
}
|
||||
|
||||
|
||||
RES Particles::_get_gizmo_geometry() const {
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) );
|
||||
mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
|
||||
mat->set_blend_mode( Material::BLEND_MODE_ADD );
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.0, 0.6, 0.7, 0.2));
|
||||
mat->set_parameter(FixedMaterial::PARAM_EMISSION, Color(0.5, 0.7, 0.8));
|
||||
mat->set_blend_mode(Material::BLEND_MODE_ADD);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
surface_tool->set_material(mat);
|
||||
|
||||
int sides=16;
|
||||
int sections=24;
|
||||
int sides = 16;
|
||||
int sections = 24;
|
||||
|
||||
// float len=1;
|
||||
float deg=Math::deg2rad(var[VAR_SPREAD]*180);
|
||||
if (deg==180)
|
||||
deg=179.5;
|
||||
// float len=1;
|
||||
float deg = Math::deg2rad(var[VAR_SPREAD] * 180);
|
||||
if (deg == 180)
|
||||
deg = 179.5;
|
||||
|
||||
Vector3 to=Vector3(0,0,-1);
|
||||
Vector3 to = Vector3(0, 0, -1);
|
||||
|
||||
for(int j=0;j<sections;j++) {
|
||||
for (int j = 0; j < sections; j++) {
|
||||
|
||||
Vector3 p1=Matrix3(Vector3(1,0,0),deg*j/sections).xform(to);
|
||||
Vector3 p2=Matrix3(Vector3(1,0,0),deg*(j+1)/sections).xform(to);
|
||||
Vector3 p1 = Matrix3(Vector3(1, 0, 0), deg * j / sections).xform(to);
|
||||
Vector3 p2 = Matrix3(Vector3(1, 0, 0), deg * (j + 1) / sections).xform(to);
|
||||
|
||||
for(int i=0;i<sides;i++) {
|
||||
for (int i = 0; i < sides; i++) {
|
||||
|
||||
Vector3 p1r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p1);
|
||||
Vector3 p1s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p1);
|
||||
Vector3 p2s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p2);
|
||||
Vector3 p2r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p2);
|
||||
Vector3 p1r = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i) / sides).xform(p1);
|
||||
Vector3 p1s = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / sides).xform(p1);
|
||||
Vector3 p2s = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / sides).xform(p2);
|
||||
Vector3 p2r = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i) / sides).xform(p2);
|
||||
|
||||
surface_tool->add_normal(p1r.normalized());
|
||||
surface_tool->add_vertex(p1r);
|
||||
|
|
@ -366,135 +347,129 @@ RES Particles::_get_gizmo_geometry() const {
|
|||
surface_tool->add_normal(p2r.normalized());
|
||||
surface_tool->add_vertex(p2r);
|
||||
|
||||
if (j==sections-1) {
|
||||
if (j == sections - 1) {
|
||||
|
||||
surface_tool->add_normal(p2r.normalized());
|
||||
surface_tool->add_vertex(p2r);
|
||||
surface_tool->add_normal(p2s.normalized());
|
||||
surface_tool->add_vertex(p2s);
|
||||
surface_tool->add_normal(Vector3(0,0,1));
|
||||
surface_tool->add_normal(Vector3(0, 0, 1));
|
||||
surface_tool->add_vertex(Vector3());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ref<Mesh> mesh = surface_tool->commit();
|
||||
|
||||
Ref<FixedMaterial> mat_aabb( memnew( FixedMaterial ));
|
||||
Ref<FixedMaterial> mat_aabb(memnew(FixedMaterial));
|
||||
|
||||
mat_aabb->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) );
|
||||
mat_aabb->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.8, 0.8, 0.9, 0.7));
|
||||
mat_aabb->set_line_width(3);
|
||||
mat_aabb->set_flag( Material::FLAG_UNSHADED, true );
|
||||
mat_aabb->set_flag(Material::FLAG_UNSHADED, true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(mat_aabb);
|
||||
|
||||
for(int i=0;i<12;i++) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
|
||||
Vector3 f,t;
|
||||
visibility_aabb.get_edge(i,f,t);
|
||||
Vector3 f, t;
|
||||
visibility_aabb.get_edge(i, f, t);
|
||||
surface_tool->add_vertex(f);
|
||||
surface_tool->add_vertex(t);
|
||||
}
|
||||
|
||||
return surface_tool->commit(mesh);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Particles::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_amount","amount"),&Particles::set_amount);
|
||||
ObjectTypeDB::bind_method(_MD("get_amount"),&Particles::get_amount);
|
||||
ObjectTypeDB::bind_method(_MD("set_emitting","enabled"),&Particles::set_emitting);
|
||||
ObjectTypeDB::bind_method(_MD("is_emitting"),&Particles::is_emitting);
|
||||
ObjectTypeDB::bind_method(_MD("set_visibility_aabb","aabb"),&Particles::set_visibility_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_visibility_aabb"),&Particles::get_visibility_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_half_extents","half_extents"),&Particles::set_emission_half_extents);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_half_extents"),&Particles::get_emission_half_extents);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_base_velocity","base_velocity"),&Particles::set_emission_base_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_base_velocity"),&Particles::get_emission_base_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_points","points"),&Particles::set_emission_points);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_points"),&Particles::get_emission_points);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_normal","normal"),&Particles::set_gravity_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_normal"),&Particles::get_gravity_normal);
|
||||
ObjectTypeDB::bind_method(_MD("set_variable","variable","value"),&Particles::set_variable);
|
||||
ObjectTypeDB::bind_method(_MD("get_variable","variable"),&Particles::get_variable);
|
||||
ObjectTypeDB::bind_method(_MD("set_randomness","variable","randomness"),&Particles::set_randomness);
|
||||
ObjectTypeDB::bind_method(_MD("get_randomness","variable"),&Particles::get_randomness);
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phase_pos","phase","pos"),&Particles::set_color_phase_pos);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phase_pos","phase"),&Particles::get_color_phase_pos);
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phase_color","phase","color"),&Particles::set_color_phase_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phase_color","phase"),&Particles::get_color_phase_color);
|
||||
ObjectTypeDB::bind_method(_MD("set_material","material:Material"),&Particles::set_material);
|
||||
ObjectTypeDB::bind_method(_MD("get_material:Material"),&Particles::get_material);
|
||||
ObjectTypeDB::bind_method(_MD("set_emit_timeout","timeout"),&Particles::set_emit_timeout);
|
||||
ObjectTypeDB::bind_method(_MD("get_emit_timeout"),&Particles::get_emit_timeout);
|
||||
ObjectTypeDB::bind_method(_MD("set_height_from_velocity","enable"),&Particles::set_height_from_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("has_height_from_velocity"),&Particles::has_height_from_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("set_use_local_coordinates","enable"),&Particles::set_use_local_coordinates);
|
||||
ObjectTypeDB::bind_method(_MD("is_using_local_coordinates"),&Particles::is_using_local_coordinates);
|
||||
ObjectTypeDB::bind_method(_MD("set_amount", "amount"), &Particles::set_amount);
|
||||
ObjectTypeDB::bind_method(_MD("get_amount"), &Particles::get_amount);
|
||||
ObjectTypeDB::bind_method(_MD("set_emitting", "enabled"), &Particles::set_emitting);
|
||||
ObjectTypeDB::bind_method(_MD("is_emitting"), &Particles::is_emitting);
|
||||
ObjectTypeDB::bind_method(_MD("set_visibility_aabb", "aabb"), &Particles::set_visibility_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_visibility_aabb"), &Particles::get_visibility_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_half_extents", "half_extents"), &Particles::set_emission_half_extents);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_half_extents"), &Particles::get_emission_half_extents);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_base_velocity", "base_velocity"), &Particles::set_emission_base_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_base_velocity"), &Particles::get_emission_base_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("set_emission_points", "points"), &Particles::set_emission_points);
|
||||
ObjectTypeDB::bind_method(_MD("get_emission_points"), &Particles::get_emission_points);
|
||||
ObjectTypeDB::bind_method(_MD("set_gravity_normal", "normal"), &Particles::set_gravity_normal);
|
||||
ObjectTypeDB::bind_method(_MD("get_gravity_normal"), &Particles::get_gravity_normal);
|
||||
ObjectTypeDB::bind_method(_MD("set_variable", "variable", "value"), &Particles::set_variable);
|
||||
ObjectTypeDB::bind_method(_MD("get_variable", "variable"), &Particles::get_variable);
|
||||
ObjectTypeDB::bind_method(_MD("set_randomness", "variable", "randomness"), &Particles::set_randomness);
|
||||
ObjectTypeDB::bind_method(_MD("get_randomness", "variable"), &Particles::get_randomness);
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phase_pos", "phase", "pos"), &Particles::set_color_phase_pos);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phase_pos", "phase"), &Particles::get_color_phase_pos);
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phase_color", "phase", "color"), &Particles::set_color_phase_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phase_color", "phase"), &Particles::get_color_phase_color);
|
||||
ObjectTypeDB::bind_method(_MD("set_material", "material:Material"), &Particles::set_material);
|
||||
ObjectTypeDB::bind_method(_MD("get_material:Material"), &Particles::get_material);
|
||||
ObjectTypeDB::bind_method(_MD("set_emit_timeout", "timeout"), &Particles::set_emit_timeout);
|
||||
ObjectTypeDB::bind_method(_MD("get_emit_timeout"), &Particles::get_emit_timeout);
|
||||
ObjectTypeDB::bind_method(_MD("set_height_from_velocity", "enable"), &Particles::set_height_from_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("has_height_from_velocity"), &Particles::has_height_from_velocity);
|
||||
ObjectTypeDB::bind_method(_MD("set_use_local_coordinates", "enable"), &Particles::set_use_local_coordinates);
|
||||
ObjectTypeDB::bind_method(_MD("is_using_local_coordinates"), &Particles::is_using_local_coordinates);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phases","count"),&Particles::set_color_phases);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phases"),&Particles::get_color_phases);
|
||||
ObjectTypeDB::bind_method(_MD("set_color_phases", "count"), &Particles::set_color_phases);
|
||||
ObjectTypeDB::bind_method(_MD("get_color_phases"), &Particles::get_color_phases);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material" ), _SCS("set_material"), _SCS("get_material") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), _SCS("set_material"), _SCS("get_material"));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1024,1" ), _SCS("set_amount"), _SCS("get_amount") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "emitting" ), _SCS("set_emitting"), _SCS("is_emitting") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::_AABB, "visibility" ), _SCS("set_visibility_aabb"), _SCS("get_visibility_aabb") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_extents" ), _SCS("set_emission_half_extents"), _SCS("get_emission_half_extents") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_base_velocity" ), _SCS("set_emission_base_velocity"), _SCS("get_emission_base_velocity") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3_ARRAY, "emission_points" ), _SCS("set_emission_points"), _SCS("get_emission_points") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "gravity_normal" ), _SCS("set_gravity_normal"), _SCS("get_gravity_normal") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "local_coords" ), _SCS("set_use_local_coordinates"), _SCS("is_using_local_coordinates") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "emit_timeout",PROPERTY_HINT_RANGE,"0,256,0.01"), _SCS("set_emit_timeout"), _SCS("get_emit_timeout") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1024,1"), _SCS("set_amount"), _SCS("get_amount"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), _SCS("set_emitting"), _SCS("is_emitting"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::_AABB, "visibility"), _SCS("set_visibility_aabb"), _SCS("get_visibility_aabb"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_extents"), _SCS("set_emission_half_extents"), _SCS("get_emission_half_extents"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_base_velocity"), _SCS("set_emission_base_velocity"), _SCS("get_emission_base_velocity"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3_ARRAY, "emission_points"), _SCS("set_emission_points"), _SCS("get_emission_points"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_normal"), _SCS("set_gravity_normal"), _SCS("get_gravity_normal"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), _SCS("set_use_local_coordinates"), _SCS("is_using_local_coordinates"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "emit_timeout", PROPERTY_HINT_RANGE, "0,256,0.01"), _SCS("set_emit_timeout"), _SCS("get_emit_timeout"));
|
||||
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/lifetime", PROPERTY_HINT_RANGE, "0.1,60,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LIFETIME);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/spread", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_SPREAD);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/gravity", PROPERTY_HINT_RANGE, "-48,48,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_GRAVITY);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/linear_vel", PROPERTY_HINT_RANGE, "-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LINEAR_VELOCITY);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/angular_vel", PROPERTY_HINT_RANGE, "-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_ANGULAR_VELOCITY);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LINEAR_ACCELERATION);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_DRAG);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/tan_accel", PROPERTY_HINT_RANGE, "-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_TANGENTIAL_ACCELERATION);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/damping", PROPERTY_HINT_RANGE, "0,128,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_DAMPING);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/initial_size", PROPERTY_HINT_RANGE, "0,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_INITIAL_SIZE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/final_size", PROPERTY_HINT_RANGE, "0,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_FINAL_SIZE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/initial_angle", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_INITIAL_ANGLE);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vars/height_from_velocity"), _SCS("set_height_from_velocity"), _SCS("has_height_from_velocity"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/height", PROPERTY_HINT_RANGE, "0,4096,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_HEIGHT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "vars/height_speed_scale", PROPERTY_HINT_RANGE, "0,4096,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_HEIGHT_SPEED_SCALE);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/lifetime", PROPERTY_HINT_RANGE,"0.1,60,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LIFETIME );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/spread", PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_SPREAD );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/gravity", PROPERTY_HINT_RANGE,"-48,48,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_GRAVITY );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/linear_vel", PROPERTY_HINT_RANGE,"-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LINEAR_VELOCITY );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/angular_vel", PROPERTY_HINT_RANGE,"-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_ANGULAR_VELOCITY );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/linear_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_LINEAR_ACCELERATION );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/radial_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_DRAG );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/tan_accel", PROPERTY_HINT_RANGE,"-100,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_TANGENTIAL_ACCELERATION );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/damping", PROPERTY_HINT_RANGE,"0,128,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_DAMPING );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/initial_size", PROPERTY_HINT_RANGE,"0,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_INITIAL_SIZE );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/final_size", PROPERTY_HINT_RANGE,"0,100,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_FINAL_SIZE );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/initial_angle",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_INITIAL_ANGLE );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "vars/height_from_velocity"), _SCS("set_height_from_velocity"), _SCS("has_height_from_velocity") );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/height",PROPERTY_HINT_RANGE,"0,4096,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_HEIGHT);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "vars/height_speed_scale",PROPERTY_HINT_RANGE,"0,4096,0.01"), _SCS("set_variable"), _SCS("get_variable"), VAR_HEIGHT_SPEED_SCALE );
|
||||
for (int i = 0; i < VAR_MAX; i++)
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, _rand_names[i], PROPERTY_HINT_RANGE, "-16.0,16.0,0.01"), _SCS("set_randomness"), _SCS("get_randomness"), _var_indices[i]);
|
||||
|
||||
for(int i=0;i<VAR_MAX;i++)
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, _rand_names[i], PROPERTY_HINT_RANGE,"-16.0,16.0,0.01"),_SCS("set_randomness"), _SCS("get_randomness"),_var_indices[i] );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "color_phases/count", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_color_phases"), _SCS("get_color_phases"));
|
||||
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1"), _SCS("set_color_phases"), _SCS("get_color_phases"));
|
||||
|
||||
for(int i=0;i<VS::MAX_PARTICLE_COLOR_PHASES;i++) {
|
||||
String phase="phase_"+itos(i)+"/";
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_color_phase_pos"),_SCS("get_color_phase_pos"),i );
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color"),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
|
||||
for (int i = 0; i < VS::MAX_PARTICLE_COLOR_PHASES; i++) {
|
||||
String phase = "phase_" + itos(i) + "/";
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, phase + "pos", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_color_phase_pos"), _SCS("get_color_phase_pos"), i);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::COLOR, phase + "color"), _SCS("set_color_phase_color"), _SCS("get_color_phase_color"), i);
|
||||
}
|
||||
|
||||
BIND_CONSTANT( VAR_LIFETIME );
|
||||
BIND_CONSTANT( VAR_SPREAD );
|
||||
BIND_CONSTANT( VAR_GRAVITY );
|
||||
BIND_CONSTANT( VAR_LINEAR_VELOCITY );
|
||||
BIND_CONSTANT( VAR_ANGULAR_VELOCITY );
|
||||
BIND_CONSTANT( VAR_LINEAR_ACCELERATION );
|
||||
BIND_CONSTANT( VAR_DRAG );
|
||||
BIND_CONSTANT( VAR_TANGENTIAL_ACCELERATION );
|
||||
BIND_CONSTANT( VAR_INITIAL_SIZE );
|
||||
BIND_CONSTANT( VAR_FINAL_SIZE );
|
||||
BIND_CONSTANT( VAR_INITIAL_ANGLE );
|
||||
BIND_CONSTANT( VAR_HEIGHT );
|
||||
BIND_CONSTANT( VAR_HEIGHT_SPEED_SCALE );
|
||||
BIND_CONSTANT( VAR_MAX );
|
||||
|
||||
BIND_CONSTANT(VAR_LIFETIME);
|
||||
BIND_CONSTANT(VAR_SPREAD);
|
||||
BIND_CONSTANT(VAR_GRAVITY);
|
||||
BIND_CONSTANT(VAR_LINEAR_VELOCITY);
|
||||
BIND_CONSTANT(VAR_ANGULAR_VELOCITY);
|
||||
BIND_CONSTANT(VAR_LINEAR_ACCELERATION);
|
||||
BIND_CONSTANT(VAR_DRAG);
|
||||
BIND_CONSTANT(VAR_TANGENTIAL_ACCELERATION);
|
||||
BIND_CONSTANT(VAR_INITIAL_SIZE);
|
||||
BIND_CONSTANT(VAR_FINAL_SIZE);
|
||||
BIND_CONSTANT(VAR_INITIAL_ANGLE);
|
||||
BIND_CONSTANT(VAR_HEIGHT);
|
||||
BIND_CONSTANT(VAR_HEIGHT_SPEED_SCALE);
|
||||
BIND_CONSTANT(VAR_MAX);
|
||||
}
|
||||
|
||||
Particles::Particles() {
|
||||
|
|
@ -506,54 +481,52 @@ Particles::Particles() {
|
|||
|
||||
set_amount(64);
|
||||
set_emitting(true);
|
||||
set_visibility_aabb(AABB( Vector3(-4,-4,-4), Vector3(8,8,8) ) );
|
||||
set_visibility_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)));
|
||||
|
||||
for (int i=0;i<VAR_MAX;i++) {
|
||||
set_randomness((Variable)i,0.0);
|
||||
for (int i = 0; i < VAR_MAX; i++) {
|
||||
set_randomness((Variable)i, 0.0);
|
||||
}
|
||||
|
||||
set_variable( VAR_LIFETIME, 5.0);
|
||||
set_variable( VAR_SPREAD, 0.2);
|
||||
set_variable( VAR_GRAVITY, 9.8);
|
||||
set_variable( VAR_LINEAR_VELOCITY, 0.2);
|
||||
set_variable( VAR_ANGULAR_VELOCITY, 0.0);
|
||||
set_variable( VAR_LINEAR_ACCELERATION, 0.0);
|
||||
set_variable( VAR_DRAG, 0.0);
|
||||
set_variable( VAR_TANGENTIAL_ACCELERATION, 0.0);
|
||||
set_variable( VAR_DAMPING, 0.0);
|
||||
set_variable( VAR_INITIAL_SIZE, 1.0);
|
||||
set_variable( VAR_FINAL_SIZE, 1.0);
|
||||
set_variable( VAR_INITIAL_ANGLE, 0.0);
|
||||
set_variable( VAR_HEIGHT, 1.0);
|
||||
set_variable( VAR_HEIGHT_SPEED_SCALE, 0.0);
|
||||
set_variable(VAR_LIFETIME, 5.0);
|
||||
set_variable(VAR_SPREAD, 0.2);
|
||||
set_variable(VAR_GRAVITY, 9.8);
|
||||
set_variable(VAR_LINEAR_VELOCITY, 0.2);
|
||||
set_variable(VAR_ANGULAR_VELOCITY, 0.0);
|
||||
set_variable(VAR_LINEAR_ACCELERATION, 0.0);
|
||||
set_variable(VAR_DRAG, 0.0);
|
||||
set_variable(VAR_TANGENTIAL_ACCELERATION, 0.0);
|
||||
set_variable(VAR_DAMPING, 0.0);
|
||||
set_variable(VAR_INITIAL_SIZE, 1.0);
|
||||
set_variable(VAR_FINAL_SIZE, 1.0);
|
||||
set_variable(VAR_INITIAL_ANGLE, 0.0);
|
||||
set_variable(VAR_HEIGHT, 1.0);
|
||||
set_variable(VAR_HEIGHT_SPEED_SCALE, 0.0);
|
||||
|
||||
color_phase_count=0;
|
||||
color_phase_count = 0;
|
||||
|
||||
set_color_phase_pos(0,0.0);
|
||||
set_color_phase_pos(1,1.0);
|
||||
set_color_phase_pos(2,1.0);
|
||||
set_color_phase_pos(3,1.0);
|
||||
set_color_phase_pos(0, 0.0);
|
||||
set_color_phase_pos(1, 1.0);
|
||||
set_color_phase_pos(2, 1.0);
|
||||
set_color_phase_pos(3, 1.0);
|
||||
|
||||
set_color_phase_color(0,Color(1,1,1));
|
||||
set_color_phase_color(1,Color(0,0,0));
|
||||
set_color_phase_color(2,Color(0,0,0));
|
||||
set_color_phase_color(3,Color(0,0,0));
|
||||
set_color_phase_color(0, Color(1, 1, 1));
|
||||
set_color_phase_color(1, Color(0, 0, 0));
|
||||
set_color_phase_color(2, Color(0, 0, 0));
|
||||
set_color_phase_color(3, Color(0, 0, 0));
|
||||
|
||||
set_gravity_normal(Vector3(0,-1.0,0));
|
||||
set_emission_half_extents(Vector3(0.1,0.1,0.1));
|
||||
set_gravity_normal(Vector3(0, -1.0, 0));
|
||||
set_emission_half_extents(Vector3(0.1, 0.1, 0.1));
|
||||
|
||||
height_from_velocity=false;
|
||||
height_from_velocity = false;
|
||||
|
||||
Vector<Variant> pars;
|
||||
pars.push_back(false);
|
||||
timer->connect("timeout", this, "set_emitting", pars);
|
||||
set_base(particles);
|
||||
local_coordinates=false;
|
||||
local_coordinates = false;
|
||||
}
|
||||
|
||||
|
||||
Particles::~Particles() {
|
||||
|
||||
VisualServer::get_singleton()->free(particles);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@
|
|||
#ifndef VISUALINSTANCEPARTICLES_H
|
||||
#define VISUALINSTANCEPARTICLES_H
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "scene/resources/material.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "rid.h"
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "scene/resources/material.h"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
|
|
@ -40,27 +40,26 @@
|
|||
|
||||
class Particles : public GeometryInstance {
|
||||
public:
|
||||
|
||||
enum Variable {
|
||||
VAR_LIFETIME=VS::PARTICLE_LIFETIME,
|
||||
VAR_SPREAD=VS::PARTICLE_SPREAD,
|
||||
VAR_GRAVITY=VS::PARTICLE_GRAVITY,
|
||||
VAR_LINEAR_VELOCITY=VS::PARTICLE_LINEAR_VELOCITY,
|
||||
VAR_ANGULAR_VELOCITY=VS::PARTICLE_ANGULAR_VELOCITY,
|
||||
VAR_LINEAR_ACCELERATION=VS::PARTICLE_LINEAR_ACCELERATION,
|
||||
VAR_DRAG=VS::PARTICLE_RADIAL_ACCELERATION,
|
||||
VAR_TANGENTIAL_ACCELERATION=VS::PARTICLE_TANGENTIAL_ACCELERATION,
|
||||
VAR_DAMPING=VS::PARTICLE_DAMPING,
|
||||
VAR_INITIAL_SIZE=VS::PARTICLE_INITIAL_SIZE,
|
||||
VAR_FINAL_SIZE=VS::PARTICLE_FINAL_SIZE,
|
||||
VAR_INITIAL_ANGLE=VS::PARTICLE_INITIAL_ANGLE,
|
||||
VAR_HEIGHT=VS::PARTICLE_HEIGHT,
|
||||
VAR_HEIGHT_SPEED_SCALE=VS::PARTICLE_HEIGHT_SPEED_SCALE,
|
||||
VAR_MAX=VS::PARTICLE_VAR_MAX
|
||||
VAR_LIFETIME = VS::PARTICLE_LIFETIME,
|
||||
VAR_SPREAD = VS::PARTICLE_SPREAD,
|
||||
VAR_GRAVITY = VS::PARTICLE_GRAVITY,
|
||||
VAR_LINEAR_VELOCITY = VS::PARTICLE_LINEAR_VELOCITY,
|
||||
VAR_ANGULAR_VELOCITY = VS::PARTICLE_ANGULAR_VELOCITY,
|
||||
VAR_LINEAR_ACCELERATION = VS::PARTICLE_LINEAR_ACCELERATION,
|
||||
VAR_DRAG = VS::PARTICLE_RADIAL_ACCELERATION,
|
||||
VAR_TANGENTIAL_ACCELERATION = VS::PARTICLE_TANGENTIAL_ACCELERATION,
|
||||
VAR_DAMPING = VS::PARTICLE_DAMPING,
|
||||
VAR_INITIAL_SIZE = VS::PARTICLE_INITIAL_SIZE,
|
||||
VAR_FINAL_SIZE = VS::PARTICLE_FINAL_SIZE,
|
||||
VAR_INITIAL_ANGLE = VS::PARTICLE_INITIAL_ANGLE,
|
||||
VAR_HEIGHT = VS::PARTICLE_HEIGHT,
|
||||
VAR_HEIGHT_SPEED_SCALE = VS::PARTICLE_HEIGHT_SPEED_SCALE,
|
||||
VAR_MAX = VS::PARTICLE_VAR_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
OBJ_TYPE( Particles, GeometryInstance );
|
||||
OBJ_TYPE(Particles, GeometryInstance);
|
||||
|
||||
RID particles;
|
||||
|
||||
|
|
@ -92,16 +91,13 @@ private:
|
|||
|
||||
Ref<Material> material;
|
||||
|
||||
Timer* timer;
|
||||
Timer *timer;
|
||||
void setup_timer();
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
AABB get_aabb() const;
|
||||
DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
|
|
@ -111,25 +107,25 @@ public:
|
|||
void set_emitting(bool p_emitting);
|
||||
bool is_emitting() const;
|
||||
|
||||
void set_visibility_aabb(const AABB& p_aabb);
|
||||
void set_visibility_aabb(const AABB &p_aabb);
|
||||
AABB get_visibility_aabb() const;
|
||||
|
||||
void set_emission_half_extents(const Vector3& p_half_extents);
|
||||
void set_emission_half_extents(const Vector3 &p_half_extents);
|
||||
Vector3 get_emission_half_extents() const;
|
||||
|
||||
void set_emission_base_velocity(const Vector3& p_base_velocity);
|
||||
void set_emission_base_velocity(const Vector3 &p_base_velocity);
|
||||
Vector3 get_emission_base_velocity() const;
|
||||
|
||||
void set_emission_points(const DVector<Vector3>& p_points);
|
||||
void set_emission_points(const DVector<Vector3> &p_points);
|
||||
DVector<Vector3> get_emission_points() const;
|
||||
|
||||
void set_gravity_normal(const Vector3& p_normal);
|
||||
void set_gravity_normal(const Vector3 &p_normal);
|
||||
Vector3 get_gravity_normal() const;
|
||||
|
||||
void set_variable(Variable p_variable,float p_value);
|
||||
void set_variable(Variable p_variable, float p_value);
|
||||
float get_variable(Variable p_variable) const;
|
||||
|
||||
void set_randomness(Variable p_variable,float p_randomness);
|
||||
void set_randomness(Variable p_variable, float p_randomness);
|
||||
float get_randomness(Variable p_variable) const;
|
||||
|
||||
void set_color_phases(int p_phases);
|
||||
|
|
@ -138,13 +134,13 @@ public:
|
|||
void set_color_phase_pos(int p_phase, float p_pos);
|
||||
float get_color_phase_pos(int p_phase) const;
|
||||
|
||||
void set_color_phase_color(int p_phase, const Color& p_color);
|
||||
void set_color_phase_color(int p_phase, const Color &p_color);
|
||||
Color get_color_phase_color(int p_phase) const;
|
||||
|
||||
void set_height_from_velocity(bool p_enable);
|
||||
bool has_height_from_velocity() const;
|
||||
|
||||
void set_material(const Ref<Material>& p_material);
|
||||
void set_material(const Ref<Material> &p_material);
|
||||
Ref<Material> get_material() const;
|
||||
|
||||
void set_emit_timeout(float p_timeout);
|
||||
|
|
@ -155,11 +151,9 @@ public:
|
|||
|
||||
void start_emitting(float p_time);
|
||||
|
||||
|
||||
Particles();
|
||||
~Particles();
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( Particles::Variable );
|
||||
VARIANT_ENUM_CAST(Particles::Variable);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,119 +52,108 @@ void Path::_notification(int p_what) {
|
|||
|
||||
void Path::_curve_changed() {
|
||||
|
||||
|
||||
if (is_inside_tree() && get_tree()->is_editor_hint())
|
||||
update_gizmo();
|
||||
}
|
||||
|
||||
|
||||
void Path::set_curve(const Ref<Curve3D>& p_curve) {
|
||||
void Path::set_curve(const Ref<Curve3D> &p_curve) {
|
||||
|
||||
if (curve.is_valid()) {
|
||||
curve->disconnect("changed",this,"_curve_changed");
|
||||
curve->disconnect("changed", this, "_curve_changed");
|
||||
}
|
||||
|
||||
curve=p_curve;
|
||||
curve = p_curve;
|
||||
|
||||
if (curve.is_valid()) {
|
||||
curve->connect("changed",this,"_curve_changed");
|
||||
curve->connect("changed", this, "_curve_changed");
|
||||
}
|
||||
_curve_changed();
|
||||
|
||||
}
|
||||
|
||||
Ref<Curve3D> Path::get_curve() const{
|
||||
Ref<Curve3D> Path::get_curve() const {
|
||||
|
||||
return curve;
|
||||
}
|
||||
|
||||
void Path::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_curve","curve:Curve3D"),&Path::set_curve);
|
||||
ObjectTypeDB::bind_method(_MD("get_curve:Curve3D","curve"),&Path::get_curve);
|
||||
ObjectTypeDB::bind_method(_MD("_curve_changed"),&Path::_curve_changed);
|
||||
ObjectTypeDB::bind_method(_MD("set_curve", "curve:Curve3D"), &Path::set_curve);
|
||||
ObjectTypeDB::bind_method(_MD("get_curve:Curve3D", "curve"), &Path::get_curve);
|
||||
ObjectTypeDB::bind_method(_MD("_curve_changed"), &Path::_curve_changed);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D"), _SCS("set_curve"),_SCS("get_curve"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D"), _SCS("set_curve"), _SCS("get_curve"));
|
||||
}
|
||||
|
||||
Path::Path() {
|
||||
|
||||
set_curve(Ref<Curve3D>( memnew( Curve3D ))); //create one by default
|
||||
set_curve(Ref<Curve3D>(memnew(Curve3D))); //create one by default
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
|
||||
|
||||
void PathFollow::_update_transform() {
|
||||
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
Ref<Curve3D> c =path->get_curve();
|
||||
Ref<Curve3D> c = path->get_curve();
|
||||
if (!c.is_valid())
|
||||
return;
|
||||
|
||||
|
||||
float o = offset;
|
||||
if (loop)
|
||||
o=Math::fposmod(o,c->get_baked_length());
|
||||
o = Math::fposmod(o, c->get_baked_length());
|
||||
|
||||
Vector3 pos = c->interpolate_baked(o,cubic);
|
||||
Transform t=get_transform();
|
||||
Vector3 pos = c->interpolate_baked(o, cubic);
|
||||
Transform t = get_transform();
|
||||
|
||||
if (rotation_mode != ROTATION_NONE) {
|
||||
|
||||
if (rotation_mode!=ROTATION_NONE) {
|
||||
Vector3 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized();
|
||||
|
||||
Vector3 n = (c->interpolate_baked(o+lookahead,cubic)-pos).normalized();
|
||||
if (rotation_mode == ROTATION_Y) {
|
||||
|
||||
if (rotation_mode==ROTATION_Y) {
|
||||
|
||||
n.y=0;
|
||||
n.y = 0;
|
||||
n.normalize();
|
||||
}
|
||||
|
||||
if (n.length()<CMP_EPSILON) {//nothing, use previous
|
||||
n=-t.get_basis().get_axis(2).normalized();
|
||||
if (n.length() < CMP_EPSILON) { //nothing, use previous
|
||||
n = -t.get_basis().get_axis(2).normalized();
|
||||
}
|
||||
|
||||
Vector3 up = Vector3(0, 1, 0);
|
||||
|
||||
Vector3 up = Vector3(0,1,0);
|
||||
|
||||
if (rotation_mode==ROTATION_XYZ) {
|
||||
if (rotation_mode == ROTATION_XYZ) {
|
||||
|
||||
float tilt = c->interpolate_baked_tilt(o);
|
||||
if (tilt!=0) {
|
||||
if (tilt != 0) {
|
||||
|
||||
Matrix3 rot(-n,tilt); //remember.. lookat will be znegative.. znegative!! we abide by opengl clan.
|
||||
up=rot.xform(up);
|
||||
Matrix3 rot(-n, tilt); //remember.. lookat will be znegative.. znegative!! we abide by opengl clan.
|
||||
up = rot.xform(up);
|
||||
}
|
||||
}
|
||||
|
||||
t.set_look_at(pos,pos+n,up);
|
||||
t.set_look_at(pos, pos + n, up);
|
||||
|
||||
} else {
|
||||
|
||||
t.origin=pos;
|
||||
t.origin = pos;
|
||||
}
|
||||
|
||||
t.origin+=t.basis.get_axis(0)*h_offset + t.basis.get_axis(1)*v_offset;
|
||||
t.origin += t.basis.get_axis(0) * h_offset + t.basis.get_axis(1) * v_offset;
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void PathFollow::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
Node *parent=get_parent();
|
||||
Node *parent = get_parent();
|
||||
if (parent) {
|
||||
|
||||
path=parent->cast_to<Path>();
|
||||
path = parent->cast_to<Path>();
|
||||
if (path) {
|
||||
_update_transform();
|
||||
}
|
||||
|
|
@ -173,16 +162,14 @@ void PathFollow::_notification(int p_what) {
|
|||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
||||
|
||||
path=NULL;
|
||||
path = NULL;
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PathFollow::set_cubic_interpolation(bool p_enable) {
|
||||
|
||||
cubic=p_enable;
|
||||
cubic = p_enable;
|
||||
}
|
||||
|
||||
bool PathFollow::get_cubic_interpolation() const {
|
||||
|
|
@ -190,24 +177,23 @@ bool PathFollow::get_cubic_interpolation() const {
|
|||
return cubic;
|
||||
}
|
||||
|
||||
bool PathFollow::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
bool PathFollow::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (p_name==SceneStringNames::get_singleton()->offset) {
|
||||
if (p_name == SceneStringNames::get_singleton()->offset) {
|
||||
set_offset(p_value);
|
||||
} else if (p_name==SceneStringNames::get_singleton()->unit_offset) {
|
||||
} else if (p_name == SceneStringNames::get_singleton()->unit_offset) {
|
||||
set_unit_offset(p_value);
|
||||
} else if (p_name==SceneStringNames::get_singleton()->rotation_mode) {
|
||||
} else if (p_name == SceneStringNames::get_singleton()->rotation_mode) {
|
||||
set_rotation_mode(RotationMode(p_value.operator int()));
|
||||
} else if (p_name==SceneStringNames::get_singleton()->v_offset) {
|
||||
} else if (p_name == SceneStringNames::get_singleton()->v_offset) {
|
||||
set_v_offset(p_value);
|
||||
} else if (p_name==SceneStringNames::get_singleton()->h_offset) {
|
||||
} else if (p_name == SceneStringNames::get_singleton()->h_offset) {
|
||||
set_h_offset(p_value);
|
||||
} else if (String(p_name)=="cubic_interp") {
|
||||
} else if (String(p_name) == "cubic_interp") {
|
||||
set_cubic_interpolation(p_value);
|
||||
} else if (String(p_name)=="loop") {
|
||||
} else if (String(p_name) == "loop") {
|
||||
set_loop(p_value);
|
||||
} else if (String(p_name)=="lookahead") {
|
||||
} else if (String(p_name) == "lookahead") {
|
||||
set_lookahead(p_value);
|
||||
} else
|
||||
return false;
|
||||
|
|
@ -215,92 +201,87 @@ bool PathFollow::_set(const StringName& p_name, const Variant& p_value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PathFollow::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
bool PathFollow::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (p_name==SceneStringNames::get_singleton()->offset) {
|
||||
r_ret=get_offset();
|
||||
} else if (p_name==SceneStringNames::get_singleton()->unit_offset) {
|
||||
r_ret=get_unit_offset();
|
||||
} else if (p_name==SceneStringNames::get_singleton()->rotation_mode) {
|
||||
r_ret=get_rotation_mode();
|
||||
} else if (p_name==SceneStringNames::get_singleton()->v_offset) {
|
||||
r_ret=get_v_offset();
|
||||
} else if (p_name==SceneStringNames::get_singleton()->h_offset) {
|
||||
r_ret=get_h_offset();
|
||||
} else if (String(p_name)=="cubic_interp") {
|
||||
r_ret=cubic;
|
||||
} else if (String(p_name)=="loop") {
|
||||
r_ret=loop;
|
||||
} else if (String(p_name)=="lookahead") {
|
||||
r_ret=lookahead;
|
||||
if (p_name == SceneStringNames::get_singleton()->offset) {
|
||||
r_ret = get_offset();
|
||||
} else if (p_name == SceneStringNames::get_singleton()->unit_offset) {
|
||||
r_ret = get_unit_offset();
|
||||
} else if (p_name == SceneStringNames::get_singleton()->rotation_mode) {
|
||||
r_ret = get_rotation_mode();
|
||||
} else if (p_name == SceneStringNames::get_singleton()->v_offset) {
|
||||
r_ret = get_v_offset();
|
||||
} else if (p_name == SceneStringNames::get_singleton()->h_offset) {
|
||||
r_ret = get_h_offset();
|
||||
} else if (String(p_name) == "cubic_interp") {
|
||||
r_ret = cubic;
|
||||
} else if (String(p_name) == "loop") {
|
||||
r_ret = loop;
|
||||
} else if (String(p_name) == "lookahead") {
|
||||
r_ret = lookahead;
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
void PathFollow::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
void PathFollow::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
float max=10000;
|
||||
float max = 10000;
|
||||
if (path && path->get_curve().is_valid())
|
||||
max=path->get_curve()->get_baked_length();
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "offset", PROPERTY_HINT_RANGE,"0,"+rtos(max)+",0.01"));
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE,"0,1,0.0001",PROPERTY_USAGE_EDITOR));
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "h_offset") );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "v_offset") );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM,"None,Y,XY,XYZ"));
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "cubic_interp"));
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "loop"));
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "lookahead",PROPERTY_HINT_RANGE,"0.001,1024.0,0.001"));
|
||||
max = path->get_curve()->get_baked_length();
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0," + rtos(max) + ",0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001", PROPERTY_USAGE_EDITOR));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "h_offset"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "v_offset"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "cubic_interp"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "loop"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"));
|
||||
}
|
||||
|
||||
|
||||
void PathFollow::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_offset","offset"),&PathFollow::set_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_offset"),&PathFollow::get_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_offset", "offset"), &PathFollow::set_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_offset"), &PathFollow::get_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_h_offset","h_offset"),&PathFollow::set_h_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_h_offset"),&PathFollow::get_h_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_h_offset", "h_offset"), &PathFollow::set_h_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_h_offset"), &PathFollow::get_h_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_v_offset","v_offset"),&PathFollow::set_v_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_v_offset"),&PathFollow::get_v_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_v_offset", "v_offset"), &PathFollow::set_v_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_v_offset"), &PathFollow::get_v_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_unit_offset","unit_offset"),&PathFollow::set_unit_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_unit_offset"),&PathFollow::get_unit_offset);
|
||||
ObjectTypeDB::bind_method(_MD("set_unit_offset", "unit_offset"), &PathFollow::set_unit_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_unit_offset"), &PathFollow::get_unit_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation_mode","rotation_mode"),&PathFollow::set_rotation_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_rotation_mode"),&PathFollow::get_rotation_mode);
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation_mode", "rotation_mode"), &PathFollow::set_rotation_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_rotation_mode"), &PathFollow::get_rotation_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cubic_interpolation","enable"),&PathFollow::set_cubic_interpolation);
|
||||
ObjectTypeDB::bind_method(_MD("get_cubic_interpolation"),&PathFollow::get_cubic_interpolation);
|
||||
ObjectTypeDB::bind_method(_MD("set_cubic_interpolation", "enable"), &PathFollow::set_cubic_interpolation);
|
||||
ObjectTypeDB::bind_method(_MD("get_cubic_interpolation"), &PathFollow::get_cubic_interpolation);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_loop","loop"),&PathFollow::set_loop);
|
||||
ObjectTypeDB::bind_method(_MD("has_loop"),&PathFollow::has_loop);
|
||||
|
||||
BIND_CONSTANT( ROTATION_NONE );
|
||||
BIND_CONSTANT( ROTATION_Y );
|
||||
BIND_CONSTANT( ROTATION_XY );
|
||||
BIND_CONSTANT( ROTATION_XYZ );
|
||||
ObjectTypeDB::bind_method(_MD("set_loop", "loop"), &PathFollow::set_loop);
|
||||
ObjectTypeDB::bind_method(_MD("has_loop"), &PathFollow::has_loop);
|
||||
|
||||
BIND_CONSTANT(ROTATION_NONE);
|
||||
BIND_CONSTANT(ROTATION_Y);
|
||||
BIND_CONSTANT(ROTATION_XY);
|
||||
BIND_CONSTANT(ROTATION_XYZ);
|
||||
}
|
||||
|
||||
void PathFollow::set_offset(float p_offset) {
|
||||
|
||||
offset=p_offset;
|
||||
offset = p_offset;
|
||||
if (path)
|
||||
_update_transform();
|
||||
_change_notify("offset");
|
||||
_change_notify("unit_offset");
|
||||
|
||||
}
|
||||
|
||||
void PathFollow::set_h_offset(float p_h_offset) {
|
||||
|
||||
h_offset=p_h_offset;
|
||||
h_offset = p_h_offset;
|
||||
if (path)
|
||||
_update_transform();
|
||||
|
||||
}
|
||||
|
||||
float PathFollow::get_h_offset() const {
|
||||
|
|
@ -310,10 +291,9 @@ float PathFollow::get_h_offset() const {
|
|||
|
||||
void PathFollow::set_v_offset(float p_v_offset) {
|
||||
|
||||
v_offset=p_v_offset;
|
||||
v_offset = p_v_offset;
|
||||
if (path)
|
||||
_update_transform();
|
||||
|
||||
}
|
||||
|
||||
float PathFollow::get_v_offset() const {
|
||||
|
|
@ -321,8 +301,7 @@ float PathFollow::get_v_offset() const {
|
|||
return v_offset;
|
||||
}
|
||||
|
||||
|
||||
float PathFollow::get_offset() const{
|
||||
float PathFollow::get_offset() const {
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
@ -330,32 +309,30 @@ float PathFollow::get_offset() const{
|
|||
void PathFollow::set_unit_offset(float p_unit_offset) {
|
||||
|
||||
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
|
||||
set_offset(p_unit_offset*path->get_curve()->get_baked_length());
|
||||
|
||||
set_offset(p_unit_offset * path->get_curve()->get_baked_length());
|
||||
}
|
||||
|
||||
float PathFollow::get_unit_offset() const{
|
||||
float PathFollow::get_unit_offset() const {
|
||||
|
||||
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
|
||||
return get_offset()/path->get_curve()->get_baked_length();
|
||||
return get_offset() / path->get_curve()->get_baked_length();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PathFollow::set_lookahead(float p_lookahead) {
|
||||
|
||||
lookahead=p_lookahead;
|
||||
|
||||
lookahead = p_lookahead;
|
||||
}
|
||||
|
||||
float PathFollow::get_lookahead() const{
|
||||
float PathFollow::get_lookahead() const {
|
||||
|
||||
return lookahead;
|
||||
}
|
||||
|
||||
void PathFollow::set_rotation_mode(RotationMode p_rotation_mode) {
|
||||
|
||||
rotation_mode=p_rotation_mode;
|
||||
rotation_mode = p_rotation_mode;
|
||||
_update_transform();
|
||||
}
|
||||
|
||||
|
|
@ -366,23 +343,22 @@ PathFollow::RotationMode PathFollow::get_rotation_mode() const {
|
|||
|
||||
void PathFollow::set_loop(bool p_loop) {
|
||||
|
||||
loop=p_loop;
|
||||
loop = p_loop;
|
||||
}
|
||||
|
||||
bool PathFollow::has_loop() const{
|
||||
bool PathFollow::has_loop() const {
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
|
||||
PathFollow::PathFollow() {
|
||||
|
||||
offset=0;
|
||||
h_offset=0;
|
||||
v_offset=0;
|
||||
path=NULL;
|
||||
rotation_mode=ROTATION_XYZ;
|
||||
cubic=true;
|
||||
loop=true;
|
||||
lookahead=0.1;
|
||||
offset = 0;
|
||||
h_offset = 0;
|
||||
v_offset = 0;
|
||||
path = NULL;
|
||||
rotation_mode = ROTATION_XYZ;
|
||||
cubic = true;
|
||||
loop = true;
|
||||
lookahead = 0.1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,36 +29,33 @@
|
|||
#ifndef PATH_H
|
||||
#define PATH_H
|
||||
|
||||
#include "scene/resources/curve.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/resources/curve.h"
|
||||
|
||||
class Path : public Spatial {
|
||||
|
||||
OBJ_TYPE( Path, Spatial );
|
||||
OBJ_TYPE(Path, Spatial);
|
||||
|
||||
Ref<Curve3D> curve;
|
||||
|
||||
void _curve_changed();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_curve(const Ref<Curve3D>& p_curve);
|
||||
void set_curve(const Ref<Curve3D> &p_curve);
|
||||
Ref<Curve3D> get_curve() const;
|
||||
|
||||
|
||||
Path();
|
||||
};
|
||||
|
||||
class PathFollow : public Spatial {
|
||||
|
||||
OBJ_TYPE(PathFollow,Spatial);
|
||||
public:
|
||||
OBJ_TYPE(PathFollow, Spatial);
|
||||
|
||||
public:
|
||||
enum RotationMode {
|
||||
|
||||
ROTATION_NONE,
|
||||
|
|
@ -79,17 +76,15 @@ private:
|
|||
|
||||
void _update_transform();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_offset(float p_offset);
|
||||
float get_offset() const;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -33,10 +33,9 @@
|
|||
#include "servers/physics_server.h"
|
||||
#include "vset.h"
|
||||
|
||||
|
||||
class PhysicsBody : public CollisionObject {
|
||||
|
||||
OBJ_TYPE(PhysicsBody,CollisionObject);
|
||||
OBJ_TYPE(PhysicsBody, CollisionObject);
|
||||
|
||||
uint32_t layer_mask;
|
||||
uint32_t collision_mask;
|
||||
|
|
@ -45,12 +44,11 @@ class PhysicsBody : public CollisionObject {
|
|||
uint32_t _get_layers() const;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
PhysicsBody(PhysicsServer::BodyMode p_mode);
|
||||
public:
|
||||
|
||||
public:
|
||||
virtual Vector3 get_linear_velocity() const;
|
||||
virtual Vector3 get_angular_velocity() const;
|
||||
virtual float get_inverse_mass() const;
|
||||
|
|
@ -67,18 +65,15 @@ public:
|
|||
void set_collision_mask_bit(int p_bit, bool p_value);
|
||||
bool get_collision_mask_bit(int p_bit) const;
|
||||
|
||||
void add_collision_exception_with(Node* p_node); //must be physicsbody
|
||||
void remove_collision_exception_with(Node* p_node);
|
||||
|
||||
|
||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
||||
void remove_collision_exception_with(Node *p_node);
|
||||
|
||||
PhysicsBody();
|
||||
|
||||
};
|
||||
|
||||
class StaticBody : public PhysicsBody {
|
||||
|
||||
OBJ_TYPE(StaticBody,PhysicsBody);
|
||||
OBJ_TYPE(StaticBody, PhysicsBody);
|
||||
|
||||
Vector3 constant_linear_velocity;
|
||||
Vector3 constant_angular_velocity;
|
||||
|
|
@ -86,37 +81,31 @@ class StaticBody : public PhysicsBody {
|
|||
real_t bounce;
|
||||
real_t friction;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void set_friction(real_t p_friction);
|
||||
real_t get_friction() const;
|
||||
|
||||
void set_bounce(real_t p_bounce);
|
||||
real_t get_bounce() const;
|
||||
|
||||
|
||||
void set_constant_linear_velocity(const Vector3& p_vel);
|
||||
void set_constant_angular_velocity(const Vector3& p_vel);
|
||||
void set_constant_linear_velocity(const Vector3 &p_vel);
|
||||
void set_constant_angular_velocity(const Vector3 &p_vel);
|
||||
|
||||
Vector3 get_constant_linear_velocity() const;
|
||||
Vector3 get_constant_angular_velocity() const;
|
||||
|
||||
StaticBody();
|
||||
~StaticBody();
|
||||
|
||||
};
|
||||
|
||||
class RigidBody : public PhysicsBody {
|
||||
|
||||
OBJ_TYPE(RigidBody,PhysicsBody);
|
||||
public:
|
||||
OBJ_TYPE(RigidBody, PhysicsBody);
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
MODE_RIGID,
|
||||
MODE_STATIC,
|
||||
|
|
@ -132,7 +121,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
|
||||
bool can_sleep;
|
||||
PhysicsDirectBodyState *state;
|
||||
Mode mode;
|
||||
|
|
@ -142,7 +130,7 @@ private:
|
|||
real_t friction;
|
||||
|
||||
Vector3 linear_velocity;
|
||||
Vector3 angular_velocity;
|
||||
Vector3 angular_velocity;
|
||||
real_t gravity_scale;
|
||||
real_t linear_damp;
|
||||
real_t angular_damp;
|
||||
|
|
@ -152,33 +140,32 @@ private:
|
|||
|
||||
AxisLock axis_lock;
|
||||
|
||||
|
||||
int max_contacts_reported;
|
||||
|
||||
bool custom_integrator;
|
||||
|
||||
|
||||
struct ShapePair {
|
||||
|
||||
int body_shape;
|
||||
int local_shape;
|
||||
bool tagged;
|
||||
bool operator<(const ShapePair& p_sp) const {
|
||||
if (body_shape==p_sp.body_shape)
|
||||
bool operator<(const ShapePair &p_sp) const {
|
||||
if (body_shape == p_sp.body_shape)
|
||||
return local_shape < p_sp.local_shape;
|
||||
else
|
||||
return body_shape < p_sp.body_shape;
|
||||
}
|
||||
|
||||
ShapePair() {}
|
||||
ShapePair(int p_bs, int p_ls) { body_shape=p_bs; local_shape=p_ls; }
|
||||
ShapePair(int p_bs, int p_ls) {
|
||||
body_shape = p_bs;
|
||||
local_shape = p_ls;
|
||||
}
|
||||
};
|
||||
struct RigidBody_RemoveAction {
|
||||
|
||||
|
||||
ObjectID body_id;
|
||||
ShapePair pair;
|
||||
|
||||
};
|
||||
struct BodyState {
|
||||
|
||||
|
|
@ -190,33 +177,28 @@ private:
|
|||
struct ContactMonitor {
|
||||
|
||||
bool locked;
|
||||
Map<ObjectID,BodyState> body_map;
|
||||
|
||||
Map<ObjectID, BodyState> body_map;
|
||||
};
|
||||
|
||||
|
||||
ContactMonitor *contact_monitor;
|
||||
void _body_enter_tree(ObjectID p_id);
|
||||
void _body_exit_tree(ObjectID p_id);
|
||||
|
||||
|
||||
void _body_inout(int p_status, ObjectID p_instance, int p_body_shape,int p_local_shape);
|
||||
void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape);
|
||||
void _direct_state_changed(Object *p_state);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_mode(Mode p_mode);
|
||||
Mode get_mode() const;
|
||||
|
||||
void set_mass(real_t p_mass);
|
||||
real_t get_mass() const;
|
||||
|
||||
virtual float get_inverse_mass() const { return 1.0/mass; }
|
||||
virtual float get_inverse_mass() const { return 1.0 / mass; }
|
||||
|
||||
void set_weight(real_t p_weight);
|
||||
real_t get_weight() const;
|
||||
|
|
@ -227,13 +209,13 @@ public:
|
|||
void set_bounce(real_t p_bounce);
|
||||
real_t get_bounce() const;
|
||||
|
||||
void set_linear_velocity(const Vector3& p_velocity);
|
||||
void set_linear_velocity(const Vector3 &p_velocity);
|
||||
Vector3 get_linear_velocity() const;
|
||||
|
||||
void set_axis_velocity(const Vector3& p_axis);
|
||||
void set_axis_velocity(const Vector3 &p_axis);
|
||||
|
||||
void set_angular_velocity(const Vector3&p_velocity);
|
||||
Vector3 get_angular_velocity() const;
|
||||
void set_angular_velocity(const Vector3 &p_velocity);
|
||||
Vector3 get_angular_velocity() const;
|
||||
|
||||
void set_gravity_scale(real_t p_gravity_scale);
|
||||
real_t get_gravity_scale() const;
|
||||
|
|
@ -244,7 +226,6 @@ public:
|
|||
void set_angular_damp(real_t p_angular_damp);
|
||||
real_t get_angular_damp() const;
|
||||
|
||||
|
||||
void set_use_custom_integrator(bool p_enable);
|
||||
bool is_using_custom_integrator();
|
||||
|
||||
|
|
@ -268,23 +249,18 @@ public:
|
|||
|
||||
Array get_colliding_bodies() const;
|
||||
|
||||
void apply_impulse(const Vector3& p_pos, const Vector3& p_impulse);
|
||||
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
|
||||
|
||||
RigidBody();
|
||||
~RigidBody();
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(RigidBody::Mode);
|
||||
VARIANT_ENUM_CAST(RigidBody::AxisLock);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class KinematicBody : public PhysicsBody {
|
||||
|
||||
OBJ_TYPE(KinematicBody,PhysicsBody);
|
||||
OBJ_TYPE(KinematicBody, PhysicsBody);
|
||||
|
||||
float margin;
|
||||
bool collide_static;
|
||||
|
|
@ -299,26 +275,24 @@ class KinematicBody : public PhysicsBody {
|
|||
ObjectID collider;
|
||||
int collider_shape;
|
||||
|
||||
|
||||
|
||||
Variant _get_collider() const;
|
||||
|
||||
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
enum {
|
||||
SLIDE_FLAG_FLOOR,
|
||||
SLIDE_FLAG_WALL,
|
||||
SLIDE_FLAG_ROOF
|
||||
};
|
||||
|
||||
Vector3 move(const Vector3& p_motion);
|
||||
Vector3 move_to(const Vector3& p_position);
|
||||
Vector3 move(const Vector3 &p_motion);
|
||||
Vector3 move_to(const Vector3 &p_position);
|
||||
|
||||
bool can_teleport_to(const Vector3& p_position);
|
||||
bool can_teleport_to(const Vector3 &p_position);
|
||||
bool is_colliding() const;
|
||||
Vector3 get_collision_pos() const;
|
||||
Vector3 get_collision_normal() const;
|
||||
|
|
@ -343,7 +317,6 @@ public:
|
|||
|
||||
KinematicBody();
|
||||
~KinematicBody();
|
||||
|
||||
};
|
||||
|
||||
#endif // PHYSICS_BODY__H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -29,15 +29,14 @@
|
|||
#ifndef PHYSICS_JOINT_H
|
||||
#define PHYSICS_JOINT_H
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/3d/physics_body.h"
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
class Joint : public Spatial {
|
||||
|
||||
OBJ_TYPE(Joint,Spatial);
|
||||
OBJ_TYPE(Joint, Spatial);
|
||||
|
||||
RID ba,bb;
|
||||
RID ba, bb;
|
||||
|
||||
RID joint;
|
||||
|
||||
|
|
@ -47,22 +46,20 @@ class Joint : public Spatial {
|
|||
int solver_priority;
|
||||
bool exclude_from_collision;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void _update_joint(bool p_only_free=false);
|
||||
void _update_joint(bool p_only_free = false);
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
virtual RID _configure_joint(PhysicsBody *body_a,PhysicsBody *body_b)=0;
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b) = 0;
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_node_a(const NodePath& p_node_a);
|
||||
public:
|
||||
void set_node_a(const NodePath &p_node_a);
|
||||
NodePath get_node_a() const;
|
||||
|
||||
void set_node_b(const NodePath& p_node_b);
|
||||
void set_node_b(const NodePath &p_node_b);
|
||||
NodePath get_node_b() const;
|
||||
|
||||
void set_solver_priority(int p_priority);
|
||||
|
|
@ -73,31 +70,28 @@ public:
|
|||
|
||||
RID get_joint() const { return joint; }
|
||||
Joint();
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
|
||||
class PinJoint : public Joint {
|
||||
|
||||
OBJ_TYPE(PinJoint,Joint);
|
||||
public:
|
||||
OBJ_TYPE(PinJoint, Joint);
|
||||
|
||||
public:
|
||||
enum Param {
|
||||
PARAM_BIAS=PhysicsServer::PIN_JOINT_BIAS,
|
||||
PARAM_DAMPING=PhysicsServer::PIN_JOINT_DAMPING,
|
||||
PARAM_IMPULSE_CLAMP=PhysicsServer::PIN_JOINT_IMPULSE_CLAMP
|
||||
PARAM_BIAS = PhysicsServer::PIN_JOINT_BIAS,
|
||||
PARAM_DAMPING = PhysicsServer::PIN_JOINT_DAMPING,
|
||||
PARAM_IMPULSE_CLAMP = PhysicsServer::PIN_JOINT_IMPULSE_CLAMP
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
float params[3];
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_param(Param p_param,float p_value);
|
||||
public:
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
PinJoint();
|
||||
|
|
@ -105,34 +99,30 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(PinJoint::Param);
|
||||
|
||||
|
||||
class HingeJoint : public Joint {
|
||||
|
||||
OBJ_TYPE(HingeJoint,Joint);
|
||||
public:
|
||||
OBJ_TYPE(HingeJoint, Joint);
|
||||
|
||||
public:
|
||||
enum Param {
|
||||
PARAM_BIAS=PhysicsServer::HINGE_JOINT_BIAS,
|
||||
PARAM_LIMIT_UPPER=PhysicsServer::HINGE_JOINT_LIMIT_UPPER,
|
||||
PARAM_LIMIT_LOWER=PhysicsServer::HINGE_JOINT_LIMIT_LOWER,
|
||||
PARAM_LIMIT_BIAS=PhysicsServer::HINGE_JOINT_LIMIT_BIAS,
|
||||
PARAM_LIMIT_SOFTNESS=PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS,
|
||||
PARAM_LIMIT_RELAXATION=PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION,
|
||||
PARAM_MOTOR_TARGET_VELOCITY=PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY,
|
||||
PARAM_MOTOR_MAX_IMPULSE=PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE,
|
||||
PARAM_MAX=PhysicsServer::HINGE_JOINT_MAX
|
||||
PARAM_BIAS = PhysicsServer::HINGE_JOINT_BIAS,
|
||||
PARAM_LIMIT_UPPER = PhysicsServer::HINGE_JOINT_LIMIT_UPPER,
|
||||
PARAM_LIMIT_LOWER = PhysicsServer::HINGE_JOINT_LIMIT_LOWER,
|
||||
PARAM_LIMIT_BIAS = PhysicsServer::HINGE_JOINT_LIMIT_BIAS,
|
||||
PARAM_LIMIT_SOFTNESS = PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS,
|
||||
PARAM_LIMIT_RELAXATION = PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION,
|
||||
PARAM_MOTOR_TARGET_VELOCITY = PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY,
|
||||
PARAM_MOTOR_MAX_IMPULSE = PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE,
|
||||
PARAM_MAX = PhysicsServer::HINGE_JOINT_MAX
|
||||
};
|
||||
|
||||
enum Flag {
|
||||
FLAG_USE_LIMIT=PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT,
|
||||
FLAG_ENABLE_MOTOR=PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR,
|
||||
FLAG_MAX=PhysicsServer::HINGE_JOINT_FLAG_MAX
|
||||
FLAG_USE_LIMIT = PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT,
|
||||
FLAG_ENABLE_MOTOR = PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR,
|
||||
FLAG_MAX = PhysicsServer::HINGE_JOINT_FLAG_MAX
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
float params[PARAM_MAX];
|
||||
bool flags[FLAG_MAX];
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
|
||||
|
|
@ -145,11 +135,10 @@ protected:
|
|||
float _get_lower_limit() const;
|
||||
|
||||
public:
|
||||
|
||||
void set_param(Param p_param,float p_value);
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
void set_flag(Flag p_flag,bool p_value);
|
||||
void set_flag(Flag p_flag, bool p_value);
|
||||
bool get_flag(Flag p_flag) const;
|
||||
|
||||
HingeJoint();
|
||||
|
|
@ -158,44 +147,40 @@ public:
|
|||
VARIANT_ENUM_CAST(HingeJoint::Param);
|
||||
VARIANT_ENUM_CAST(HingeJoint::Flag);
|
||||
|
||||
|
||||
class SliderJoint : public Joint {
|
||||
|
||||
OBJ_TYPE(SliderJoint,Joint);
|
||||
OBJ_TYPE(SliderJoint, Joint);
|
||||
|
||||
public:
|
||||
|
||||
enum Param {
|
||||
PARAM_LINEAR_LIMIT_UPPER=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER,
|
||||
PARAM_LINEAR_LIMIT_LOWER=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER,
|
||||
PARAM_LINEAR_LIMIT_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS,
|
||||
PARAM_LINEAR_LIMIT_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION,
|
||||
PARAM_LINEAR_LIMIT_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING,
|
||||
PARAM_LINEAR_MOTION_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS,
|
||||
PARAM_LINEAR_MOTION_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION,
|
||||
PARAM_LINEAR_MOTION_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING,
|
||||
PARAM_LINEAR_ORTHOGONAL_SOFTNESS=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS,
|
||||
PARAM_LINEAR_ORTHOGONAL_RESTITUTION=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION,
|
||||
PARAM_LINEAR_ORTHOGONAL_DAMPING=PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING,
|
||||
PARAM_LINEAR_LIMIT_UPPER = PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER,
|
||||
PARAM_LINEAR_LIMIT_LOWER = PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER,
|
||||
PARAM_LINEAR_LIMIT_SOFTNESS = PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS,
|
||||
PARAM_LINEAR_LIMIT_RESTITUTION = PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION,
|
||||
PARAM_LINEAR_LIMIT_DAMPING = PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING,
|
||||
PARAM_LINEAR_MOTION_SOFTNESS = PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS,
|
||||
PARAM_LINEAR_MOTION_RESTITUTION = PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION,
|
||||
PARAM_LINEAR_MOTION_DAMPING = PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING,
|
||||
PARAM_LINEAR_ORTHOGONAL_SOFTNESS = PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS,
|
||||
PARAM_LINEAR_ORTHOGONAL_RESTITUTION = PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION,
|
||||
PARAM_LINEAR_ORTHOGONAL_DAMPING = PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING,
|
||||
|
||||
PARAM_ANGULAR_LIMIT_UPPER=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER,
|
||||
PARAM_ANGULAR_LIMIT_LOWER=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER,
|
||||
PARAM_ANGULAR_LIMIT_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS,
|
||||
PARAM_ANGULAR_LIMIT_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION,
|
||||
PARAM_ANGULAR_LIMIT_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING,
|
||||
PARAM_ANGULAR_MOTION_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS,
|
||||
PARAM_ANGULAR_MOTION_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION,
|
||||
PARAM_ANGULAR_MOTION_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING,
|
||||
PARAM_ANGULAR_ORTHOGONAL_SOFTNESS=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS,
|
||||
PARAM_ANGULAR_ORTHOGONAL_RESTITUTION=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION,
|
||||
PARAM_ANGULAR_ORTHOGONAL_DAMPING=PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING,
|
||||
PARAM_MAX=PhysicsServer::SLIDER_JOINT_MAX
|
||||
PARAM_ANGULAR_LIMIT_UPPER = PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER,
|
||||
PARAM_ANGULAR_LIMIT_LOWER = PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER,
|
||||
PARAM_ANGULAR_LIMIT_SOFTNESS = PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS,
|
||||
PARAM_ANGULAR_LIMIT_RESTITUTION = PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION,
|
||||
PARAM_ANGULAR_LIMIT_DAMPING = PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING,
|
||||
PARAM_ANGULAR_MOTION_SOFTNESS = PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS,
|
||||
PARAM_ANGULAR_MOTION_RESTITUTION = PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION,
|
||||
PARAM_ANGULAR_MOTION_DAMPING = PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING,
|
||||
PARAM_ANGULAR_ORTHOGONAL_SOFTNESS = PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS,
|
||||
PARAM_ANGULAR_ORTHOGONAL_RESTITUTION = PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION,
|
||||
PARAM_ANGULAR_ORTHOGONAL_DAMPING = PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING,
|
||||
PARAM_MAX = PhysicsServer::SLIDER_JOINT_MAX
|
||||
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
void _set_upper_limit_angular(float p_limit_angular);
|
||||
float _get_upper_limit_angular() const;
|
||||
|
||||
|
|
@ -205,25 +190,21 @@ protected:
|
|||
float params[PARAM_MAX];
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_param(Param p_param,float p_value);
|
||||
public:
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
SliderJoint();
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST(SliderJoint::Param);
|
||||
|
||||
|
||||
|
||||
|
||||
class ConeTwistJoint : public Joint {
|
||||
|
||||
OBJ_TYPE(ConeTwistJoint,Joint);
|
||||
public:
|
||||
OBJ_TYPE(ConeTwistJoint, Joint);
|
||||
|
||||
public:
|
||||
enum Param {
|
||||
|
||||
PARAM_SWING_SPAN,
|
||||
|
|
@ -235,8 +216,6 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void _set_swing_span(float p_limit_angular);
|
||||
float _get_swing_span() const;
|
||||
|
||||
|
|
@ -246,53 +225,48 @@ protected:
|
|||
float params[PARAM_MAX];
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_param(Param p_param,float p_value);
|
||||
public:
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
ConeTwistJoint();
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST(ConeTwistJoint::Param);
|
||||
|
||||
|
||||
class Generic6DOFJoint : public Joint {
|
||||
|
||||
OBJ_TYPE(Generic6DOFJoint,Joint);
|
||||
public:
|
||||
OBJ_TYPE(Generic6DOFJoint, Joint);
|
||||
|
||||
public:
|
||||
enum Param {
|
||||
|
||||
PARAM_LINEAR_LOWER_LIMIT=PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT,
|
||||
PARAM_LINEAR_UPPER_LIMIT=PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT,
|
||||
PARAM_LINEAR_LIMIT_SOFTNESS=PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS,
|
||||
PARAM_LINEAR_RESTITUTION=PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION,
|
||||
PARAM_LINEAR_DAMPING=PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING,
|
||||
PARAM_ANGULAR_LOWER_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT,
|
||||
PARAM_ANGULAR_UPPER_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT,
|
||||
PARAM_ANGULAR_LIMIT_SOFTNESS=PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS,
|
||||
PARAM_ANGULAR_DAMPING=PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING,
|
||||
PARAM_ANGULAR_RESTITUTION=PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION,
|
||||
PARAM_ANGULAR_FORCE_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_FORCE_LIMIT,
|
||||
PARAM_ANGULAR_ERP=PhysicsServer::G6DOF_JOINT_ANGULAR_ERP,
|
||||
PARAM_ANGULAR_MOTOR_TARGET_VELOCITY=PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY,
|
||||
PARAM_ANGULAR_MOTOR_FORCE_LIMIT=PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT,
|
||||
PARAM_MAX=PhysicsServer::G6DOF_JOINT_MAX,
|
||||
PARAM_LINEAR_LOWER_LIMIT = PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT,
|
||||
PARAM_LINEAR_UPPER_LIMIT = PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT,
|
||||
PARAM_LINEAR_LIMIT_SOFTNESS = PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS,
|
||||
PARAM_LINEAR_RESTITUTION = PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION,
|
||||
PARAM_LINEAR_DAMPING = PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING,
|
||||
PARAM_ANGULAR_LOWER_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT,
|
||||
PARAM_ANGULAR_UPPER_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT,
|
||||
PARAM_ANGULAR_LIMIT_SOFTNESS = PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS,
|
||||
PARAM_ANGULAR_DAMPING = PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING,
|
||||
PARAM_ANGULAR_RESTITUTION = PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION,
|
||||
PARAM_ANGULAR_FORCE_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_FORCE_LIMIT,
|
||||
PARAM_ANGULAR_ERP = PhysicsServer::G6DOF_JOINT_ANGULAR_ERP,
|
||||
PARAM_ANGULAR_MOTOR_TARGET_VELOCITY = PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY,
|
||||
PARAM_ANGULAR_MOTOR_FORCE_LIMIT = PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT,
|
||||
PARAM_MAX = PhysicsServer::G6DOF_JOINT_MAX,
|
||||
};
|
||||
|
||||
enum Flag {
|
||||
FLAG_ENABLE_LINEAR_LIMIT=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT,
|
||||
FLAG_ENABLE_ANGULAR_LIMIT=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT,
|
||||
FLAG_ENABLE_MOTOR=PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR,
|
||||
FLAG_MAX=PhysicsServer::G6DOF_JOINT_FLAG_MAX
|
||||
FLAG_ENABLE_LINEAR_LIMIT = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT,
|
||||
FLAG_ENABLE_ANGULAR_LIMIT = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT,
|
||||
FLAG_ENABLE_MOTOR = PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR,
|
||||
FLAG_MAX = PhysicsServer::G6DOF_JOINT_FLAG_MAX
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void _set_angular_hi_limit_x(float p_limit_angular);
|
||||
float _get_angular_hi_limit_x() const;
|
||||
|
||||
|
|
@ -320,34 +294,32 @@ protected:
|
|||
|
||||
virtual RID _configure_joint(PhysicsBody *body_a, PhysicsBody *body_b);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_param_x(Param p_param,float p_value);
|
||||
public:
|
||||
void set_param_x(Param p_param, float p_value);
|
||||
float get_param_x(Param p_param) const;
|
||||
|
||||
void set_param_y(Param p_param,float p_value);
|
||||
void set_param_y(Param p_param, float p_value);
|
||||
float get_param_y(Param p_param) const;
|
||||
|
||||
void set_param_z(Param p_param,float p_value);
|
||||
void set_param_z(Param p_param, float p_value);
|
||||
float get_param_z(Param p_param) const;
|
||||
|
||||
void set_flag_x(Flag p_flag,bool p_enabled);
|
||||
void set_flag_x(Flag p_flag, bool p_enabled);
|
||||
bool get_flag_x(Flag p_flag) const;
|
||||
|
||||
void set_flag_y(Flag p_flag,bool p_enabled);
|
||||
void set_flag_y(Flag p_flag, bool p_enabled);
|
||||
bool get_flag_y(Flag p_flag) const;
|
||||
|
||||
void set_flag_z(Flag p_flag,bool p_enabled);
|
||||
void set_flag_z(Flag p_flag, bool p_enabled);
|
||||
bool get_flag_z(Flag p_flag) const;
|
||||
|
||||
Generic6DOFJoint();
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST(Generic6DOFJoint::Param);
|
||||
VARIANT_ENUM_CAST(Generic6DOFJoint::Flag);
|
||||
|
||||
|
||||
#if 0
|
||||
class PhysicsJoint : public Spatial {
|
||||
|
||||
|
|
|
|||
|
|
@ -27,31 +27,31 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "portal.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "globals.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
bool Portal::_set(const StringName& p_name, const Variant& p_value) {
|
||||
bool Portal::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
if (p_name=="shape") {
|
||||
DVector<float> src_coords=p_value;
|
||||
if (p_name == "shape") {
|
||||
DVector<float> src_coords = p_value;
|
||||
Vector<Point2> points;
|
||||
int src_coords_size = src_coords.size();
|
||||
ERR_FAIL_COND_V(src_coords_size%2,false);
|
||||
points.resize(src_coords_size/2);
|
||||
for (int i=0;i<points.size();i++) {
|
||||
ERR_FAIL_COND_V(src_coords_size % 2, false);
|
||||
points.resize(src_coords_size / 2);
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
|
||||
points[i].x=src_coords[i*2+0];
|
||||
points[i].y=src_coords[i*2+1];
|
||||
points[i].x = src_coords[i * 2 + 0];
|
||||
points[i].y = src_coords[i * 2 + 1];
|
||||
set_shape(points);
|
||||
}
|
||||
} else if (p_name=="enabled") {
|
||||
} else if (p_name == "enabled") {
|
||||
set_enabled(p_value);
|
||||
} else if (p_name=="disable_distance") {
|
||||
} else if (p_name == "disable_distance") {
|
||||
set_disable_distance(p_value);
|
||||
} else if (p_name=="disabled_color") {
|
||||
} else if (p_name == "disabled_color") {
|
||||
set_disabled_color(p_value);
|
||||
} else if (p_name=="connect_range") {
|
||||
} else if (p_name == "connect_range") {
|
||||
set_connect_range(p_value);
|
||||
} else
|
||||
return false;
|
||||
|
|
@ -59,54 +59,53 @@ bool Portal::_set(const StringName& p_name, const Variant& p_value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Portal::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool Portal::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
if (p_name=="shape") {
|
||||
Vector<Point2> points=get_shape();
|
||||
if (p_name == "shape") {
|
||||
Vector<Point2> points = get_shape();
|
||||
DVector<float> dst_coords;
|
||||
dst_coords.resize(points.size()*2);
|
||||
dst_coords.resize(points.size() * 2);
|
||||
|
||||
for (int i=0;i<points.size();i++) {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
|
||||
dst_coords.set(i*2+0,points[i].x);
|
||||
dst_coords.set(i*2+1,points[i].y);
|
||||
dst_coords.set(i * 2 + 0, points[i].x);
|
||||
dst_coords.set(i * 2 + 1, points[i].y);
|
||||
}
|
||||
|
||||
r_ret= dst_coords;
|
||||
} else if (p_name=="enabled") {
|
||||
r_ret= is_enabled();
|
||||
} else if (p_name=="disable_distance") {
|
||||
r_ret= get_disable_distance();
|
||||
} else if (p_name=="disabled_color") {
|
||||
r_ret= get_disabled_color();
|
||||
} else if (p_name=="connect_range") {
|
||||
r_ret= get_connect_range();
|
||||
r_ret = dst_coords;
|
||||
} else if (p_name == "enabled") {
|
||||
r_ret = is_enabled();
|
||||
} else if (p_name == "disable_distance") {
|
||||
r_ret = get_disable_distance();
|
||||
} else if (p_name == "disabled_color") {
|
||||
r_ret = get_disabled_color();
|
||||
} else if (p_name == "connect_range") {
|
||||
r_ret = get_connect_range();
|
||||
} else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Portal::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
void Portal::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::REAL_ARRAY, "shape" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "enabled" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "disable_distance",PROPERTY_HINT_RANGE,"0,4096,0.01" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::COLOR, "disabled_color") );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "connect_range",PROPERTY_HINT_RANGE,"0.1,4096,0.01" ) );
|
||||
p_list->push_back(PropertyInfo(Variant::REAL_ARRAY, "shape"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "enabled"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "disable_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::COLOR, "disabled_color"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "connect_range", PROPERTY_HINT_RANGE, "0.1,4096,0.01"));
|
||||
}
|
||||
|
||||
|
||||
RES Portal::_get_gizmo_geometry() const {
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.8,0.8,0.7) );
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(1.0, 0.8, 0.8, 0.7));
|
||||
mat->set_line_width(4);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED,true);
|
||||
// mat->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER,true);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED, true);
|
||||
// mat->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(mat);
|
||||
|
|
@ -114,68 +113,63 @@ RES Portal::_get_gizmo_geometry() const {
|
|||
Vector<Point2> shape = get_shape();
|
||||
|
||||
Vector2 center;
|
||||
for (int i=0;i<shape.size();i++) {
|
||||
for (int i = 0; i < shape.size(); i++) {
|
||||
|
||||
int n=(i+1)%shape.size();
|
||||
int n = (i + 1) % shape.size();
|
||||
Vector<Vector3> points;
|
||||
surface_tool->add_vertex( Vector3( shape[i].x, shape[i].y,0 ));
|
||||
surface_tool->add_vertex( Vector3( shape[n].x, shape[n].y,0 ));
|
||||
center+=shape[i];
|
||||
|
||||
surface_tool->add_vertex(Vector3(shape[i].x, shape[i].y, 0));
|
||||
surface_tool->add_vertex(Vector3(shape[n].x, shape[n].y, 0));
|
||||
center += shape[i];
|
||||
}
|
||||
|
||||
if (shape.size()>0) {
|
||||
if (shape.size() > 0) {
|
||||
|
||||
center/=shape.size();
|
||||
center /= shape.size();
|
||||
Vector<Vector3> points;
|
||||
surface_tool->add_vertex( Vector3( center.x, center.y,0 ));
|
||||
surface_tool->add_vertex( Vector3( center.x, center.y,1.0 ));
|
||||
surface_tool->add_vertex(Vector3(center.x, center.y, 0));
|
||||
surface_tool->add_vertex(Vector3(center.x, center.y, 1.0));
|
||||
}
|
||||
|
||||
return surface_tool->commit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
AABB Portal::get_aabb() const {
|
||||
|
||||
return aabb;
|
||||
}
|
||||
DVector<Face3> Portal::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
if (!(p_usage_flags&FACES_ENCLOSING))
|
||||
if (!(p_usage_flags & FACES_ENCLOSING))
|
||||
return DVector<Face3>();
|
||||
|
||||
Vector<Point2> shape = get_shape();
|
||||
if (shape.size()==0)
|
||||
if (shape.size() == 0)
|
||||
return DVector<Face3>();
|
||||
|
||||
Vector2 center;
|
||||
for (int i=0;i<shape.size();i++) {
|
||||
|
||||
center+=shape[i];
|
||||
for (int i = 0; i < shape.size(); i++) {
|
||||
|
||||
center += shape[i];
|
||||
}
|
||||
|
||||
DVector<Face3> ret;
|
||||
center/=shape.size();
|
||||
center /= shape.size();
|
||||
|
||||
for (int i=0;i<shape.size();i++) {
|
||||
for (int i = 0; i < shape.size(); i++) {
|
||||
|
||||
int n=(i+1)%shape.size();
|
||||
int n = (i + 1) % shape.size();
|
||||
|
||||
Face3 f;
|
||||
f.vertex[0]=Vector3( center.x, center.y, 0 );
|
||||
f.vertex[1]=Vector3( shape[i].x, shape[i].y, 0 );
|
||||
f.vertex[2]=Vector3( shape[n].x, shape[n].y, 0 );
|
||||
f.vertex[0] = Vector3(center.x, center.y, 0);
|
||||
f.vertex[1] = Vector3(shape[i].x, shape[i].y, 0);
|
||||
f.vertex[2] = Vector3(shape[n].x, shape[n].y, 0);
|
||||
ret.push_back(f);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Portal::set_shape(const Vector<Point2>& p_shape) {
|
||||
|
||||
void Portal::set_shape(const Vector<Point2> &p_shape) {
|
||||
|
||||
VisualServer::get_singleton()->portal_set_shape(portal, p_shape);
|
||||
update_gizmo();
|
||||
|
|
@ -188,8 +182,8 @@ Vector<Point2> Portal::get_shape() const {
|
|||
|
||||
void Portal::set_connect_range(float p_range) {
|
||||
|
||||
connect_range=p_range;
|
||||
VisualServer::get_singleton()->portal_set_connect_range(portal,p_range);
|
||||
connect_range = p_range;
|
||||
VisualServer::get_singleton()->portal_set_connect_range(portal, p_range);
|
||||
}
|
||||
|
||||
float Portal::get_connect_range() const {
|
||||
|
|
@ -197,35 +191,31 @@ float Portal::get_connect_range() const {
|
|||
return connect_range;
|
||||
}
|
||||
|
||||
|
||||
void Portal::set_enabled(bool p_enabled) {
|
||||
|
||||
enabled=p_enabled;
|
||||
VisualServer::get_singleton()->portal_set_enabled(portal,enabled);
|
||||
enabled = p_enabled;
|
||||
VisualServer::get_singleton()->portal_set_enabled(portal, enabled);
|
||||
}
|
||||
|
||||
bool Portal::is_enabled() const {
|
||||
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void Portal::set_disable_distance(float p_distance) {
|
||||
|
||||
disable_distance=p_distance;
|
||||
VisualServer::get_singleton()->portal_set_disable_distance(portal,disable_distance);
|
||||
|
||||
disable_distance = p_distance;
|
||||
VisualServer::get_singleton()->portal_set_disable_distance(portal, disable_distance);
|
||||
}
|
||||
float Portal::get_disable_distance() const {
|
||||
|
||||
|
||||
return disable_distance;
|
||||
}
|
||||
|
||||
void Portal::set_disabled_color(const Color& p_disabled_color) {
|
||||
void Portal::set_disabled_color(const Color &p_disabled_color) {
|
||||
|
||||
disabled_color=p_disabled_color;
|
||||
VisualServer::get_singleton()->portal_set_disabled_color(portal,disabled_color);
|
||||
disabled_color = p_disabled_color;
|
||||
VisualServer::get_singleton()->portal_set_disabled_color(portal, disabled_color);
|
||||
}
|
||||
|
||||
Color Portal::get_disabled_color() const {
|
||||
|
|
@ -235,47 +225,40 @@ Color Portal::get_disabled_color() const {
|
|||
|
||||
void Portal::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shape","points"),&Portal::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape"),&Portal::get_shape);
|
||||
ObjectTypeDB::bind_method(_MD("set_shape", "points"), &Portal::set_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_shape"), &Portal::get_shape);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enable"),&Portal::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"),&Portal::is_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled", "enable"), &Portal::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"), &Portal::is_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_disable_distance","distance"),&Portal::set_disable_distance);
|
||||
ObjectTypeDB::bind_method(_MD("get_disable_distance"),&Portal::get_disable_distance);
|
||||
ObjectTypeDB::bind_method(_MD("set_disable_distance", "distance"), &Portal::set_disable_distance);
|
||||
ObjectTypeDB::bind_method(_MD("get_disable_distance"), &Portal::get_disable_distance);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_disabled_color","color"),&Portal::set_disabled_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_disabled_color"),&Portal::get_disabled_color);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_connect_range","range"),&Portal::set_connect_range);
|
||||
ObjectTypeDB::bind_method(_MD("get_connect_range"),&Portal::get_connect_range);
|
||||
ObjectTypeDB::bind_method(_MD("set_disabled_color", "color"), &Portal::set_disabled_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_disabled_color"), &Portal::get_disabled_color);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_connect_range", "range"), &Portal::set_connect_range);
|
||||
ObjectTypeDB::bind_method(_MD("get_connect_range"), &Portal::get_connect_range);
|
||||
}
|
||||
|
||||
Portal::Portal() {
|
||||
|
||||
portal = VisualServer::get_singleton()->portal_create();
|
||||
Vector< Point2 > points;
|
||||
points.push_back( Point2( -1, 1 ) );
|
||||
points.push_back( Point2( 1, 1 ) );
|
||||
points.push_back( Point2( 1, -1 ) );
|
||||
points.push_back( Point2( -1, -1 ) );
|
||||
Vector<Point2> points;
|
||||
points.push_back(Point2(-1, 1));
|
||||
points.push_back(Point2(1, 1));
|
||||
points.push_back(Point2(1, -1));
|
||||
points.push_back(Point2(-1, -1));
|
||||
set_shape(points); // default shape
|
||||
|
||||
|
||||
set_connect_range(0.8);
|
||||
set_disable_distance(50);
|
||||
set_enabled(true);
|
||||
|
||||
set_base(portal);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Portal::~Portal() {
|
||||
|
||||
VisualServer::get_singleton()->free(portal);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,11 @@
|
|||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/* Portal Logic:
|
||||
If a portal is placed next (very close to) a similar, opposing portal, they automatically connect,
|
||||
otherwise, a portal connects to the parent room
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class Portal : public VisualInstance {
|
||||
|
||||
OBJ_TYPE(Portal, VisualInstance);
|
||||
|
|
@ -58,15 +55,13 @@ class Portal : public VisualInstance {
|
|||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
protected:
|
||||
|
||||
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;
|
||||
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 void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
|
|
@ -76,10 +71,10 @@ public:
|
|||
void set_disable_distance(float p_distance);
|
||||
float get_disable_distance() const;
|
||||
|
||||
void set_disabled_color(const Color& p_disabled_color);
|
||||
void set_disabled_color(const Color &p_disabled_color);
|
||||
Color get_disabled_color() const;
|
||||
|
||||
void set_shape(const Vector<Point2>& p_shape);
|
||||
void set_shape(const Vector<Point2> &p_shape);
|
||||
Vector<Point2> get_shape() const;
|
||||
|
||||
void set_connect_range(float p_range);
|
||||
|
|
@ -87,7 +82,6 @@ public:
|
|||
|
||||
Portal();
|
||||
~Portal();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,36 +31,34 @@
|
|||
|
||||
RES Position3D::_get_gizmo_geometry() const {
|
||||
|
||||
|
||||
Ref<Mesh> mesh = memnew( Mesh );
|
||||
Ref<Mesh> mesh = memnew(Mesh);
|
||||
|
||||
DVector<Vector3> cursor_points;
|
||||
DVector<Color> cursor_colors;
|
||||
float cs = 0.25;
|
||||
cursor_points.push_back(Vector3(+cs,0,0));
|
||||
cursor_points.push_back(Vector3(-cs,0,0));
|
||||
cursor_points.push_back(Vector3(0,+cs,0));
|
||||
cursor_points.push_back(Vector3(0,-cs,0));
|
||||
cursor_points.push_back(Vector3(0,0,+cs));
|
||||
cursor_points.push_back(Vector3(0,0,-cs));
|
||||
cursor_colors.push_back(Color(1,0.5,0.5,1));
|
||||
cursor_colors.push_back(Color(1,0.5,0.5,1));
|
||||
cursor_colors.push_back(Color(0.5,1,0.5,1));
|
||||
cursor_colors.push_back(Color(0.5,1,0.5,1));
|
||||
cursor_colors.push_back(Color(0.5,0.5,1,1));
|
||||
cursor_colors.push_back(Color(0.5,0.5,1,1));
|
||||
cursor_points.push_back(Vector3(+cs, 0, 0));
|
||||
cursor_points.push_back(Vector3(-cs, 0, 0));
|
||||
cursor_points.push_back(Vector3(0, +cs, 0));
|
||||
cursor_points.push_back(Vector3(0, -cs, 0));
|
||||
cursor_points.push_back(Vector3(0, 0, +cs));
|
||||
cursor_points.push_back(Vector3(0, 0, -cs));
|
||||
cursor_colors.push_back(Color(1, 0.5, 0.5, 1));
|
||||
cursor_colors.push_back(Color(1, 0.5, 0.5, 1));
|
||||
cursor_colors.push_back(Color(0.5, 1, 0.5, 1));
|
||||
cursor_colors.push_back(Color(0.5, 1, 0.5, 1));
|
||||
cursor_colors.push_back(Color(0.5, 0.5, 1, 1));
|
||||
cursor_colors.push_back(Color(0.5, 0.5, 1, 1));
|
||||
|
||||
Ref<FixedMaterial> mat = memnew( FixedMaterial );
|
||||
mat->set_flag(Material::FLAG_UNSHADED,true);
|
||||
Ref<FixedMaterial> mat = memnew(FixedMaterial);
|
||||
mat->set_flag(Material::FLAG_UNSHADED, true);
|
||||
mat->set_line_width(3);
|
||||
Array d;
|
||||
d[Mesh::ARRAY_VERTEX]=cursor_points;
|
||||
d[Mesh::ARRAY_COLOR]=cursor_colors;
|
||||
mesh->add_surface(Mesh::PRIMITIVE_LINES,d);
|
||||
mesh->surface_set_material(0,mat);
|
||||
d[Mesh::ARRAY_VERTEX] = cursor_points;
|
||||
d[Mesh::ARRAY_COLOR] = cursor_colors;
|
||||
mesh->add_surface(Mesh::PRIMITIVE_LINES, d);
|
||||
mesh->surface_set_material(0, mat);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
Position3D::Position3D()
|
||||
{
|
||||
Position3D::Position3D() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,14 +31,13 @@
|
|||
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
class Position3D : public Spatial {
|
||||
class Position3D : public Spatial {
|
||||
|
||||
OBJ_TYPE(Position3D,Spatial);
|
||||
OBJ_TYPE(Position3D, Spatial);
|
||||
|
||||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
public:
|
||||
|
||||
Position3D();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ void ProximityGroup::clear_groups() {
|
|||
|
||||
E = E->next();
|
||||
};
|
||||
for (int i=0; i<num; i++) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
|
||||
groups.erase(remove_list[i]);
|
||||
};
|
||||
|
|
@ -74,7 +74,7 @@ void ProximityGroup::update_groups() {
|
|||
clear_groups();
|
||||
};
|
||||
|
||||
void ProximityGroup::add_groups(int* p_cell, String p_base, int p_depth) {
|
||||
void ProximityGroup::add_groups(int *p_cell, String p_base, int p_depth) {
|
||||
|
||||
p_base = p_base + "|";
|
||||
if (grid_radius[p_depth] == 0) {
|
||||
|
|
@ -89,7 +89,7 @@ void ProximityGroup::add_groups(int* p_cell, String p_base, int p_depth) {
|
|||
int start = p_cell[p_depth] - grid_radius[p_depth];
|
||||
int end = p_cell[p_depth] + grid_radius[p_depth];
|
||||
|
||||
for (int i=start; i<=end; i++) {
|
||||
for (int i = start; i <= end; i++) {
|
||||
|
||||
String gname = p_base + itos(i);
|
||||
if (p_depth == 2) {
|
||||
|
|
@ -102,7 +102,7 @@ void ProximityGroup::add_groups(int* p_cell, String p_base, int p_depth) {
|
|||
|
||||
void ProximityGroup::_new_group(StringName p_name) {
|
||||
|
||||
const Map<StringName, uint32_t>::Element* E = groups.find(p_name);
|
||||
const Map<StringName, uint32_t>::Element *E = groups.find(p_name);
|
||||
if (!E) {
|
||||
add_to_group(p_name);
|
||||
};
|
||||
|
|
@ -119,13 +119,13 @@ void ProximityGroup::_notification(int what) {
|
|||
|
||||
switch (what) {
|
||||
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
++group_version;
|
||||
clear_groups();
|
||||
break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED:
|
||||
update_groups();
|
||||
break;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
++group_version;
|
||||
clear_groups();
|
||||
break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED:
|
||||
update_groups();
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -138,7 +138,6 @@ void ProximityGroup::broadcast(String p_name, Variant p_params) {
|
|||
get_tree()->call_group(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_name, p_params);
|
||||
E = E->next();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void ProximityGroup::_proximity_group_broadcast(String p_name, Variant p_params) {
|
||||
|
|
@ -152,13 +151,12 @@ void ProximityGroup::_proximity_group_broadcast(String p_name, Variant p_params)
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
void ProximityGroup::set_dispatch_mode(int p_mode) {
|
||||
|
||||
dispatch_mode = (DispatchMode)p_mode;
|
||||
};
|
||||
|
||||
void ProximityGroup::set_grid_radius(const Vector3& p_radius) {
|
||||
void ProximityGroup::set_grid_radius(const Vector3 &p_radius) {
|
||||
|
||||
grid_radius = p_radius;
|
||||
};
|
||||
|
|
@ -168,31 +166,28 @@ Vector3 ProximityGroup::get_grid_radius() const {
|
|||
return grid_radius;
|
||||
};
|
||||
|
||||
|
||||
void ProximityGroup::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_group_name","name"), &ProximityGroup::set_group_name);
|
||||
ObjectTypeDB::bind_method(_MD("broadcast","name", "parameters"), &ProximityGroup::broadcast);
|
||||
ObjectTypeDB::bind_method(_MD("set_dispatch_mode","mode"), &ProximityGroup::set_dispatch_mode);
|
||||
ObjectTypeDB::bind_method(_MD("_proximity_group_broadcast","name","params"), &ProximityGroup::_proximity_group_broadcast);
|
||||
ObjectTypeDB::bind_method(_MD("set_grid_radius","radius"), &ProximityGroup::set_grid_radius);
|
||||
ObjectTypeDB::bind_method(_MD("set_group_name", "name"), &ProximityGroup::set_group_name);
|
||||
ObjectTypeDB::bind_method(_MD("broadcast", "name", "parameters"), &ProximityGroup::broadcast);
|
||||
ObjectTypeDB::bind_method(_MD("set_dispatch_mode", "mode"), &ProximityGroup::set_dispatch_mode);
|
||||
ObjectTypeDB::bind_method(_MD("_proximity_group_broadcast", "name", "params"), &ProximityGroup::_proximity_group_broadcast);
|
||||
ObjectTypeDB::bind_method(_MD("set_grid_radius", "radius"), &ProximityGroup::set_grid_radius);
|
||||
ObjectTypeDB::bind_method(_MD("get_grid_radius"), &ProximityGroup::get_grid_radius);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "grid_radius"), _SCS("set_grid_radius"), _SCS("get_grid_radius"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "grid_radius"), _SCS("set_grid_radius"), _SCS("get_grid_radius"));
|
||||
|
||||
ADD_SIGNAL( MethodInfo("broadcast", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::ARRAY, "parameters")) );
|
||||
ADD_SIGNAL(MethodInfo("broadcast", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::ARRAY, "parameters")));
|
||||
};
|
||||
|
||||
|
||||
ProximityGroup::ProximityGroup() {
|
||||
|
||||
group_version = 0;
|
||||
dispatch_mode = MODE_PROXY;
|
||||
|
||||
grid_radius = Vector3(1, 1, 1);
|
||||
|
||||
};
|
||||
|
||||
ProximityGroup::~ProximityGroup() {
|
||||
ProximityGroup::~ProximityGroup(){
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
class ProximityGroup : public Spatial {
|
||||
|
||||
OBJ_TYPE( ProximityGroup, Spatial );
|
||||
OBJ_TYPE(ProximityGroup, Spatial);
|
||||
OBJ_CATEGORY("3D");
|
||||
|
||||
public:
|
||||
|
|
@ -57,7 +57,7 @@ public:
|
|||
Vector3 grid_radius;
|
||||
uint32_t group_version;
|
||||
|
||||
void add_groups(int* p_cell, String p_base, int p_depth);
|
||||
void add_groups(int *p_cell, String p_base, int p_depth);
|
||||
void _new_group(StringName p_name);
|
||||
|
||||
void _proximity_group_broadcast(String p_name, Variant p_params);
|
||||
|
|
@ -65,12 +65,11 @@ public:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_group_name(String p_group_name);
|
||||
void broadcast(String p_name, Variant p_params);
|
||||
void set_dispatch_mode(int p_mode);
|
||||
|
||||
void set_grid_radius(const Vector3& p_radius);
|
||||
void set_grid_radius(const Vector3 &p_radius);
|
||||
Vector3 get_grid_radius() const;
|
||||
|
||||
ProximityGroup();
|
||||
|
|
@ -78,4 +77,3 @@ public:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -35,39 +35,36 @@ void Quad::_update() {
|
|||
return;
|
||||
|
||||
Vector3 normal;
|
||||
normal[axis]=1.0;
|
||||
|
||||
const int axis_order_1[3]={1,2,0};
|
||||
const int axis_order_2[3]={2,0,1};
|
||||
const int a1=axis_order_1[axis];
|
||||
const int a2=axis_order_2[axis];
|
||||
|
||||
normal[axis] = 1.0;
|
||||
|
||||
const int axis_order_1[3] = { 1, 2, 0 };
|
||||
const int axis_order_2[3] = { 2, 0, 1 };
|
||||
const int a1 = axis_order_1[axis];
|
||||
const int a2 = axis_order_2[axis];
|
||||
|
||||
DVector<Vector3> points;
|
||||
points.resize(4);
|
||||
DVector<Vector3>::Write pointsw = points.write();
|
||||
|
||||
Vector2 s2 = size*0.5;
|
||||
Vector2 s2 = size * 0.5;
|
||||
Vector2 o = offset;
|
||||
if (!centered)
|
||||
o+=s2;
|
||||
o += s2;
|
||||
|
||||
pointsw[0][a1]=-s2.x+offset.x;
|
||||
pointsw[0][a2]=s2.y+offset.y;
|
||||
pointsw[0][a1] = -s2.x + offset.x;
|
||||
pointsw[0][a2] = s2.y + offset.y;
|
||||
|
||||
pointsw[1][a1]=s2.x+offset.x;
|
||||
pointsw[1][a2]=s2.y+offset.y;
|
||||
pointsw[1][a1] = s2.x + offset.x;
|
||||
pointsw[1][a2] = s2.y + offset.y;
|
||||
|
||||
pointsw[2][a1]=s2.x+offset.x;
|
||||
pointsw[2][a2]=-s2.y+offset.y;
|
||||
pointsw[2][a1] = s2.x + offset.x;
|
||||
pointsw[2][a2] = -s2.y + offset.y;
|
||||
|
||||
pointsw[3][a1]=-s2.x+offset.x;
|
||||
pointsw[3][a2]=-s2.y+offset.y;
|
||||
pointsw[3][a1] = -s2.x + offset.x;
|
||||
pointsw[3][a2] = -s2.y + offset.y;
|
||||
|
||||
|
||||
aabb=AABB(pointsw[0],Vector3());
|
||||
for(int i=1;i<4;i++)
|
||||
aabb = AABB(pointsw[0], Vector3());
|
||||
for (int i = 1; i < 4; i++)
|
||||
aabb.expand_to(pointsw[i]);
|
||||
|
||||
pointsw = DVector<Vector3>::Write();
|
||||
|
|
@ -76,21 +73,19 @@ void Quad::_update() {
|
|||
normals.resize(4);
|
||||
DVector<Vector3>::Write normalsw = normals.write();
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
normalsw[i]=normal;
|
||||
|
||||
normalsw=DVector<Vector3>::Write();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
normalsw[i] = normal;
|
||||
|
||||
normalsw = DVector<Vector3>::Write();
|
||||
|
||||
DVector<Vector2> uvs;
|
||||
uvs.resize(4);
|
||||
DVector<Vector2>::Write uvsw = uvs.write();
|
||||
|
||||
uvsw[0]=Vector2(0,0);
|
||||
uvsw[1]=Vector2(1,0);
|
||||
uvsw[2]=Vector2(1,1);
|
||||
uvsw[3]=Vector2(0,1);
|
||||
uvsw[0] = Vector2(0, 0);
|
||||
uvsw[1] = Vector2(1, 0);
|
||||
uvsw[2] = Vector2(1, 1);
|
||||
uvsw[3] = Vector2(0, 1);
|
||||
|
||||
uvsw = DVector<Vector2>::Write();
|
||||
|
||||
|
|
@ -98,90 +93,86 @@ void Quad::_update() {
|
|||
indices.resize(6);
|
||||
|
||||
DVector<int>::Write indicesw = indices.write();
|
||||
indicesw[0]=0;
|
||||
indicesw[1]=1;
|
||||
indicesw[2]=2;
|
||||
indicesw[3]=2;
|
||||
indicesw[4]=3;
|
||||
indicesw[5]=0;
|
||||
indicesw[0] = 0;
|
||||
indicesw[1] = 1;
|
||||
indicesw[2] = 2;
|
||||
indicesw[3] = 2;
|
||||
indicesw[4] = 3;
|
||||
indicesw[5] = 0;
|
||||
|
||||
indicesw=DVector<int>::Write();
|
||||
indicesw = DVector<int>::Write();
|
||||
|
||||
Array arr;
|
||||
arr.resize(VS::ARRAY_MAX);
|
||||
arr[VS::ARRAY_VERTEX]=points;
|
||||
arr[VS::ARRAY_NORMAL]=normals;
|
||||
arr[VS::ARRAY_TEX_UV]=uvs;
|
||||
arr[VS::ARRAY_INDEX]=indices;
|
||||
|
||||
arr[VS::ARRAY_VERTEX] = points;
|
||||
arr[VS::ARRAY_NORMAL] = normals;
|
||||
arr[VS::ARRAY_TEX_UV] = uvs;
|
||||
arr[VS::ARRAY_INDEX] = indices;
|
||||
|
||||
if (configured) {
|
||||
VS::get_singleton()->mesh_remove_surface(mesh,0);
|
||||
VS::get_singleton()->mesh_remove_surface(mesh, 0);
|
||||
} else {
|
||||
configured=true;
|
||||
configured = true;
|
||||
}
|
||||
VS::get_singleton()->mesh_add_surface(mesh,VS::PRIMITIVE_TRIANGLES,arr);
|
||||
VS::get_singleton()->mesh_add_surface(mesh, VS::PRIMITIVE_TRIANGLES, arr);
|
||||
|
||||
pending_update=false;
|
||||
pending_update = false;
|
||||
}
|
||||
|
||||
|
||||
void Quad::set_axis(Vector3::Axis p_axis) {
|
||||
|
||||
axis=p_axis;
|
||||
axis = p_axis;
|
||||
_update();
|
||||
}
|
||||
|
||||
Vector3::Axis Quad::get_axis() const{
|
||||
Vector3::Axis Quad::get_axis() const {
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
void Quad::set_size(const Vector2& p_size){
|
||||
void Quad::set_size(const Vector2 &p_size) {
|
||||
|
||||
size=p_size;
|
||||
size = p_size;
|
||||
_update();
|
||||
}
|
||||
Vector2 Quad::get_size() const{
|
||||
Vector2 Quad::get_size() const {
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void Quad::set_offset(const Vector2& p_offset){
|
||||
void Quad::set_offset(const Vector2 &p_offset) {
|
||||
|
||||
offset=p_offset;
|
||||
offset = p_offset;
|
||||
_update();
|
||||
}
|
||||
Vector2 Quad::get_offset() const{
|
||||
Vector2 Quad::get_offset() const {
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void Quad::set_centered(bool p_enabled){
|
||||
void Quad::set_centered(bool p_enabled) {
|
||||
|
||||
centered=p_enabled;
|
||||
centered = p_enabled;
|
||||
_update();
|
||||
}
|
||||
bool Quad::is_centered() const{
|
||||
bool Quad::is_centered() const {
|
||||
|
||||
return centered;
|
||||
}
|
||||
|
||||
void Quad::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
if (pending_update)
|
||||
_update();
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
||||
pending_update=true;
|
||||
|
||||
pending_update = true;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
|
@ -197,38 +188,36 @@ AABB Quad::get_aabb() const {
|
|||
return aabb;
|
||||
}
|
||||
|
||||
void Quad::_bind_methods(){
|
||||
void Quad::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_axis","axis"),&Quad::set_axis);
|
||||
ObjectTypeDB::bind_method(_MD("get_axis"),&Quad::get_axis);
|
||||
ObjectTypeDB::bind_method(_MD("set_axis", "axis"), &Quad::set_axis);
|
||||
ObjectTypeDB::bind_method(_MD("get_axis"), &Quad::get_axis);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_size","size"),&Quad::set_size);
|
||||
ObjectTypeDB::bind_method(_MD("get_size"),&Quad::get_size);
|
||||
ObjectTypeDB::bind_method(_MD("set_size", "size"), &Quad::set_size);
|
||||
ObjectTypeDB::bind_method(_MD("get_size"), &Quad::get_size);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_centered","centered"),&Quad::set_centered);
|
||||
ObjectTypeDB::bind_method(_MD("is_centered"),&Quad::is_centered);
|
||||
ObjectTypeDB::bind_method(_MD("set_centered", "centered"), &Quad::set_centered);
|
||||
ObjectTypeDB::bind_method(_MD("is_centered"), &Quad::is_centered);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_offset","offset"),&Quad::set_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_offset"),&Quad::get_offset);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "quad/axis", PROPERTY_HINT_ENUM,"X,Y,Z" ), _SCS("set_axis"), _SCS("get_axis"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "quad/size" ), _SCS("set_size"), _SCS("get_size"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "quad/offset" ), _SCS("set_offset"), _SCS("get_offset"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "quad/centered" ), _SCS("set_centered"), _SCS("is_centered"));
|
||||
ObjectTypeDB::bind_method(_MD("set_offset", "offset"), &Quad::set_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_offset"), &Quad::get_offset);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "quad/axis", PROPERTY_HINT_ENUM, "X,Y,Z"), _SCS("set_axis"), _SCS("get_axis"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "quad/size"), _SCS("set_size"), _SCS("get_size"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "quad/offset"), _SCS("set_offset"), _SCS("get_offset"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "quad/centered"), _SCS("set_centered"), _SCS("is_centered"));
|
||||
}
|
||||
|
||||
Quad::Quad() {
|
||||
|
||||
pending_update=true;
|
||||
centered=true;
|
||||
pending_update = true;
|
||||
centered = true;
|
||||
//offset=0;
|
||||
size=Vector2(1,1);
|
||||
axis=Vector3::AXIS_Z;
|
||||
mesh=VisualServer::get_singleton()->mesh_create();
|
||||
size = Vector2(1, 1);
|
||||
axis = Vector3::AXIS_Z;
|
||||
mesh = VisualServer::get_singleton()->mesh_create();
|
||||
set_base(mesh);
|
||||
configured=false;
|
||||
|
||||
configured = false;
|
||||
}
|
||||
|
||||
Quad::~Quad() {
|
||||
|
|
|
|||
|
|
@ -29,13 +29,12 @@
|
|||
#ifndef QUAD_H
|
||||
#define QUAD_H
|
||||
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "rid.h"
|
||||
#include "scene/3d/visual_instance.h"
|
||||
|
||||
class Quad : public GeometryInstance {
|
||||
|
||||
OBJ_TYPE(Quad,GeometryInstance);
|
||||
OBJ_TYPE(Quad, GeometryInstance);
|
||||
|
||||
Vector3::Axis axis;
|
||||
bool centered;
|
||||
|
|
@ -50,18 +49,17 @@ class Quad : public GeometryInstance {
|
|||
void _update();
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_axis(Vector3::Axis p_axis);
|
||||
Vector3::Axis get_axis() const;
|
||||
|
||||
void set_size(const Vector2& p_sizze);
|
||||
void set_size(const Vector2 &p_sizze);
|
||||
Vector2 get_size() const;
|
||||
|
||||
void set_offset(const Vector2& p_offset);
|
||||
void set_offset(const Vector2 &p_offset);
|
||||
Vector2 get_offset() const;
|
||||
|
||||
void set_centered(bool p_enabled);
|
||||
|
|
@ -74,5 +72,4 @@ public:
|
|||
~Quad();
|
||||
};
|
||||
|
||||
|
||||
#endif // QUAD_H
|
||||
|
|
|
|||
|
|
@ -28,24 +28,23 @@
|
|||
/*************************************************************************/
|
||||
#include "ray_cast.h"
|
||||
|
||||
#include "servers/physics_server.h"
|
||||
#include "collision_object.h"
|
||||
void RayCast::set_cast_to(const Vector3& p_point) {
|
||||
#include "servers/physics_server.h"
|
||||
void RayCast::set_cast_to(const Vector3 &p_point) {
|
||||
|
||||
cast_to=p_point;
|
||||
cast_to = p_point;
|
||||
if (is_inside_tree() && (get_tree()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
|
||||
update_gizmo();
|
||||
|
||||
}
|
||||
|
||||
Vector3 RayCast::get_cast_to() const{
|
||||
Vector3 RayCast::get_cast_to() const {
|
||||
|
||||
return cast_to;
|
||||
}
|
||||
|
||||
void RayCast::set_layer_mask(uint32_t p_mask) {
|
||||
|
||||
layer_mask=p_mask;
|
||||
layer_mask = p_mask;
|
||||
}
|
||||
|
||||
uint32_t RayCast::get_layer_mask() const {
|
||||
|
|
@ -55,7 +54,7 @@ uint32_t RayCast::get_layer_mask() const {
|
|||
|
||||
void RayCast::set_type_mask(uint32_t p_mask) {
|
||||
|
||||
type_mask=p_mask;
|
||||
type_mask = p_mask;
|
||||
}
|
||||
|
||||
uint32_t RayCast::get_type_mask() const {
|
||||
|
|
@ -63,13 +62,13 @@ uint32_t RayCast::get_type_mask() const {
|
|||
return type_mask;
|
||||
}
|
||||
|
||||
bool RayCast::is_colliding() const{
|
||||
bool RayCast::is_colliding() const {
|
||||
|
||||
return collided;
|
||||
}
|
||||
Object *RayCast::get_collider() const{
|
||||
Object *RayCast::get_collider() const {
|
||||
|
||||
if (against==0)
|
||||
if (against == 0)
|
||||
return NULL;
|
||||
|
||||
return ObjectDB::get_instance(against);
|
||||
|
|
@ -79,37 +78,32 @@ int RayCast::get_collider_shape() const {
|
|||
|
||||
return against_shape;
|
||||
}
|
||||
Vector3 RayCast::get_collision_point() const{
|
||||
Vector3 RayCast::get_collision_point() const {
|
||||
|
||||
return collision_point;
|
||||
}
|
||||
Vector3 RayCast::get_collision_normal() const{
|
||||
Vector3 RayCast::get_collision_normal() const {
|
||||
|
||||
return collision_normal;
|
||||
}
|
||||
|
||||
|
||||
void RayCast::set_enabled(bool p_enabled) {
|
||||
|
||||
enabled=p_enabled;
|
||||
enabled = p_enabled;
|
||||
if (is_inside_tree() && !get_tree()->is_editor_hint())
|
||||
set_fixed_process(p_enabled);
|
||||
if (!p_enabled)
|
||||
collided=false;
|
||||
|
||||
collided = false;
|
||||
}
|
||||
|
||||
|
||||
bool RayCast::is_enabled() const {
|
||||
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
||||
void RayCast::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
|
|
@ -118,8 +112,6 @@ void RayCast::_notification(int p_what) {
|
|||
} else
|
||||
set_fixed_process(false);
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
||||
|
|
@ -127,7 +119,6 @@ void RayCast::_notification(int p_what) {
|
|||
set_fixed_process(false);
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_FIXED_PROCESS: {
|
||||
|
||||
|
|
@ -136,35 +127,34 @@ void RayCast::_notification(int p_what) {
|
|||
|
||||
_update_raycast_state();
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void RayCast::_update_raycast_state(){
|
||||
void RayCast::_update_raycast_state() {
|
||||
Ref<World> w3d = get_world();
|
||||
ERR_FAIL_COND( w3d.is_null() );
|
||||
ERR_FAIL_COND(w3d.is_null());
|
||||
|
||||
PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(w3d->get_space());
|
||||
ERR_FAIL_COND( !dss );
|
||||
ERR_FAIL_COND(!dss);
|
||||
|
||||
Transform gt = get_global_transform();
|
||||
|
||||
Vector3 to = cast_to;
|
||||
if (to==Vector3())
|
||||
to=Vector3(0,0.01,0);
|
||||
if (to == Vector3())
|
||||
to = Vector3(0, 0.01, 0);
|
||||
|
||||
PhysicsDirectSpaceState::RayResult rr;
|
||||
|
||||
if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude, layer_mask, type_mask)) {
|
||||
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) {
|
||||
|
||||
collided=true;
|
||||
against=rr.collider_id;
|
||||
collision_point=rr.position;
|
||||
collision_normal=rr.normal;
|
||||
against_shape=rr.shape;
|
||||
collided = true;
|
||||
against = rr.collider_id;
|
||||
collision_point = rr.position;
|
||||
collision_normal = rr.normal;
|
||||
against_shape = rr.shape;
|
||||
} else {
|
||||
collided=false;
|
||||
collided = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,85 +162,82 @@ void RayCast::force_raycast_update() {
|
|||
_update_raycast_state();
|
||||
}
|
||||
|
||||
void RayCast::add_exception_rid(const RID& p_rid) {
|
||||
void RayCast::add_exception_rid(const RID &p_rid) {
|
||||
|
||||
exclude.insert(p_rid);
|
||||
}
|
||||
|
||||
void RayCast::add_exception(const Object* p_object){
|
||||
void RayCast::add_exception(const Object *p_object) {
|
||||
|
||||
ERR_FAIL_NULL(p_object);
|
||||
CollisionObject *co=((Object*)p_object)->cast_to<CollisionObject>();
|
||||
CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
|
||||
if (!co)
|
||||
return;
|
||||
add_exception_rid(co->get_rid());
|
||||
}
|
||||
|
||||
void RayCast::remove_exception_rid(const RID& p_rid) {
|
||||
void RayCast::remove_exception_rid(const RID &p_rid) {
|
||||
|
||||
exclude.erase(p_rid);
|
||||
}
|
||||
|
||||
void RayCast::remove_exception(const Object* p_object){
|
||||
void RayCast::remove_exception(const Object *p_object) {
|
||||
|
||||
ERR_FAIL_NULL(p_object);
|
||||
CollisionObject *co=((Object*)p_object)->cast_to<CollisionObject>();
|
||||
CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
|
||||
if (!co)
|
||||
return;
|
||||
remove_exception_rid(co->get_rid());
|
||||
}
|
||||
|
||||
|
||||
void RayCast::clear_exceptions(){
|
||||
void RayCast::clear_exceptions() {
|
||||
|
||||
exclude.clear();
|
||||
}
|
||||
|
||||
|
||||
void RayCast::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled", "enabled"), &RayCast::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"), &RayCast::is_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&RayCast::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"),&RayCast::is_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("set_cast_to", "local_point"), &RayCast::set_cast_to);
|
||||
ObjectTypeDB::bind_method(_MD("get_cast_to"), &RayCast::get_cast_to);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cast_to","local_point"),&RayCast::set_cast_to);
|
||||
ObjectTypeDB::bind_method(_MD("get_cast_to"),&RayCast::get_cast_to);
|
||||
ObjectTypeDB::bind_method(_MD("is_colliding"), &RayCast::is_colliding);
|
||||
ObjectTypeDB::bind_method(_MD("force_raycast_update"), &RayCast::force_raycast_update);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("is_colliding"),&RayCast::is_colliding);
|
||||
ObjectTypeDB::bind_method(_MD("force_raycast_update"),&RayCast::force_raycast_update);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider"), &RayCast::get_collider);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_shape"), &RayCast::get_collider_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_point"), &RayCast::get_collision_point);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_normal"), &RayCast::get_collision_normal);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_collider"),&RayCast::get_collider);
|
||||
ObjectTypeDB::bind_method(_MD("get_collider_shape"),&RayCast::get_collider_shape);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_point"),&RayCast::get_collision_point);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_normal"),&RayCast::get_collision_normal);
|
||||
ObjectTypeDB::bind_method(_MD("add_exception_rid", "rid"), &RayCast::add_exception_rid);
|
||||
ObjectTypeDB::bind_method(_MD("add_exception", "node"), &RayCast::add_exception);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_exception_rid","rid"),&RayCast::add_exception_rid);
|
||||
ObjectTypeDB::bind_method(_MD("add_exception","node"),&RayCast::add_exception);
|
||||
ObjectTypeDB::bind_method(_MD("remove_exception_rid", "rid"), &RayCast::remove_exception_rid);
|
||||
ObjectTypeDB::bind_method(_MD("remove_exception", "node"), &RayCast::remove_exception);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("remove_exception_rid","rid"),&RayCast::remove_exception_rid);
|
||||
ObjectTypeDB::bind_method(_MD("remove_exception","node"),&RayCast::remove_exception);
|
||||
ObjectTypeDB::bind_method(_MD("clear_exceptions"), &RayCast::clear_exceptions);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast::clear_exceptions);
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask", "mask"), &RayCast::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"), &RayCast::get_layer_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast::get_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("set_type_mask", "mask"), &RayCast::set_type_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_type_mask"), &RayCast::get_type_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast::set_type_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast::get_type_mask);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), _SCS("set_cast_to"), _SCS("get_cast_to"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_ALL_FLAGS), _SCS("set_layer_mask"), _SCS("get_layer_mask"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), _SCS("set_type_mask"), _SCS("get_type_mask"));
|
||||
}
|
||||
|
||||
RayCast::RayCast() {
|
||||
|
||||
enabled=false;
|
||||
against=0;
|
||||
collided=false;
|
||||
against_shape=0;
|
||||
layer_mask=1;
|
||||
type_mask=PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
|
||||
cast_to=Vector3(0,-1,0);
|
||||
enabled = false;
|
||||
against = 0;
|
||||
collided = false;
|
||||
against_shape = 0;
|
||||
layer_mask = 1;
|
||||
type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
|
||||
cast_to = Vector3(0, -1, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@
|
|||
|
||||
class RayCast : public Spatial {
|
||||
|
||||
OBJ_TYPE(RayCast,Spatial);
|
||||
|
||||
OBJ_TYPE(RayCast, Spatial);
|
||||
|
||||
bool enabled;
|
||||
bool collided;
|
||||
|
|
@ -51,16 +50,15 @@ class RayCast : public Spatial {
|
|||
uint32_t type_mask;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
void _update_raycast_state();
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void set_cast_to(const Vector3& p_point);
|
||||
void set_cast_to(const Vector3 &p_point);
|
||||
Vector3 get_cast_to() const;
|
||||
|
||||
void set_layer_mask(uint32_t p_mask);
|
||||
|
|
@ -76,10 +74,10 @@ public:
|
|||
Vector3 get_collision_point() const;
|
||||
Vector3 get_collision_normal() const;
|
||||
|
||||
void add_exception_rid(const RID& p_rid);
|
||||
void add_exception(const Object* p_object);
|
||||
void remove_exception_rid(const RID& p_rid);
|
||||
void remove_exception(const Object* p_object);
|
||||
void add_exception_rid(const RID &p_rid);
|
||||
void add_exception(const Object *p_object);
|
||||
void remove_exception_rid(const RID &p_rid);
|
||||
void remove_exception(const Object *p_object);
|
||||
void clear_exceptions();
|
||||
|
||||
RayCast();
|
||||
|
|
|
|||
|
|
@ -34,77 +34,72 @@
|
|||
#include "globals.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
|
||||
void Room::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
// go find parent level
|
||||
Node *parent_room=get_parent();
|
||||
level=0;
|
||||
Node *parent_room = get_parent();
|
||||
level = 0;
|
||||
|
||||
while(parent_room) {
|
||||
while (parent_room) {
|
||||
|
||||
Room *r = parent_room->cast_to<Room>();
|
||||
if (r) {
|
||||
|
||||
level=r->level+1;
|
||||
level = r->level + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
parent_room=parent_room->get_parent();
|
||||
parent_room = parent_room->get_parent();
|
||||
}
|
||||
|
||||
|
||||
if (sound_enabled)
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room,get_world()->get_sound_space());
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room, get_world()->get_sound_space());
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
SpatialSoundServer::get_singleton()->room_set_transform(sound_room,get_global_transform());
|
||||
SpatialSoundServer::get_singleton()->room_set_transform(sound_room, get_global_transform());
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
||||
if (sound_enabled)
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room,RID());
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room, RID());
|
||||
|
||||
|
||||
} break;
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
RES Room::_get_gizmo_geometry() const {
|
||||
|
||||
DVector<Face3> faces;
|
||||
if (!room.is_null())
|
||||
faces=room->get_geometry_hint();
|
||||
faces = room->get_geometry_hint();
|
||||
|
||||
int count=faces.size();
|
||||
if (count==0)
|
||||
int count = faces.size();
|
||||
if (count == 0)
|
||||
return RES();
|
||||
|
||||
DVector<Face3>::Read facesr=faces.read();
|
||||
DVector<Face3>::Read facesr = faces.read();
|
||||
|
||||
const Face3* facesptr=facesr.ptr();
|
||||
const Face3 *facesptr = facesr.ptr();
|
||||
|
||||
DVector<Vector3> points;
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.2,0.8,0.9,0.3) );
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.2, 0.8, 0.9, 0.3));
|
||||
mat->set_line_width(4);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED,true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED, true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(mat);
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
surface_tool->add_vertex(facesptr[i].vertex[0]);
|
||||
surface_tool->add_vertex(facesptr[i].vertex[1]);
|
||||
|
|
@ -114,14 +109,11 @@ RES Room::_get_gizmo_geometry() const {
|
|||
|
||||
surface_tool->add_vertex(facesptr[i].vertex[2]);
|
||||
surface_tool->add_vertex(facesptr[i].vertex[0]);
|
||||
|
||||
}
|
||||
|
||||
return surface_tool->commit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
AABB Room::get_aabb() const {
|
||||
|
||||
if (room.is_null())
|
||||
|
|
@ -132,12 +124,11 @@ AABB Room::get_aabb() const {
|
|||
DVector<Face3> Room::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
return DVector<Face3>();
|
||||
|
||||
}
|
||||
|
||||
void Room::set_room( const Ref<RoomBounds>& p_room ) {
|
||||
void Room::set_room(const Ref<RoomBounds> &p_room) {
|
||||
|
||||
room=p_room;
|
||||
room = p_room;
|
||||
update_gizmo();
|
||||
|
||||
if (room.is_valid()) {
|
||||
|
|
@ -150,14 +141,11 @@ void Room::set_room( const Ref<RoomBounds>& p_room ) {
|
|||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
|
||||
propagate_notification(NOTIFICATION_AREA_CHANGED);
|
||||
update_gizmo();
|
||||
|
||||
if (room.is_valid())
|
||||
SpatialSoundServer::get_singleton()->room_set_bounds(sound_room,room->get_bounds());
|
||||
|
||||
|
||||
SpatialSoundServer::get_singleton()->room_set_bounds(sound_room, room->get_bounds());
|
||||
}
|
||||
|
||||
Ref<RoomBounds> Room::get_room() const {
|
||||
|
|
@ -165,86 +153,76 @@ Ref<RoomBounds> Room::get_room() const {
|
|||
return room;
|
||||
}
|
||||
|
||||
void Room::_parse_node_faces(DVector<Face3> &all_faces,const Node *p_node) const {
|
||||
void Room::_parse_node_faces(DVector<Face3> &all_faces, const Node *p_node) const {
|
||||
|
||||
const VisualInstance *vi=p_node->cast_to<VisualInstance>();
|
||||
const VisualInstance *vi = p_node->cast_to<VisualInstance>();
|
||||
|
||||
if (vi) {
|
||||
DVector<Face3> faces=vi->get_faces(FACES_ENCLOSING);
|
||||
DVector<Face3> faces = vi->get_faces(FACES_ENCLOSING);
|
||||
|
||||
if (faces.size()) {
|
||||
int old_len=all_faces.size();
|
||||
all_faces.resize( all_faces.size() + faces.size() );
|
||||
int new_len=all_faces.size();
|
||||
DVector<Face3>::Write all_facesw=all_faces.write();
|
||||
Face3 * all_facesptr=all_facesw.ptr();
|
||||
int old_len = all_faces.size();
|
||||
all_faces.resize(all_faces.size() + faces.size());
|
||||
int new_len = all_faces.size();
|
||||
DVector<Face3>::Write all_facesw = all_faces.write();
|
||||
Face3 *all_facesptr = all_facesw.ptr();
|
||||
|
||||
DVector<Face3>::Read facesr=faces.read();
|
||||
const Face3 * facesptr=facesr.ptr();
|
||||
DVector<Face3>::Read facesr = faces.read();
|
||||
const Face3 *facesptr = facesr.ptr();
|
||||
|
||||
Transform tr=vi->get_relative_transform(this);
|
||||
Transform tr = vi->get_relative_transform(this);
|
||||
|
||||
for(int i=old_len;i<new_len;i++) {
|
||||
for (int i = old_len; i < new_len; i++) {
|
||||
|
||||
Face3 f=facesptr[i-old_len];
|
||||
for (int j=0;j<3;j++)
|
||||
f.vertex[j]=tr.xform(f.vertex[j]);
|
||||
all_facesptr[i]=f;
|
||||
Face3 f = facesptr[i - old_len];
|
||||
for (int j = 0; j < 3; j++)
|
||||
f.vertex[j] = tr.xform(f.vertex[j]);
|
||||
all_facesptr[i] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
|
||||
for (int i=0;i<p_node->get_child_count();i++) {
|
||||
|
||||
_parse_node_faces(all_faces,p_node->get_child(i));
|
||||
_parse_node_faces(all_faces, p_node->get_child(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Room::compute_room_from_subtree() {
|
||||
|
||||
|
||||
DVector<Face3> all_faces;
|
||||
_parse_node_faces(all_faces,this);
|
||||
_parse_node_faces(all_faces, this);
|
||||
|
||||
|
||||
if (all_faces.size()==0)
|
||||
if (all_faces.size() == 0)
|
||||
return;
|
||||
float error;
|
||||
DVector<Face3> wrapped_faces = Geometry::wrap_geometry(all_faces,&error);
|
||||
DVector<Face3> wrapped_faces = Geometry::wrap_geometry(all_faces, &error);
|
||||
|
||||
|
||||
if (wrapped_faces.size()==0)
|
||||
if (wrapped_faces.size() == 0)
|
||||
return;
|
||||
|
||||
BSP_Tree tree(wrapped_faces,error);
|
||||
BSP_Tree tree(wrapped_faces, error);
|
||||
|
||||
Ref<RoomBounds> room( memnew( RoomBounds ) );
|
||||
Ref<RoomBounds> room(memnew(RoomBounds));
|
||||
room->set_bounds(tree);
|
||||
room->set_geometry_hint(wrapped_faces);
|
||||
|
||||
set_room(room);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Room::set_simulate_acoustics(bool p_enable) {
|
||||
|
||||
if (sound_enabled==p_enable)
|
||||
if (sound_enabled == p_enable)
|
||||
return;
|
||||
|
||||
sound_enabled=p_enable;
|
||||
sound_enabled = p_enable;
|
||||
if (!is_inside_world())
|
||||
return; //nothing to do
|
||||
|
||||
if (sound_enabled)
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room,get_world()->get_sound_space());
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room, get_world()->get_sound_space());
|
||||
else
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room,RID());
|
||||
|
||||
|
||||
SpatialSoundServer::get_singleton()->room_set_space(sound_room, RID());
|
||||
}
|
||||
|
||||
void Room::_bounds_changed() {
|
||||
|
|
@ -257,8 +235,6 @@ bool Room::is_simulating_acoustics() const {
|
|||
return sound_enabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RID Room::get_sound_room() const {
|
||||
|
||||
return RID();
|
||||
|
|
@ -266,34 +242,26 @@ RID Room::get_sound_room() const {
|
|||
|
||||
void Room::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_room","room:Room"),&Room::set_room );
|
||||
ObjectTypeDB::bind_method(_MD("get_room:Room"),&Room::get_room );
|
||||
ObjectTypeDB::bind_method(_MD("compute_room_from_subtree"),&Room::compute_room_from_subtree);
|
||||
ObjectTypeDB::bind_method(_MD("set_room", "room:Room"), &Room::set_room);
|
||||
ObjectTypeDB::bind_method(_MD("get_room:Room"), &Room::get_room);
|
||||
ObjectTypeDB::bind_method(_MD("compute_room_from_subtree"), &Room::compute_room_from_subtree);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_simulate_acoustics", "enable"), &Room::set_simulate_acoustics);
|
||||
ObjectTypeDB::bind_method(_MD("is_simulating_acoustics"), &Room::is_simulating_acoustics);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_simulate_acoustics","enable"),&Room::set_simulate_acoustics );
|
||||
ObjectTypeDB::bind_method(_MD("is_simulating_acoustics"),&Room::is_simulating_acoustics );
|
||||
|
||||
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "room/room", PROPERTY_HINT_RESOURCE_TYPE, "Area" ), _SCS("set_room"), _SCS("get_room") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "room/simulate_acoustics"), _SCS("set_simulate_acoustics"), _SCS("is_simulating_acoustics") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "room/room", PROPERTY_HINT_RESOURCE_TYPE, "Area"), _SCS("set_room"), _SCS("get_room"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "room/simulate_acoustics"), _SCS("set_simulate_acoustics"), _SCS("is_simulating_acoustics"));
|
||||
}
|
||||
|
||||
|
||||
Room::Room() {
|
||||
|
||||
sound_enabled=false;
|
||||
sound_room=SpatialSoundServer::get_singleton()->room_create();
|
||||
|
||||
level=0;
|
||||
sound_enabled = false;
|
||||
sound_room = SpatialSoundServer::get_singleton()->room_create();
|
||||
|
||||
level = 0;
|
||||
}
|
||||
|
||||
|
||||
Room::~Room() {
|
||||
|
||||
SpatialSoundServer::get_singleton()->free(sound_room);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/* RoomInstance Logic:
|
||||
a) Instances that belong to the room are drawn only if the room is visible (seen through portal, or player inside)
|
||||
b) Instances that don't belong to any room are considered to belong to the root room (RID empty)
|
||||
|
|
@ -44,15 +43,11 @@
|
|||
|
||||
*/
|
||||
|
||||
|
||||
class Room : public VisualInstance {
|
||||
|
||||
OBJ_TYPE( Room, VisualInstance );
|
||||
OBJ_TYPE(Room, VisualInstance);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Ref<RoomBounds> room;
|
||||
|
||||
|
|
@ -61,29 +56,26 @@ private:
|
|||
bool sound_enabled;
|
||||
|
||||
int level;
|
||||
void _parse_node_faces(DVector<Face3> &all_faces,const Node *p_node) const;
|
||||
|
||||
void _parse_node_faces(DVector<Face3> &all_faces, const Node *p_node) const;
|
||||
|
||||
void _bounds_changed();
|
||||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
// used to notify portals that the room in which they are has changed.
|
||||
NOTIFICATION_AREA_CHANGED=60
|
||||
NOTIFICATION_AREA_CHANGED = 60
|
||||
};
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
void set_room( const Ref<RoomBounds>& p_room );
|
||||
void set_room(const Ref<RoomBounds> &p_room);
|
||||
Ref<RoomBounds> get_room() const;
|
||||
|
||||
void set_simulate_acoustics(bool p_enable);
|
||||
|
|
@ -95,8 +87,6 @@ public:
|
|||
|
||||
Room();
|
||||
~Room();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ROOM_INSTANCE_H
|
||||
|
|
|
|||
|
|
@ -28,49 +28,42 @@
|
|||
/*************************************************************************/
|
||||
#include "scenario_fx.h"
|
||||
|
||||
|
||||
|
||||
void WorldEnvironment::_notification(int p_what) {
|
||||
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_WORLD) {
|
||||
if (p_what == NOTIFICATION_ENTER_WORLD) {
|
||||
|
||||
if (environment.is_valid()) {
|
||||
if (get_world()->get_environment().is_valid()) {
|
||||
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
|
||||
}
|
||||
get_world()->set_environment(environment);
|
||||
add_to_group("_world_environment_"+itos(get_world()->get_scenario().get_id()));
|
||||
|
||||
add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
|
||||
}
|
||||
|
||||
} else if (p_what==NOTIFICATION_EXIT_WORLD) {
|
||||
} else if (p_what == NOTIFICATION_EXIT_WORLD) {
|
||||
|
||||
if (environment.is_valid() && get_world()->get_environment()==environment) {
|
||||
if (environment.is_valid() && get_world()->get_environment() == environment) {
|
||||
get_world()->set_environment(Ref<Environment>());
|
||||
remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id()));
|
||||
|
||||
remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldEnvironment::set_environment(const Ref<Environment>& p_environment) {
|
||||
void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
|
||||
|
||||
if (is_inside_world() && environment.is_valid() && get_world()->get_environment()==environment) {
|
||||
if (is_inside_world() && environment.is_valid() && get_world()->get_environment() == environment) {
|
||||
get_world()->set_environment(Ref<Environment>());
|
||||
remove_from_group("_world_environment_"+itos(get_world()->get_scenario().get_id()));
|
||||
remove_from_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
|
||||
//clean up
|
||||
}
|
||||
|
||||
|
||||
environment=p_environment;
|
||||
environment = p_environment;
|
||||
if (is_inside_world() && environment.is_valid()) {
|
||||
if (get_world()->get_environment().is_valid()) {
|
||||
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
|
||||
}
|
||||
get_world()->set_environment(environment);
|
||||
add_to_group("_world_environment_"+itos(get_world()->get_scenario().get_id()));
|
||||
|
||||
add_to_group("_world_environment_" + itos(get_world()->get_scenario().get_id()));
|
||||
}
|
||||
|
||||
update_configuration_warning();
|
||||
|
|
@ -86,29 +79,22 @@ String WorldEnvironment::get_configuration_warning() const {
|
|||
if (!is_visible() || !is_inside_tree() || !environment.is_valid())
|
||||
return String();
|
||||
|
||||
List<Node*> nodes;
|
||||
get_tree()->get_nodes_in_group("_world_environment_"+itos(get_world()->get_scenario().get_id()),&nodes);
|
||||
List<Node *> nodes;
|
||||
get_tree()->get_nodes_in_group("_world_environment_" + itos(get_world()->get_scenario().get_id()), &nodes);
|
||||
|
||||
if (nodes.size()>1) {
|
||||
if (nodes.size() > 1) {
|
||||
return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
void WorldEnvironment::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_environment","env:Environment"),&WorldEnvironment::set_environment);
|
||||
ObjectTypeDB::bind_method(_MD("get_environment:Environment"),&WorldEnvironment::get_environment);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment"),_SCS("set_environment"),_SCS("get_environment"));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_environment", "env:Environment"), &WorldEnvironment::set_environment);
|
||||
ObjectTypeDB::bind_method(_MD("get_environment:Environment"), &WorldEnvironment::get_environment);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), _SCS("set_environment"), _SCS("get_environment"));
|
||||
}
|
||||
|
||||
|
||||
WorldEnvironment::WorldEnvironment() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,30 +31,27 @@
|
|||
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
class WorldEnvironment : public Spatial {
|
||||
|
||||
OBJ_TYPE(WorldEnvironment,Spatial );
|
||||
OBJ_TYPE(WorldEnvironment, Spatial);
|
||||
|
||||
Ref<Environment> environment;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_environment(const Ref<Environment>& p_environment);
|
||||
void set_environment(const Ref<Environment> &p_environment);
|
||||
Ref<Environment> get_environment() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
WorldEnvironment();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,50 +30,48 @@
|
|||
|
||||
#include "message_queue.h"
|
||||
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "core/globals.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
|
||||
bool Skeleton::_set(const StringName& p_path, const Variant& p_value) {
|
||||
bool Skeleton::_set(const StringName &p_path, const Variant &p_value) {
|
||||
|
||||
String path = p_path;
|
||||
|
||||
if (!path.begins_with("bones/"))
|
||||
return false;
|
||||
|
||||
int which=path.get_slicec('/',1).to_int();
|
||||
String what=path.get_slicec('/',2);
|
||||
int which = path.get_slicec('/', 1).to_int();
|
||||
String what = path.get_slicec('/', 2);
|
||||
|
||||
|
||||
if (which==bones.size() && what=="name") {
|
||||
if (which == bones.size() && what == "name") {
|
||||
|
||||
add_bone(p_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
ERR_FAIL_INDEX_V( which, bones.size(), false );
|
||||
ERR_FAIL_INDEX_V(which, bones.size(), false);
|
||||
|
||||
if (what=="parent")
|
||||
set_bone_parent(which, p_value );
|
||||
else if (what=="rest")
|
||||
if (what == "parent")
|
||||
set_bone_parent(which, p_value);
|
||||
else if (what == "rest")
|
||||
set_bone_rest(which, p_value);
|
||||
else if (what=="enabled")
|
||||
else if (what == "enabled")
|
||||
set_bone_enabled(which, p_value);
|
||||
else if (what=="pose")
|
||||
else if (what == "pose")
|
||||
set_bone_pose(which, p_value);
|
||||
else if (what=="bound_childs") {
|
||||
Array children=p_value;
|
||||
else if (what == "bound_childs") {
|
||||
Array children = p_value;
|
||||
|
||||
if (is_inside_tree()) {
|
||||
bones[which].nodes_bound.clear();
|
||||
|
||||
for (int i=0;i<children.size();i++) {
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
|
||||
NodePath path=children[i];
|
||||
ERR_CONTINUE( path.operator String()=="" );
|
||||
NodePath path = children[i];
|
||||
ERR_CONTINUE(path.operator String() == "");
|
||||
Node *node = get_node(path);
|
||||
ERR_CONTINUE(!node);
|
||||
bind_child_node_to_bone(which,node);
|
||||
bind_child_node_to_bone(which, node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -83,72 +81,70 @@ bool Skeleton::_set(const StringName& p_path, const Variant& p_value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Skeleton::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool Skeleton::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
String path=p_name;
|
||||
String path = p_name;
|
||||
|
||||
if (!path.begins_with("bones/"))
|
||||
return false;
|
||||
|
||||
int which=path.get_slicec('/',1).to_int();
|
||||
String what=path.get_slicec('/',2);
|
||||
int which = path.get_slicec('/', 1).to_int();
|
||||
String what = path.get_slicec('/', 2);
|
||||
|
||||
ERR_FAIL_INDEX_V( which, bones.size(), false );
|
||||
ERR_FAIL_INDEX_V(which, bones.size(), false);
|
||||
|
||||
if (what=="name")
|
||||
r_ret=get_bone_name(which);
|
||||
else if (what=="parent")
|
||||
r_ret=get_bone_parent(which);
|
||||
else if (what=="rest")
|
||||
r_ret=get_bone_rest(which);
|
||||
else if (what=="enabled")
|
||||
r_ret=is_bone_enabled(which);
|
||||
else if (what=="pose")
|
||||
r_ret=get_bone_pose(which);
|
||||
else if (what=="bound_childs") {
|
||||
if (what == "name")
|
||||
r_ret = get_bone_name(which);
|
||||
else if (what == "parent")
|
||||
r_ret = get_bone_parent(which);
|
||||
else if (what == "rest")
|
||||
r_ret = get_bone_rest(which);
|
||||
else if (what == "enabled")
|
||||
r_ret = is_bone_enabled(which);
|
||||
else if (what == "pose")
|
||||
r_ret = get_bone_pose(which);
|
||||
else if (what == "bound_childs") {
|
||||
Array children;
|
||||
|
||||
for (const List<uint32_t>::Element *E=bones[which].nodes_bound.front();E;E=E->next()) {
|
||||
for (const List<uint32_t>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
|
||||
|
||||
Object *obj=ObjectDB::get_instance(E->get());
|
||||
Object *obj = ObjectDB::get_instance(E->get());
|
||||
ERR_CONTINUE(!obj);
|
||||
Node *node=obj->cast_to<Node>();
|
||||
Node *node = obj->cast_to<Node>();
|
||||
ERR_CONTINUE(!node);
|
||||
NodePath path=get_path_to(node);
|
||||
NodePath path = get_path_to(node);
|
||||
children.push_back(path);
|
||||
|
||||
}
|
||||
|
||||
r_ret=children;
|
||||
r_ret = children;
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
void Skeleton::_get_property_list( List<PropertyInfo>* p_list ) const {
|
||||
void Skeleton::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
for (int i=0;i<bones.size();i++) {
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
|
||||
String prep="bones/"+itos(i)+"/";
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, prep+"name" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, prep+"parent" , PROPERTY_HINT_RANGE,"-1,"+itos(i-1)+",1") );
|
||||
p_list->push_back( PropertyInfo( Variant::TRANSFORM, prep+"rest" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, prep+"enabled" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::TRANSFORM, prep+"pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ) );
|
||||
p_list->push_back( PropertyInfo( Variant::ARRAY, prep+"bound_childs" ) );
|
||||
String prep = "bones/" + itos(i) + "/";
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(i - 1) + ",1"));
|
||||
p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled"));
|
||||
p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_childs"));
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
if (dirty) {
|
||||
|
||||
dirty=false;
|
||||
dirty = false;
|
||||
_make_dirty(); // property make it dirty
|
||||
}
|
||||
|
||||
|
|
@ -158,97 +154,95 @@ void Skeleton::_notification(int p_what) {
|
|||
} break;
|
||||
case NOTIFICATION_UPDATE_SKELETON: {
|
||||
|
||||
VisualServer *vs = VisualServer::get_singleton();
|
||||
Bone *bonesptr = &bones[0];
|
||||
int len = bones.size();
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
Bone *bonesptr=&bones[0];
|
||||
int len=bones.size();
|
||||
|
||||
vs->skeleton_resize( skeleton, len ); // if same size, nothin really happens
|
||||
vs->skeleton_resize(skeleton, len); // if same size, nothin really happens
|
||||
|
||||
// pose changed, rebuild cache of inverses
|
||||
if (rest_global_inverse_dirty) {
|
||||
|
||||
// calculate global rests and invert them
|
||||
for (int i=0;i<len;i++) {
|
||||
Bone &b=bonesptr[i];
|
||||
if (b.parent>=0)
|
||||
b.rest_global_inverse=bonesptr[b.parent].rest_global_inverse * b.rest;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Bone &b = bonesptr[i];
|
||||
if (b.parent >= 0)
|
||||
b.rest_global_inverse = bonesptr[b.parent].rest_global_inverse * b.rest;
|
||||
else
|
||||
b.rest_global_inverse=b.rest;
|
||||
b.rest_global_inverse = b.rest;
|
||||
}
|
||||
for (int i=0;i<len;i++) {
|
||||
Bone &b=bonesptr[i];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Bone &b = bonesptr[i];
|
||||
b.rest_global_inverse.affine_invert();
|
||||
}
|
||||
|
||||
rest_global_inverse_dirty=false;
|
||||
|
||||
rest_global_inverse_dirty = false;
|
||||
}
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
Bone &b=bonesptr[i];
|
||||
Bone &b = bonesptr[i];
|
||||
|
||||
if (b.disable_rest) {
|
||||
if (b.enabled) {
|
||||
|
||||
Transform pose=b.pose;
|
||||
Transform pose = b.pose;
|
||||
if (b.custom_pose_enable) {
|
||||
|
||||
pose = b.custom_pose * pose;
|
||||
}
|
||||
|
||||
if (b.parent>=0) {
|
||||
if (b.parent >= 0) {
|
||||
|
||||
b.pose_global=bonesptr[b.parent].pose_global * pose;
|
||||
b.pose_global = bonesptr[b.parent].pose_global * pose;
|
||||
} else {
|
||||
|
||||
b.pose_global=pose;
|
||||
b.pose_global = pose;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (b.parent>=0) {
|
||||
if (b.parent >= 0) {
|
||||
|
||||
b.pose_global=bonesptr[b.parent].pose_global;
|
||||
b.pose_global = bonesptr[b.parent].pose_global;
|
||||
} else {
|
||||
|
||||
b.pose_global=Transform();
|
||||
b.pose_global = Transform();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (b.enabled) {
|
||||
|
||||
Transform pose=b.pose;
|
||||
Transform pose = b.pose;
|
||||
if (b.custom_pose_enable) {
|
||||
|
||||
pose = b.custom_pose * pose;
|
||||
}
|
||||
|
||||
if (b.parent>=0) {
|
||||
if (b.parent >= 0) {
|
||||
|
||||
b.pose_global=bonesptr[b.parent].pose_global * (b.rest * pose);
|
||||
b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
|
||||
} else {
|
||||
|
||||
b.pose_global=b.rest * pose;
|
||||
b.pose_global = b.rest * pose;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (b.parent>=0) {
|
||||
if (b.parent >= 0) {
|
||||
|
||||
b.pose_global=bonesptr[b.parent].pose_global * b.rest;
|
||||
b.pose_global = bonesptr[b.parent].pose_global * b.rest;
|
||||
} else {
|
||||
|
||||
b.pose_global=b.rest;
|
||||
b.pose_global = b.rest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vs->skeleton_bone_set_transform( skeleton, i, b.pose_global * b.rest_global_inverse );
|
||||
vs->skeleton_bone_set_transform(skeleton, i, b.pose_global * b.rest_global_inverse);
|
||||
|
||||
for(List<uint32_t>::Element *E=b.nodes_bound.front();E;E=E->next()) {
|
||||
for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
|
||||
|
||||
Object *obj=ObjectDB::get_instance(E->get());
|
||||
Object *obj = ObjectDB::get_instance(E->get());
|
||||
ERR_CONTINUE(!obj);
|
||||
Spatial *sp = obj->cast_to<Spatial>();
|
||||
ERR_CONTINUE(!sp);
|
||||
|
|
@ -256,38 +250,35 @@ void Skeleton::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
dirty=false;
|
||||
dirty = false;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
Transform Skeleton::get_bone_transform(int p_bone) const {
|
||||
ERR_FAIL_INDEX_V(p_bone,bones.size(),Transform());
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
|
||||
if (dirty)
|
||||
const_cast<Skeleton*>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
return bones[p_bone].pose_global * bones[p_bone].rest_global_inverse;
|
||||
}
|
||||
|
||||
void Skeleton::set_bone_global_pose(int p_bone, const Transform &p_pose) {
|
||||
|
||||
void Skeleton::set_bone_global_pose(int p_bone,const Transform& p_pose) {
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
if (bones[p_bone].parent == -1) {
|
||||
|
||||
ERR_FAIL_INDEX(p_bone,bones.size());
|
||||
if (bones[p_bone].parent==-1) {
|
||||
|
||||
set_bone_pose(p_bone,bones[p_bone].rest_global_inverse * p_pose); //fast
|
||||
set_bone_pose(p_bone, bones[p_bone].rest_global_inverse * p_pose); //fast
|
||||
} else {
|
||||
|
||||
set_bone_pose(p_bone, bones[p_bone].rest.affine_inverse() * (get_bone_global_pose(bones[p_bone].parent).affine_inverse() * p_pose)); //slow
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Transform Skeleton::get_bone_global_pose(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_bone,bones.size(),Transform());
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
|
||||
if (dirty)
|
||||
const_cast<Skeleton*>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
|
||||
return bones[p_bone].pose_global;
|
||||
}
|
||||
|
||||
|
|
@ -297,28 +288,28 @@ RID Skeleton::get_skeleton() const {
|
|||
}
|
||||
|
||||
// skeleton creation api
|
||||
void Skeleton::add_bone(const String& p_name) {
|
||||
void Skeleton::add_bone(const String &p_name) {
|
||||
|
||||
ERR_FAIL_COND( p_name=="" || p_name.find(":")!=-1 || p_name.find("/")!=-1 );
|
||||
ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1);
|
||||
|
||||
for (int i=0;i<bones.size();i++) {
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
|
||||
ERR_FAIL_COND( bones[i].name=="p_name");
|
||||
ERR_FAIL_COND(bones[i].name == "p_name");
|
||||
}
|
||||
|
||||
Bone b;
|
||||
b.name=p_name;
|
||||
b.name = p_name;
|
||||
bones.push_back(b);
|
||||
|
||||
rest_global_inverse_dirty=true;
|
||||
rest_global_inverse_dirty = true;
|
||||
_make_dirty();
|
||||
update_gizmo();
|
||||
}
|
||||
int Skeleton::find_bone(String p_name) const {
|
||||
|
||||
for (int i=0;i<bones.size();i++) {
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
|
||||
if (bones[i].name==p_name)
|
||||
if (bones[i].name == p_name)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +317,7 @@ int Skeleton::find_bone(String p_name) const {
|
|||
}
|
||||
String Skeleton::get_bone_name(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), "" );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), "");
|
||||
|
||||
return bones[p_bone].name;
|
||||
}
|
||||
|
|
@ -338,293 +329,265 @@ int Skeleton::get_bone_count() const {
|
|||
|
||||
void Skeleton::set_bone_parent(int p_bone, int p_parent) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_COND( p_parent!=-1 && (p_parent<0 || p_parent>=p_bone));
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
ERR_FAIL_COND(p_parent != -1 && (p_parent < 0 || p_parent >= p_bone));
|
||||
|
||||
bones[p_bone].parent=p_parent;
|
||||
rest_global_inverse_dirty=true;
|
||||
bones[p_bone].parent = p_parent;
|
||||
rest_global_inverse_dirty = true;
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
void Skeleton::unparent_bone_and_rest(int p_bone) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
int parent=bones[p_bone].parent;
|
||||
while(parent>=0) {
|
||||
int parent = bones[p_bone].parent;
|
||||
while (parent >= 0) {
|
||||
bones[p_bone].rest = bones[parent].rest * bones[p_bone].rest;
|
||||
parent=bones[parent].parent;
|
||||
parent = bones[parent].parent;
|
||||
}
|
||||
|
||||
bones[p_bone].parent=-1;
|
||||
bones[p_bone].rest_global_inverse=bones[p_bone].rest.affine_inverse(); //same thing
|
||||
bones[p_bone].parent = -1;
|
||||
bones[p_bone].rest_global_inverse = bones[p_bone].rest.affine_inverse(); //same thing
|
||||
|
||||
_make_dirty();
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
bones[p_bone].disable_rest=p_disable;
|
||||
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
bones[p_bone].disable_rest = p_disable;
|
||||
}
|
||||
|
||||
bool Skeleton::is_bone_rest_disabled(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), false );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
|
||||
return bones[p_bone].disable_rest;
|
||||
}
|
||||
|
||||
|
||||
int Skeleton::get_bone_parent(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), -1 );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), -1);
|
||||
|
||||
return bones[p_bone].parent;
|
||||
}
|
||||
|
||||
void Skeleton::set_bone_rest(int p_bone, const Transform& p_rest) {
|
||||
void Skeleton::set_bone_rest(int p_bone, const Transform &p_rest) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
bones[p_bone].rest=p_rest;
|
||||
rest_global_inverse_dirty=true;
|
||||
bones[p_bone].rest = p_rest;
|
||||
rest_global_inverse_dirty = true;
|
||||
_make_dirty();
|
||||
|
||||
}
|
||||
Transform Skeleton::get_bone_rest(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), Transform() );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
|
||||
|
||||
return bones[p_bone].rest;
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::set_bone_enabled(int p_bone, bool p_enabled) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
bones[p_bone].enabled=p_enabled;
|
||||
rest_global_inverse_dirty=true;
|
||||
bones[p_bone].enabled = p_enabled;
|
||||
rest_global_inverse_dirty = true;
|
||||
_make_dirty();
|
||||
}
|
||||
bool Skeleton::is_bone_enabled(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), false );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
|
||||
return bones[p_bone].enabled;
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::bind_child_node_to_bone(int p_bone,Node *p_node) {
|
||||
void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) {
|
||||
|
||||
ERR_FAIL_NULL(p_node);
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
uint32_t id=p_node->get_instance_ID();
|
||||
uint32_t id = p_node->get_instance_ID();
|
||||
|
||||
for (List<uint32_t>::Element *E=bones[p_bone].nodes_bound.front();E;E=E->next()) {
|
||||
for (List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
|
||||
|
||||
if (E->get()==id)
|
||||
if (E->get() == id)
|
||||
return; // already here
|
||||
}
|
||||
|
||||
bones[p_bone].nodes_bound.push_back(id);
|
||||
|
||||
}
|
||||
void Skeleton::unbind_child_node_from_bone(int p_bone,Node *p_node) {
|
||||
void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
|
||||
|
||||
ERR_FAIL_NULL(p_node);
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
uint32_t id=p_node->get_instance_ID();
|
||||
uint32_t id = p_node->get_instance_ID();
|
||||
bones[p_bone].nodes_bound.erase(id);
|
||||
|
||||
}
|
||||
void Skeleton::get_bound_child_nodes_to_bone(int p_bone,List<Node*> *p_bound) const {
|
||||
void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
|
||||
for (const List<uint32_t>::Element *E=bones[p_bone].nodes_bound.front();E;E=E->next()) {
|
||||
for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
|
||||
|
||||
Object *obj=ObjectDB::get_instance(E->get());
|
||||
Object *obj = ObjectDB::get_instance(E->get());
|
||||
ERR_CONTINUE(!obj);
|
||||
p_bound->push_back(obj->cast_to<Node>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::clear_bones() {
|
||||
|
||||
bones.clear();
|
||||
rest_global_inverse_dirty=true;
|
||||
rest_global_inverse_dirty = true;
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
// posing api
|
||||
|
||||
void Skeleton::set_bone_pose(int p_bone, const Transform& p_pose) {
|
||||
void Skeleton::set_bone_pose(int p_bone, const Transform &p_pose) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
ERR_FAIL_COND( !is_inside_tree() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
|
||||
bones[p_bone].pose=p_pose;
|
||||
bones[p_bone].pose = p_pose;
|
||||
_make_dirty();
|
||||
}
|
||||
Transform Skeleton::get_bone_pose(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), Transform() );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
|
||||
return bones[p_bone].pose;
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::set_bone_custom_pose(int p_bone, const Transform& p_custom_pose) {
|
||||
void Skeleton::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) {
|
||||
|
||||
ERR_FAIL_INDEX( p_bone, bones.size() );
|
||||
// ERR_FAIL_COND( !is_inside_scene() );
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
// ERR_FAIL_COND( !is_inside_scene() );
|
||||
|
||||
|
||||
bones[p_bone].custom_pose_enable=(p_custom_pose!=Transform());
|
||||
bones[p_bone].custom_pose=p_custom_pose;
|
||||
bones[p_bone].custom_pose_enable = (p_custom_pose != Transform());
|
||||
bones[p_bone].custom_pose = p_custom_pose;
|
||||
|
||||
_make_dirty();
|
||||
}
|
||||
|
||||
Transform Skeleton::get_bone_custom_pose(int p_bone) const {
|
||||
|
||||
ERR_FAIL_INDEX_V( p_bone, bones.size(), Transform() );
|
||||
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
|
||||
return bones[p_bone].custom_pose;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::_make_dirty() {
|
||||
|
||||
if (dirty)
|
||||
return;
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
dirty=true;
|
||||
dirty = true;
|
||||
return;
|
||||
}
|
||||
MessageQueue::get_singleton()->push_notification( this, NOTIFICATION_UPDATE_SKELETON );
|
||||
dirty=true;
|
||||
MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
||||
RES Skeleton::_get_gizmo_geometry() const {
|
||||
|
||||
if (!GLOBAL_DEF("debug/draw_skeleton", true))
|
||||
return RES();
|
||||
|
||||
if (bones.size()==0)
|
||||
if (bones.size() == 0)
|
||||
return RES();
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.6,1.0,0.3,0.1) );
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.6, 1.0, 0.3, 0.1));
|
||||
mat->set_line_width(4);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED,true);
|
||||
mat->set_flag(Material::FLAG_ONTOP,true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
mat->set_flag(Material::FLAG_UNSHADED, true);
|
||||
mat->set_flag(Material::FLAG_ONTOP, true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_LINES);
|
||||
surface_tool->set_material(mat);
|
||||
|
||||
const Bone *bonesptr = &bones[0];
|
||||
int len = bones.size();
|
||||
|
||||
const Bone *bonesptr=&bones[0];
|
||||
int len=bones.size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
const Bone &b=bonesptr[i];
|
||||
const Bone &b = bonesptr[i];
|
||||
|
||||
Transform t;
|
||||
if (b.parent<0)
|
||||
if (b.parent < 0)
|
||||
continue;
|
||||
|
||||
Vector3 v1=(bonesptr[b.parent].pose_global * bonesptr[b.parent].rest_global_inverse).xform(bonesptr[b.parent].rest_global_inverse.affine_inverse().origin);
|
||||
Vector3 v2=(b.pose_global * b.rest_global_inverse).xform(b.rest_global_inverse.affine_inverse().origin);
|
||||
Vector3 v1 = (bonesptr[b.parent].pose_global * bonesptr[b.parent].rest_global_inverse).xform(bonesptr[b.parent].rest_global_inverse.affine_inverse().origin);
|
||||
Vector3 v2 = (b.pose_global * b.rest_global_inverse).xform(b.rest_global_inverse.affine_inverse().origin);
|
||||
|
||||
surface_tool->add_vertex(v1);
|
||||
surface_tool->add_vertex(v2);
|
||||
|
||||
}
|
||||
|
||||
return surface_tool->commit();
|
||||
|
||||
}
|
||||
|
||||
void Skeleton::localize_rests() {
|
||||
|
||||
for(int i=bones.size()-1;i>=0;i--) {
|
||||
for (int i = bones.size() - 1; i >= 0; i--) {
|
||||
|
||||
if (bones[i].parent>=0)
|
||||
set_bone_rest(i,bones[bones[i].parent].rest.affine_inverse() * bones[i].rest);
|
||||
if (bones[i].parent >= 0)
|
||||
set_bone_rest(i, bones[bones[i].parent].rest.affine_inverse() * bones[i].rest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Skeleton::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_bone", "name"), &Skeleton::add_bone);
|
||||
ObjectTypeDB::bind_method(_MD("find_bone", "name"), &Skeleton::find_bone);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_name", "bone_idx"), &Skeleton::get_bone_name);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_parent", "bone_idx"), &Skeleton::get_bone_parent);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_parent", "bone_idx", "parent_idx"), &Skeleton::set_bone_parent);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_count"), &Skeleton::get_bone_count);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_bone","name"),&Skeleton::add_bone);
|
||||
ObjectTypeDB::bind_method(_MD("find_bone","name"),&Skeleton::find_bone);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_name","bone_idx"),&Skeleton::get_bone_name);
|
||||
ObjectTypeDB::bind_method(_MD("unparent_bone_and_rest", "bone_idx"), &Skeleton::unparent_bone_and_rest);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_parent","bone_idx"),&Skeleton::get_bone_parent);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_parent","bone_idx","parent_idx"),&Skeleton::set_bone_parent);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_rest", "bone_idx"), &Skeleton::get_bone_rest);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_rest", "bone_idx", "rest"), &Skeleton::set_bone_rest);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_count"),&Skeleton::get_bone_count);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_disable_rest", "bone_idx", "disable"), &Skeleton::set_bone_disable_rest);
|
||||
ObjectTypeDB::bind_method(_MD("is_bone_rest_disabled", "bone_idx"), &Skeleton::is_bone_rest_disabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("unparent_bone_and_rest","bone_idx"),&Skeleton::unparent_bone_and_rest);
|
||||
ObjectTypeDB::bind_method(_MD("bind_child_node_to_bone", "bone_idx", "node:Node"), &Skeleton::bind_child_node_to_bone);
|
||||
ObjectTypeDB::bind_method(_MD("unbind_child_node_from_bone", "bone_idx", "node:Node"), &Skeleton::unbind_child_node_from_bone);
|
||||
ObjectTypeDB::bind_method(_MD("get_bound_child_nodes_to_bone", "bone_idx"), &Skeleton::_get_bound_child_nodes_to_bone);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_rest","bone_idx"),&Skeleton::get_bone_rest);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_rest","bone_idx","rest"),&Skeleton::set_bone_rest);
|
||||
ObjectTypeDB::bind_method(_MD("clear_bones"), &Skeleton::clear_bones);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_disable_rest","bone_idx","disable"),&Skeleton::set_bone_disable_rest);
|
||||
ObjectTypeDB::bind_method(_MD("is_bone_rest_disabled","bone_idx"),&Skeleton::is_bone_rest_disabled);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_pose", "bone_idx"), &Skeleton::get_bone_pose);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_pose", "bone_idx", "pose"), &Skeleton::set_bone_pose);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("bind_child_node_to_bone","bone_idx","node:Node"),&Skeleton::bind_child_node_to_bone);
|
||||
ObjectTypeDB::bind_method(_MD("unbind_child_node_from_bone","bone_idx","node:Node"),&Skeleton::unbind_child_node_from_bone);
|
||||
ObjectTypeDB::bind_method(_MD("get_bound_child_nodes_to_bone","bone_idx"),&Skeleton::_get_bound_child_nodes_to_bone);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_global_pose", "bone_idx", "pose"), &Skeleton::set_bone_global_pose);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_global_pose", "bone_idx"), &Skeleton::get_bone_global_pose);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("clear_bones"),&Skeleton::clear_bones);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_custom_pose", "bone_idx"), &Skeleton::get_bone_custom_pose);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton::set_bone_custom_pose);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_pose","bone_idx"),&Skeleton::get_bone_pose);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_pose","bone_idx","pose"),&Skeleton::set_bone_pose);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_global_pose","bone_idx","pose"),&Skeleton::set_bone_global_pose);
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_global_pose","bone_idx"),&Skeleton::get_bone_global_pose);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_custom_pose","bone_idx"),&Skeleton::get_bone_custom_pose);
|
||||
ObjectTypeDB::bind_method(_MD("set_bone_custom_pose","bone_idx","custom_pose"),&Skeleton::set_bone_custom_pose);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_bone_transform","bone_idx"),&Skeleton::get_bone_transform);
|
||||
|
||||
BIND_CONSTANT( NOTIFICATION_UPDATE_SKELETON );
|
||||
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Skeleton::Skeleton() {
|
||||
|
||||
rest_global_inverse_dirty=true;
|
||||
dirty=false;
|
||||
skeleton=VisualServer::get_singleton()->skeleton_create();
|
||||
rest_global_inverse_dirty = true;
|
||||
dirty = false;
|
||||
skeleton = VisualServer::get_singleton()->skeleton_create();
|
||||
}
|
||||
|
||||
|
||||
Skeleton::~Skeleton() {
|
||||
|
||||
VisualServer::get_singleton()->free( skeleton );
|
||||
VisualServer::get_singleton()->free(skeleton);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@
|
|||
#ifndef SKELETON_H
|
||||
#define SKELETON_H
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "rid.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class Skeleton : public Spatial {
|
||||
|
||||
OBJ_TYPE( Skeleton, Spatial );
|
||||
OBJ_TYPE(Skeleton, Spatial);
|
||||
|
||||
struct Bone {
|
||||
|
||||
|
|
@ -58,7 +58,12 @@ class Skeleton : public Spatial {
|
|||
|
||||
List<uint32_t> nodes_bound;
|
||||
|
||||
Bone() { parent=-1; enabled=true; custom_pose_enable=false; disable_rest=false; }
|
||||
Bone() {
|
||||
parent = -1;
|
||||
enabled = true;
|
||||
custom_pose_enable = false;
|
||||
disable_rest = false;
|
||||
}
|
||||
};
|
||||
|
||||
bool rest_global_inverse_dirty;
|
||||
|
|
@ -70,16 +75,16 @@ class Skeleton : public Spatial {
|
|||
void _make_dirty();
|
||||
bool dirty;
|
||||
|
||||
//bind helpers
|
||||
//bind helpers
|
||||
Array _get_bound_child_nodes_to_bone(int p_bone) const {
|
||||
|
||||
Array bound;
|
||||
List<Node*> childs;
|
||||
get_bound_child_nodes_to_bone(p_bone,&childs);
|
||||
List<Node *> childs;
|
||||
get_bound_child_nodes_to_bone(p_bone, &childs);
|
||||
|
||||
for (int i=0;i<childs.size();i++) {
|
||||
for (int i = 0; i < childs.size(); i++) {
|
||||
|
||||
bound.push_back( childs[i] );
|
||||
bound.push_back(childs[i]);
|
||||
}
|
||||
return bound;
|
||||
}
|
||||
|
|
@ -87,25 +92,22 @@ class Skeleton : public Spatial {
|
|||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
protected:
|
||||
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
void _get_property_list( List<PropertyInfo>* p_list ) const;
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
|
||||
NOTIFICATION_UPDATE_SKELETON=50
|
||||
NOTIFICATION_UPDATE_SKELETON = 50
|
||||
};
|
||||
|
||||
|
||||
RID get_skeleton() const;
|
||||
|
||||
// skeleton creation api
|
||||
void add_bone(const String&p_name);
|
||||
void add_bone(const String &p_name);
|
||||
int find_bone(String p_name) const;
|
||||
String get_bone_name(int p_bone) const;
|
||||
|
||||
|
|
@ -119,35 +121,34 @@ public:
|
|||
|
||||
int get_bone_count() const;
|
||||
|
||||
void set_bone_rest(int p_bone, const Transform& p_rest);
|
||||
void set_bone_rest(int p_bone, const Transform &p_rest);
|
||||
Transform get_bone_rest(int p_bone) const;
|
||||
Transform get_bone_transform(int p_bone) const;
|
||||
Transform get_bone_global_pose(int p_bone) const;
|
||||
|
||||
void set_bone_global_pose(int p_bone,const Transform& p_pose);
|
||||
void set_bone_global_pose(int p_bone, const Transform &p_pose);
|
||||
|
||||
void set_bone_enabled(int p_bone, bool p_enabled);
|
||||
bool is_bone_enabled(int p_bone) const;
|
||||
|
||||
void bind_child_node_to_bone(int p_bone,Node *p_node);
|
||||
void unbind_child_node_from_bone(int p_bone,Node *p_node);
|
||||
void get_bound_child_nodes_to_bone(int p_bone,List<Node*> *p_bound) const;
|
||||
void bind_child_node_to_bone(int p_bone, Node *p_node);
|
||||
void unbind_child_node_from_bone(int p_bone, Node *p_node);
|
||||
void get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const;
|
||||
|
||||
void clear_bones();
|
||||
|
||||
// posing api
|
||||
|
||||
void set_bone_pose(int p_bone, const Transform& p_pose);
|
||||
void set_bone_pose(int p_bone, const Transform &p_pose);
|
||||
Transform get_bone_pose(int p_bone) const;
|
||||
|
||||
void set_bone_custom_pose(int p_bone, const Transform& p_custom_pose);
|
||||
void set_bone_custom_pose(int p_bone, const Transform &p_custom_pose);
|
||||
Transform get_bone_custom_pose(int p_bone) const;
|
||||
|
||||
void localize_rests(); // used for loaders and tools
|
||||
|
||||
Skeleton();
|
||||
~Skeleton();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
/*************************************************************************/
|
||||
#include "spatial.h"
|
||||
|
||||
#include "scene/main/viewport.h"
|
||||
#include "message_queue.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
/*
|
||||
|
|
@ -66,10 +66,7 @@ future: no idea
|
|||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
SpatialGizmo::SpatialGizmo() {
|
||||
|
||||
}
|
||||
|
||||
void Spatial::_notify_dirty() {
|
||||
|
|
@ -80,14 +77,12 @@ void Spatial::_notify_dirty() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Spatial::_update_local_transform() const {
|
||||
|
||||
data.local_transform.basis.set_euler(data.rotation);
|
||||
data.local_transform.basis.scale(data.scale);
|
||||
|
||||
data.dirty&=~DIRTY_LOCAL;
|
||||
data.dirty &= ~DIRTY_LOCAL;
|
||||
}
|
||||
void Spatial::_propagate_transform_changed(Spatial *p_origin) {
|
||||
|
||||
|
|
@ -95,53 +90,51 @@ void Spatial::_propagate_transform_changed(Spatial *p_origin) {
|
|||
return;
|
||||
}
|
||||
|
||||
// if (data.dirty&DIRTY_GLOBAL)
|
||||
// return; //already dirty
|
||||
// if (data.dirty&DIRTY_GLOBAL)
|
||||
// return; //already dirty
|
||||
|
||||
data.children_lock++;
|
||||
|
||||
for (List<Spatial*>::Element *E=data.children.front();E;E=E->next()) {
|
||||
for (List<Spatial *>::Element *E = data.children.front(); E; E = E->next()) {
|
||||
|
||||
if (E->get()->data.toplevel_active)
|
||||
continue; //don't propagate to a toplevel
|
||||
E->get()->_propagate_transform_changed(p_origin);
|
||||
}
|
||||
|
||||
|
||||
if (!data.ignore_notification && !xform_change.in_list()) {
|
||||
|
||||
get_tree()->xform_change_list.add(&xform_change);
|
||||
|
||||
}
|
||||
data.dirty|=DIRTY_GLOBAL;
|
||||
data.dirty |= DIRTY_GLOBAL;
|
||||
|
||||
data.children_lock--;
|
||||
}
|
||||
|
||||
void Spatial::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
Node *p = get_parent();
|
||||
if (p)
|
||||
data.parent=p->cast_to<Spatial>();
|
||||
data.parent = p->cast_to<Spatial>();
|
||||
|
||||
if (data.parent)
|
||||
data.C=data.parent->data.children.push_back(this);
|
||||
data.C = data.parent->data.children.push_back(this);
|
||||
else
|
||||
data.C=NULL;
|
||||
data.C = NULL;
|
||||
|
||||
if (data.toplevel && !get_tree()->is_editor_hint()) {
|
||||
|
||||
if (data.parent) {
|
||||
data.local_transform = data.parent->get_global_transform() * get_transform();
|
||||
data.dirty=DIRTY_VECTORS; //global is always dirty upon entering a scene
|
||||
data.dirty = DIRTY_VECTORS; //global is always dirty upon entering a scene
|
||||
}
|
||||
data.toplevel_active=true;
|
||||
data.toplevel_active = true;
|
||||
}
|
||||
|
||||
data.dirty|=DIRTY_GLOBAL; //global is always dirty upon entering a scene
|
||||
data.dirty |= DIRTY_GLOBAL; //global is always dirty upon entering a scene
|
||||
_notify_dirty();
|
||||
|
||||
notification(NOTIFICATION_ENTER_WORLD);
|
||||
|
|
@ -149,38 +142,37 @@ void Spatial::_notification(int p_what) {
|
|||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
||||
notification(NOTIFICATION_EXIT_WORLD,true);
|
||||
notification(NOTIFICATION_EXIT_WORLD, true);
|
||||
if (xform_change.in_list())
|
||||
get_tree()->xform_change_list.remove(&xform_change);
|
||||
if (data.C)
|
||||
data.parent->data.children.erase(data.C);
|
||||
data.parent=NULL;
|
||||
data.C=NULL;
|
||||
data.toplevel_active=false;
|
||||
data.parent = NULL;
|
||||
data.C = NULL;
|
||||
data.toplevel_active = false;
|
||||
} break;
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
data.inside_world=true;
|
||||
data.viewport=NULL;
|
||||
data.inside_world = true;
|
||||
data.viewport = NULL;
|
||||
Node *parent = get_parent();
|
||||
while(parent && !data.viewport) {
|
||||
data.viewport=parent->cast_to<Viewport>();
|
||||
parent=parent->get_parent();
|
||||
while (parent && !data.viewport) {
|
||||
data.viewport = parent->cast_to<Viewport>();
|
||||
parent = parent->get_parent();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!data.viewport);
|
||||
|
||||
|
||||
if (get_script_instance()) {
|
||||
|
||||
Variant::CallError err;
|
||||
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world,NULL,0);
|
||||
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, NULL, 0);
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (get_tree()->is_editor_hint()) {
|
||||
|
||||
// get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
|
||||
get_tree()->call_group(0,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
|
||||
// get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
|
||||
get_tree()->call_group(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
|
||||
if (!data.gizmo_disabled) {
|
||||
|
||||
if (data.gizmo.is_valid())
|
||||
|
|
@ -201,15 +193,14 @@ void Spatial::_notification(int p_what) {
|
|||
if (get_script_instance()) {
|
||||
|
||||
Variant::CallError err;
|
||||
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world,NULL,0);
|
||||
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, NULL, 0);
|
||||
}
|
||||
|
||||
data.viewport=NULL;
|
||||
data.inside_world=false;
|
||||
data.viewport = NULL;
|
||||
data.inside_world = false;
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
|
@ -223,10 +214,10 @@ void Spatial::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
void Spatial::set_transform(const Transform& p_transform) {
|
||||
void Spatial::set_transform(const Transform &p_transform) {
|
||||
|
||||
data.local_transform=p_transform;
|
||||
data.dirty|=DIRTY_VECTORS;
|
||||
data.local_transform = p_transform;
|
||||
data.dirty |= DIRTY_VECTORS;
|
||||
_change_notify("transform/translation");
|
||||
_change_notify("transform/rotation");
|
||||
_change_notify("transform/scale");
|
||||
|
|
@ -234,23 +225,18 @@ void Spatial::set_transform(const Transform& p_transform) {
|
|||
if (data.notify_local_transform) {
|
||||
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_global_transform(const Transform& p_transform) {
|
||||
void Spatial::set_global_transform(const Transform &p_transform) {
|
||||
|
||||
Transform xform =
|
||||
(data.parent && !data.toplevel_active) ?
|
||||
data.parent->get_global_transform().affine_inverse() * p_transform :
|
||||
p_transform;
|
||||
data.parent->get_global_transform().affine_inverse() * p_transform :
|
||||
p_transform;
|
||||
|
||||
set_transform(xform);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Transform Spatial::get_transform() const {
|
||||
|
||||
if (data.dirty & DIRTY_LOCAL) {
|
||||
|
|
@ -273,13 +259,13 @@ Transform Spatial::get_global_transform() const {
|
|||
|
||||
if (data.parent && !data.toplevel_active) {
|
||||
|
||||
data.global_transform=data.parent->get_global_transform() * data.local_transform;
|
||||
data.global_transform = data.parent->get_global_transform() * data.local_transform;
|
||||
} else {
|
||||
|
||||
data.global_transform=data.local_transform;
|
||||
data.global_transform = data.local_transform;
|
||||
}
|
||||
|
||||
data.dirty&=~DIRTY_GLOBAL;
|
||||
data.dirty &= ~DIRTY_GLOBAL;
|
||||
}
|
||||
|
||||
return data.global_transform;
|
||||
|
|
@ -319,87 +305,82 @@ void Spatial::remove_child_notify(Node *p_child) {
|
|||
Spatial *Spatial::get_parent_spatial() const {
|
||||
|
||||
return data.parent;
|
||||
|
||||
}
|
||||
|
||||
Transform Spatial::get_relative_transform(const Node *p_parent) const {
|
||||
|
||||
if (p_parent==this)
|
||||
if (p_parent == this)
|
||||
return Transform();
|
||||
|
||||
ERR_FAIL_COND_V(!data.parent,Transform());
|
||||
ERR_FAIL_COND_V(!data.parent, Transform());
|
||||
|
||||
if (p_parent==data.parent)
|
||||
if (p_parent == data.parent)
|
||||
return get_transform();
|
||||
else
|
||||
return data.parent->get_relative_transform(p_parent) * get_transform();
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_translation(const Vector3& p_translation) {
|
||||
void Spatial::set_translation(const Vector3 &p_translation) {
|
||||
|
||||
data.local_transform.origin=p_translation;
|
||||
data.local_transform.origin = p_translation;
|
||||
_propagate_transform_changed(this);
|
||||
if (data.notify_local_transform) {
|
||||
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_rotation(const Vector3& p_euler_rad){
|
||||
void Spatial::set_rotation(const Vector3 &p_euler_rad) {
|
||||
|
||||
if (data.dirty&DIRTY_VECTORS) {
|
||||
data.scale=data.local_transform.basis.get_scale();
|
||||
data.dirty&=~DIRTY_VECTORS;
|
||||
if (data.dirty & DIRTY_VECTORS) {
|
||||
data.scale = data.local_transform.basis.get_scale();
|
||||
data.dirty &= ~DIRTY_VECTORS;
|
||||
}
|
||||
|
||||
data.rotation=p_euler_rad;
|
||||
data.dirty|=DIRTY_LOCAL;
|
||||
data.rotation = p_euler_rad;
|
||||
data.dirty |= DIRTY_LOCAL;
|
||||
_propagate_transform_changed(this);
|
||||
if (data.notify_local_transform) {
|
||||
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_rotation_deg(const Vector3& p_euler_deg) {
|
||||
void Spatial::set_rotation_deg(const Vector3 &p_euler_deg) {
|
||||
|
||||
set_rotation(p_euler_deg * Math_PI / 180.0);
|
||||
}
|
||||
|
||||
void Spatial::_set_rotation_deg(const Vector3& p_euler_deg) {
|
||||
void Spatial::_set_rotation_deg(const Vector3 &p_euler_deg) {
|
||||
|
||||
WARN_PRINT("Deprecated method Spatial._set_rotation_deg(): This method was renamed to set_rotation_deg. Please adapt your code accordingly, as the old method will be obsoleted.");
|
||||
set_rotation_deg(p_euler_deg);
|
||||
}
|
||||
|
||||
void Spatial::set_scale(const Vector3& p_scale){
|
||||
void Spatial::set_scale(const Vector3 &p_scale) {
|
||||
|
||||
if (data.dirty&DIRTY_VECTORS) {
|
||||
data.rotation=data.local_transform.basis.get_euler();
|
||||
data.dirty&=~DIRTY_VECTORS;
|
||||
if (data.dirty & DIRTY_VECTORS) {
|
||||
data.rotation = data.local_transform.basis.get_euler();
|
||||
data.dirty &= ~DIRTY_VECTORS;
|
||||
}
|
||||
|
||||
data.scale=p_scale;
|
||||
data.dirty|=DIRTY_LOCAL;
|
||||
data.scale = p_scale;
|
||||
data.dirty |= DIRTY_LOCAL;
|
||||
_propagate_transform_changed(this);
|
||||
if (data.notify_local_transform) {
|
||||
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vector3 Spatial::get_translation() const{
|
||||
Vector3 Spatial::get_translation() const {
|
||||
|
||||
return data.local_transform.origin;
|
||||
}
|
||||
|
||||
Vector3 Spatial::get_rotation() const{
|
||||
Vector3 Spatial::get_rotation() const {
|
||||
|
||||
if (data.dirty&DIRTY_VECTORS) {
|
||||
data.scale=data.local_transform.basis.get_scale();
|
||||
data.rotation=data.local_transform.basis.get_euler();
|
||||
data.dirty&=~DIRTY_VECTORS;
|
||||
if (data.dirty & DIRTY_VECTORS) {
|
||||
data.scale = data.local_transform.basis.get_scale();
|
||||
data.rotation = data.local_transform.basis.get_euler();
|
||||
data.dirty &= ~DIRTY_VECTORS;
|
||||
}
|
||||
|
||||
return data.rotation;
|
||||
|
|
@ -418,18 +399,17 @@ Vector3 Spatial::_get_rotation_deg() const {
|
|||
return get_rotation_deg();
|
||||
}
|
||||
|
||||
Vector3 Spatial::get_scale() const{
|
||||
Vector3 Spatial::get_scale() const {
|
||||
|
||||
if (data.dirty&DIRTY_VECTORS) {
|
||||
data.scale=data.local_transform.basis.get_scale();
|
||||
data.rotation=data.local_transform.basis.get_euler();
|
||||
data.dirty&=~DIRTY_VECTORS;
|
||||
if (data.dirty & DIRTY_VECTORS) {
|
||||
data.scale = data.local_transform.basis.get_scale();
|
||||
data.rotation = data.local_transform.basis.get_euler();
|
||||
data.dirty &= ~DIRTY_VECTORS;
|
||||
}
|
||||
|
||||
return data.scale;
|
||||
}
|
||||
|
||||
|
||||
void Spatial::update_gizmo() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
|
@ -439,12 +419,12 @@ void Spatial::update_gizmo() {
|
|||
return;
|
||||
if (data.gizmo_dirty)
|
||||
return;
|
||||
data.gizmo_dirty=true;
|
||||
MessageQueue::get_singleton()->push_call(this,"_update_gizmo");
|
||||
data.gizmo_dirty = true;
|
||||
MessageQueue::get_singleton()->push_call(this, "_update_gizmo");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Spatial::set_gizmo(const Ref<SpatialGizmo>& p_gizmo) {
|
||||
void Spatial::set_gizmo(const Ref<SpatialGizmo> &p_gizmo) {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
|
|
@ -452,7 +432,7 @@ void Spatial::set_gizmo(const Ref<SpatialGizmo>& p_gizmo) {
|
|||
return;
|
||||
if (data.gizmo.is_valid() && is_inside_world())
|
||||
data.gizmo->free();
|
||||
data.gizmo=p_gizmo;
|
||||
data.gizmo = p_gizmo;
|
||||
if (data.gizmo.is_valid() && is_inside_world()) {
|
||||
|
||||
data.gizmo->create();
|
||||
|
|
@ -478,7 +458,7 @@ Ref<SpatialGizmo> Spatial::get_gizmo() const {
|
|||
|
||||
void Spatial::_update_gizmo() {
|
||||
|
||||
data.gizmo_dirty=false;
|
||||
data.gizmo_dirty = false;
|
||||
if (data.gizmo.is_valid()) {
|
||||
if (is_visible())
|
||||
data.gizmo->redraw();
|
||||
|
|
@ -487,19 +467,18 @@ void Spatial::_update_gizmo() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Spatial::set_disable_gizmo(bool p_enabled) {
|
||||
|
||||
data.gizmo_disabled=p_enabled;
|
||||
data.gizmo_disabled = p_enabled;
|
||||
if (!p_enabled && data.gizmo.is_valid())
|
||||
data.gizmo=Ref<SpatialGizmo>();
|
||||
data.gizmo = Ref<SpatialGizmo>();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Spatial::set_as_toplevel(bool p_enabled) {
|
||||
|
||||
if (data.toplevel==p_enabled)
|
||||
if (data.toplevel == p_enabled)
|
||||
return;
|
||||
if (is_inside_tree() && !get_tree()->is_editor_hint()) {
|
||||
|
||||
|
|
@ -508,30 +487,28 @@ void Spatial::set_as_toplevel(bool p_enabled) {
|
|||
else if (data.parent)
|
||||
set_transform(data.parent->get_global_transform().affine_inverse() * get_global_transform());
|
||||
|
||||
data.toplevel=p_enabled;
|
||||
data.toplevel_active=p_enabled;
|
||||
data.toplevel = p_enabled;
|
||||
data.toplevel_active = p_enabled;
|
||||
|
||||
} else {
|
||||
data.toplevel=p_enabled;
|
||||
data.toplevel = p_enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Spatial::is_set_as_toplevel() const{
|
||||
bool Spatial::is_set_as_toplevel() const {
|
||||
|
||||
return data.toplevel;
|
||||
}
|
||||
|
||||
Ref<World> Spatial::get_world() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_world(),Ref<World>());
|
||||
ERR_FAIL_COND_V(!is_inside_world(), Ref<World>());
|
||||
return data.viewport->find_world();
|
||||
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void Spatial::set_import_transform(const Transform& p_transform) {
|
||||
data.import_transform=p_transform;
|
||||
void Spatial::set_import_transform(const Transform &p_transform) {
|
||||
data.import_transform = p_transform;
|
||||
}
|
||||
|
||||
Transform Spatial::get_import_transform() const {
|
||||
|
|
@ -540,7 +517,6 @@ Transform Spatial::get_import_transform() const {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Spatial::_propagate_visibility_changed() {
|
||||
|
||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||
|
|
@ -551,22 +527,21 @@ void Spatial::_propagate_visibility_changed() {
|
|||
_update_gizmo();
|
||||
#endif
|
||||
|
||||
for (List<Spatial*>::Element*E=data.children.front();E;E=E->next()) {
|
||||
for (List<Spatial *>::Element *E = data.children.front(); E; E = E->next()) {
|
||||
|
||||
Spatial *c=E->get();
|
||||
Spatial *c = E->get();
|
||||
if (!c || !c->data.visible)
|
||||
continue;
|
||||
c->_propagate_visibility_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Spatial::show() {
|
||||
|
||||
if (data.visible)
|
||||
return;
|
||||
|
||||
data.visible=true;
|
||||
data.visible = true;
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
|
@ -577,36 +552,34 @@ void Spatial::show() {
|
|||
}
|
||||
}
|
||||
|
||||
void Spatial::hide(){
|
||||
void Spatial::hide() {
|
||||
|
||||
if (!data.visible)
|
||||
return;
|
||||
|
||||
bool was_visible = is_visible();
|
||||
data.visible=false;
|
||||
data.visible = false;
|
||||
|
||||
if (!data.parent || was_visible) {
|
||||
|
||||
_propagate_visibility_changed();
|
||||
}
|
||||
|
||||
}
|
||||
bool Spatial::is_visible() const{
|
||||
bool Spatial::is_visible() const {
|
||||
|
||||
const Spatial *s=this;
|
||||
const Spatial *s = this;
|
||||
|
||||
while(s) {
|
||||
while (s) {
|
||||
if (!s->data.visible) {
|
||||
return false;
|
||||
}
|
||||
s=s->data.parent;
|
||||
s = s->data.parent;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Spatial::is_hidden() const{
|
||||
bool Spatial::is_hidden() const {
|
||||
|
||||
return !data.visible;
|
||||
}
|
||||
|
|
@ -633,64 +606,57 @@ bool Spatial::_is_visible_() const {
|
|||
return !is_hidden();
|
||||
}
|
||||
|
||||
void Spatial::rotate(const Vector3& p_normal,float p_radians) {
|
||||
void Spatial::rotate(const Vector3 &p_normal, float p_radians) {
|
||||
|
||||
Transform t =get_transform();
|
||||
t.basis.rotate(p_normal,p_radians);
|
||||
Transform t = get_transform();
|
||||
t.basis.rotate(p_normal, p_radians);
|
||||
set_transform(t);
|
||||
}
|
||||
|
||||
void Spatial::rotate_x(float p_radians) {
|
||||
|
||||
Transform t =get_transform();
|
||||
t.basis.rotate(Vector3(1,0,0),p_radians);
|
||||
Transform t = get_transform();
|
||||
t.basis.rotate(Vector3(1, 0, 0), p_radians);
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::rotate_y(float p_radians){
|
||||
void Spatial::rotate_y(float p_radians) {
|
||||
|
||||
Transform t =get_transform();
|
||||
t.basis.rotate(Vector3(0,1,0),p_radians);
|
||||
Transform t = get_transform();
|
||||
t.basis.rotate(Vector3(0, 1, 0), p_radians);
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
void Spatial::rotate_z(float p_radians){
|
||||
void Spatial::rotate_z(float p_radians) {
|
||||
|
||||
Transform t =get_transform();
|
||||
t.basis.rotate(Vector3(0,0,1),p_radians);
|
||||
Transform t = get_transform();
|
||||
t.basis.rotate(Vector3(0, 0, 1), p_radians);
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::translate(const Vector3& p_offset){
|
||||
void Spatial::translate(const Vector3 &p_offset) {
|
||||
|
||||
Transform t =get_transform();
|
||||
Transform t = get_transform();
|
||||
t.translate(p_offset);
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::scale(const Vector3& p_ratio){
|
||||
void Spatial::scale(const Vector3 &p_ratio) {
|
||||
|
||||
Transform t =get_transform();
|
||||
Transform t = get_transform();
|
||||
t.basis.scale(p_ratio);
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
void Spatial::global_rotate(const Vector3& p_normal,float p_radians){
|
||||
void Spatial::global_rotate(const Vector3 &p_normal, float p_radians) {
|
||||
|
||||
Matrix3 rotation(p_normal,p_radians);
|
||||
Matrix3 rotation(p_normal, p_radians);
|
||||
Transform t = get_global_transform();
|
||||
t.basis= rotation * t.basis;
|
||||
t.basis = rotation * t.basis;
|
||||
set_global_transform(t);
|
||||
|
||||
}
|
||||
void Spatial::global_translate(const Vector3& p_offset){
|
||||
void Spatial::global_translate(const Vector3 &p_offset) {
|
||||
Transform t = get_global_transform();
|
||||
t.origin+=p_offset;
|
||||
t.origin += p_offset;
|
||||
set_global_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::orthonormalize() {
|
||||
|
|
@ -698,44 +664,40 @@ void Spatial::orthonormalize() {
|
|||
Transform t = get_transform();
|
||||
t.orthonormalize();
|
||||
set_transform(t);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_identity() {
|
||||
|
||||
set_transform(Transform());
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Spatial::look_at(const Vector3& p_target, const Vector3& p_up_normal) {
|
||||
void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up_normal) {
|
||||
|
||||
Transform lookat;
|
||||
lookat.origin=get_global_transform().origin;
|
||||
if (lookat.origin==p_target) {
|
||||
lookat.origin = get_global_transform().origin;
|
||||
if (lookat.origin == p_target) {
|
||||
ERR_EXPLAIN("Node origin and target are in the same position, look_at() failed");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
if (p_up_normal.cross(p_target-lookat.origin)==Vector3()) {
|
||||
if (p_up_normal.cross(p_target - lookat.origin) == Vector3()) {
|
||||
ERR_EXPLAIN("Up vector and direction between node origin and target are aligned, look_at() failed");
|
||||
ERR_FAIL();
|
||||
}
|
||||
lookat=lookat.looking_at(p_target,p_up_normal);
|
||||
lookat = lookat.looking_at(p_target, p_up_normal);
|
||||
set_global_transform(lookat);
|
||||
}
|
||||
|
||||
void Spatial::look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal) {
|
||||
void Spatial::look_at_from_pos(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up_normal) {
|
||||
|
||||
Transform lookat;
|
||||
lookat.origin=p_pos;
|
||||
lookat=lookat.looking_at(p_target,p_up_normal);
|
||||
lookat.origin = p_pos;
|
||||
lookat = lookat.looking_at(p_target, p_up_normal);
|
||||
set_global_transform(lookat);
|
||||
|
||||
}
|
||||
|
||||
void Spatial::set_notify_local_transform(bool p_enable) {
|
||||
data.notify_local_transform=p_enable;
|
||||
data.notify_local_transform = p_enable;
|
||||
}
|
||||
|
||||
bool Spatial::is_local_transform_notification_enabled() const {
|
||||
|
|
@ -744,118 +706,111 @@ bool Spatial::is_local_transform_notification_enabled() const {
|
|||
|
||||
void Spatial::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_transform","local"), &Spatial::set_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_transform", "local"), &Spatial::set_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_transform"), &Spatial::get_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_translation","translation"), &Spatial::set_translation);
|
||||
ObjectTypeDB::bind_method(_MD("set_translation", "translation"), &Spatial::set_translation);
|
||||
ObjectTypeDB::bind_method(_MD("get_translation"), &Spatial::get_translation);
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation","rotation_rad"), &Spatial::set_rotation);
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation", "rotation_rad"), &Spatial::set_rotation);
|
||||
ObjectTypeDB::bind_method(_MD("get_rotation"), &Spatial::get_rotation);
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation_deg","rotation_deg"), &Spatial::set_rotation_deg);
|
||||
ObjectTypeDB::bind_method(_MD("set_rotation_deg", "rotation_deg"), &Spatial::set_rotation_deg);
|
||||
ObjectTypeDB::bind_method(_MD("get_rotation_deg"), &Spatial::get_rotation_deg);
|
||||
ObjectTypeDB::bind_method(_MD("set_scale","scale"), &Spatial::set_scale);
|
||||
ObjectTypeDB::bind_method(_MD("set_scale", "scale"), &Spatial::set_scale);
|
||||
ObjectTypeDB::bind_method(_MD("get_scale"), &Spatial::get_scale);
|
||||
ObjectTypeDB::bind_method(_MD("set_global_transform","global"), &Spatial::set_global_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_global_transform", "global"), &Spatial::set_global_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_global_transform"), &Spatial::get_global_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_parent_spatial"), &Spatial::get_parent_spatial);
|
||||
ObjectTypeDB::bind_method(_MD("set_ignore_transform_notification","enabled"), &Spatial::set_ignore_transform_notification);
|
||||
ObjectTypeDB::bind_method(_MD("set_as_toplevel","enable"), &Spatial::set_as_toplevel);
|
||||
ObjectTypeDB::bind_method(_MD("set_ignore_transform_notification", "enabled"), &Spatial::set_ignore_transform_notification);
|
||||
ObjectTypeDB::bind_method(_MD("set_as_toplevel", "enable"), &Spatial::set_as_toplevel);
|
||||
ObjectTypeDB::bind_method(_MD("is_set_as_toplevel"), &Spatial::is_set_as_toplevel);
|
||||
ObjectTypeDB::bind_method(_MD("get_world:World"), &Spatial::get_world);
|
||||
|
||||
// TODO: Obsolete those two methods (old name) properly (GH-4397)
|
||||
ObjectTypeDB::bind_method(_MD("_set_rotation_deg","rotation_deg"), &Spatial::_set_rotation_deg);
|
||||
ObjectTypeDB::bind_method(_MD("_set_rotation_deg", "rotation_deg"), &Spatial::_set_rotation_deg);
|
||||
ObjectTypeDB::bind_method(_MD("_get_rotation_deg"), &Spatial::_get_rotation_deg);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
ObjectTypeDB::bind_method(_MD("_update_gizmo"), &Spatial::_update_gizmo);
|
||||
ObjectTypeDB::bind_method(_MD("_set_import_transform"), &Spatial::set_import_transform);
|
||||
ObjectTypeDB::bind_method(_MD("_get_import_transform"), &Spatial::get_import_transform);
|
||||
ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"_import_transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_import_transform"),_SCS("_get_import_transform"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "_import_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), _SCS("_set_import_transform"), _SCS("_get_import_transform"));
|
||||
#endif
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("update_gizmo"), &Spatial::update_gizmo);
|
||||
ObjectTypeDB::bind_method(_MD("set_gizmo","gizmo:SpatialGizmo"), &Spatial::set_gizmo);
|
||||
ObjectTypeDB::bind_method(_MD("set_gizmo", "gizmo:SpatialGizmo"), &Spatial::set_gizmo);
|
||||
ObjectTypeDB::bind_method(_MD("get_gizmo:SpatialGizmo"), &Spatial::get_gizmo);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("show"), &Spatial::show);
|
||||
ObjectTypeDB::bind_method(_MD("hide"), &Spatial::hide);
|
||||
ObjectTypeDB::bind_method(_MD("is_visible"), &Spatial::is_visible);
|
||||
ObjectTypeDB::bind_method(_MD("is_hidden"), &Spatial::is_hidden);
|
||||
ObjectTypeDB::bind_method(_MD("set_hidden","hidden"), &Spatial::set_hidden);
|
||||
ObjectTypeDB::bind_method(_MD("set_hidden", "hidden"), &Spatial::set_hidden);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_visible_"), &Spatial::_set_visible_);
|
||||
ObjectTypeDB::bind_method(_MD("_is_visible_"), &Spatial::_is_visible_);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_notify_local_transform","enable"), &Spatial::set_notify_local_transform);
|
||||
ObjectTypeDB::bind_method(_MD("set_notify_local_transform", "enable"), &Spatial::set_notify_local_transform);
|
||||
ObjectTypeDB::bind_method(_MD("is_local_transform_notification_enabled"), &Spatial::is_local_transform_notification_enabled);
|
||||
|
||||
void rotate(const Vector3& p_normal,float p_radians);
|
||||
void rotate(const Vector3 &p_normal, float p_radians);
|
||||
void rotate_x(float p_radians);
|
||||
void rotate_y(float p_radians);
|
||||
void rotate_z(float p_radians);
|
||||
void translate(const Vector3& p_offset);
|
||||
void scale(const Vector3& p_ratio);
|
||||
void global_rotate(const Vector3& p_normal,float p_radians);
|
||||
void global_translate(const Vector3& p_offset);
|
||||
void translate(const Vector3 &p_offset);
|
||||
void scale(const Vector3 &p_ratio);
|
||||
void global_rotate(const Vector3 &p_normal, float p_radians);
|
||||
void global_translate(const Vector3 &p_offset);
|
||||
|
||||
ObjectTypeDB::bind_method( _MD("rotate","normal","radians"),&Spatial::rotate );
|
||||
ObjectTypeDB::bind_method( _MD("global_rotate","normal","radians"),&Spatial::global_rotate );
|
||||
ObjectTypeDB::bind_method( _MD("rotate_x","radians"),&Spatial::rotate_x );
|
||||
ObjectTypeDB::bind_method( _MD("rotate_y","radians"),&Spatial::rotate_y );
|
||||
ObjectTypeDB::bind_method( _MD("rotate_z","radians"),&Spatial::rotate_z );
|
||||
ObjectTypeDB::bind_method( _MD("translate","offset"),&Spatial::translate );
|
||||
ObjectTypeDB::bind_method( _MD("global_translate","offset"),&Spatial::global_translate );
|
||||
ObjectTypeDB::bind_method( _MD("orthonormalize"),&Spatial::orthonormalize );
|
||||
ObjectTypeDB::bind_method( _MD("set_identity"),&Spatial::set_identity );
|
||||
ObjectTypeDB::bind_method(_MD("rotate", "normal", "radians"), &Spatial::rotate);
|
||||
ObjectTypeDB::bind_method(_MD("global_rotate", "normal", "radians"), &Spatial::global_rotate);
|
||||
ObjectTypeDB::bind_method(_MD("rotate_x", "radians"), &Spatial::rotate_x);
|
||||
ObjectTypeDB::bind_method(_MD("rotate_y", "radians"), &Spatial::rotate_y);
|
||||
ObjectTypeDB::bind_method(_MD("rotate_z", "radians"), &Spatial::rotate_z);
|
||||
ObjectTypeDB::bind_method(_MD("translate", "offset"), &Spatial::translate);
|
||||
ObjectTypeDB::bind_method(_MD("global_translate", "offset"), &Spatial::global_translate);
|
||||
ObjectTypeDB::bind_method(_MD("orthonormalize"), &Spatial::orthonormalize);
|
||||
ObjectTypeDB::bind_method(_MD("set_identity"), &Spatial::set_identity);
|
||||
|
||||
ObjectTypeDB::bind_method( _MD("look_at","target","up"),&Spatial::look_at );
|
||||
ObjectTypeDB::bind_method( _MD("look_at_from_pos","pos","target","up"),&Spatial::look_at_from_pos );
|
||||
ObjectTypeDB::bind_method(_MD("look_at", "target", "up"), &Spatial::look_at);
|
||||
ObjectTypeDB::bind_method(_MD("look_at_from_pos", "pos", "target", "up"), &Spatial::look_at_from_pos);
|
||||
|
||||
BIND_CONSTANT( NOTIFICATION_TRANSFORM_CHANGED );
|
||||
BIND_CONSTANT( NOTIFICATION_ENTER_WORLD );
|
||||
BIND_CONSTANT( NOTIFICATION_EXIT_WORLD );
|
||||
BIND_CONSTANT( NOTIFICATION_VISIBILITY_CHANGED );
|
||||
BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED);
|
||||
BIND_CONSTANT(NOTIFICATION_ENTER_WORLD);
|
||||
BIND_CONSTANT(NOTIFICATION_EXIT_WORLD);
|
||||
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
|
||||
|
||||
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), _SCS("set_global_transform"), _SCS("get_global_transform") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::TRANSFORM,"transform/local",PROPERTY_HINT_NONE,""), _SCS("set_transform"), _SCS("get_transform") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/translation",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR), _SCS("set_translation"), _SCS("get_translation") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/rotation",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR), _SCS("set_rotation_deg"), _SCS("get_rotation_deg") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/rotation_rad",PROPERTY_HINT_NONE,"",0), _SCS("set_rotation"), _SCS("get_rotation") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/scale",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR), _SCS("set_scale"), _SCS("get_scale") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"), _SCS("_is_visible_") );
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::TRANSFORM, "transform/local", PROPERTY_HINT_NONE, ""), _SCS("set_transform"), _SCS("get_transform"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "transform/translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), _SCS("set_translation"), _SCS("get_translation"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "transform/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), _SCS("set_rotation_deg"), _SCS("get_rotation_deg"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "transform/rotation_rad", PROPERTY_HINT_NONE, "", 0), _SCS("set_rotation"), _SCS("get_rotation"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "transform/scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), _SCS("set_scale"), _SCS("get_scale"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "visibility/visible"), _SCS("_set_visible_"), _SCS("_is_visible_"));
|
||||
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/local"), _SCS("set_transform"), _SCS("get_transform") );
|
||||
|
||||
ADD_SIGNAL( MethodInfo("visibility_changed" ) );
|
||||
|
||||
ADD_SIGNAL(MethodInfo("visibility_changed"));
|
||||
}
|
||||
|
||||
Spatial::Spatial()
|
||||
: xform_change(this) {
|
||||
|
||||
Spatial::Spatial() : xform_change(this)
|
||||
{
|
||||
data.dirty = DIRTY_NONE;
|
||||
data.children_lock = 0;
|
||||
|
||||
data.dirty=DIRTY_NONE;
|
||||
data.children_lock=0;
|
||||
|
||||
data.ignore_notification=false;
|
||||
data.toplevel=false;
|
||||
data.toplevel_active=false;
|
||||
data.scale=Vector3(1,1,1);
|
||||
data.viewport=NULL;
|
||||
data.inside_world=false;
|
||||
data.visible=true;
|
||||
data.ignore_notification = false;
|
||||
data.toplevel = false;
|
||||
data.toplevel_active = false;
|
||||
data.scale = Vector3(1, 1, 1);
|
||||
data.viewport = NULL;
|
||||
data.inside_world = false;
|
||||
data.visible = true;
|
||||
#ifdef TOOLS_ENABLED
|
||||
data.gizmo_disabled=false;
|
||||
data.gizmo_dirty=false;
|
||||
data.gizmo_disabled = false;
|
||||
data.gizmo_dirty = false;
|
||||
#endif
|
||||
data.notify_local_transform=false;
|
||||
data.parent=NULL;
|
||||
data.C=NULL;
|
||||
|
||||
data.notify_local_transform = false;
|
||||
data.parent = NULL;
|
||||
data.C = NULL;
|
||||
}
|
||||
|
||||
|
||||
Spatial::~Spatial() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,39 +38,34 @@
|
|||
|
||||
class SpatialGizmo : public Reference {
|
||||
|
||||
OBJ_TYPE(SpatialGizmo,Reference);
|
||||
|
||||
OBJ_TYPE(SpatialGizmo, Reference);
|
||||
|
||||
public:
|
||||
|
||||
virtual void create()=0;
|
||||
virtual void transform()=0;
|
||||
virtual void clear()=0;
|
||||
virtual void redraw()=0;
|
||||
virtual void free()=0;
|
||||
virtual void create() = 0;
|
||||
virtual void transform() = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual void redraw() = 0;
|
||||
virtual void free() = 0;
|
||||
|
||||
SpatialGizmo();
|
||||
};
|
||||
|
||||
|
||||
class Spatial : public Node {
|
||||
|
||||
OBJ_TYPE( Spatial, Node );
|
||||
OBJ_TYPE(Spatial, Node);
|
||||
OBJ_CATEGORY("3D");
|
||||
|
||||
enum TransformDirty {
|
||||
DIRTY_NONE=0,
|
||||
DIRTY_VECTORS=1,
|
||||
DIRTY_LOCAL=2,
|
||||
DIRTY_GLOBAL=4
|
||||
DIRTY_NONE = 0,
|
||||
DIRTY_VECTORS = 1,
|
||||
DIRTY_LOCAL = 2,
|
||||
DIRTY_GLOBAL = 4
|
||||
};
|
||||
|
||||
mutable SelfList<Node> xform_change;
|
||||
|
||||
struct Data {
|
||||
|
||||
|
||||
|
||||
mutable Transform global_transform;
|
||||
mutable Transform local_transform;
|
||||
mutable Vector3 rotation;
|
||||
|
|
@ -80,15 +75,14 @@ class Spatial : public Node {
|
|||
|
||||
Viewport *viewport;
|
||||
|
||||
|
||||
bool toplevel_active;
|
||||
bool toplevel;
|
||||
bool inside_world;
|
||||
|
||||
int children_lock;
|
||||
Spatial *parent;
|
||||
List<Spatial*> children;
|
||||
List<Spatial*>::Element *C;
|
||||
List<Spatial *> children;
|
||||
List<Spatial *>::Element *C;
|
||||
|
||||
bool ignore_notification;
|
||||
bool notify_local_transform;
|
||||
|
|
@ -111,15 +105,13 @@ class Spatial : public Node {
|
|||
void _propagate_transform_changed(Spatial *p_origin);
|
||||
|
||||
// Deprecated, should be removed in a future version.
|
||||
void _set_rotation_deg(const Vector3& p_euler_deg);
|
||||
void _set_rotation_deg(const Vector3 &p_euler_deg);
|
||||
Vector3 _get_rotation_deg() const;
|
||||
|
||||
void _propagate_visibility_changed();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
_FORCE_INLINE_ void set_ignore_transform_notification(bool p_ignore) { data.ignore_notification=p_ignore; }
|
||||
_FORCE_INLINE_ void set_ignore_transform_notification(bool p_ignore) { data.ignore_notification = p_ignore; }
|
||||
|
||||
_FORCE_INLINE_ void _update_local_transform() const;
|
||||
|
||||
|
|
@ -128,34 +120,33 @@ protected:
|
|||
|
||||
void _set_visible_(bool p_visible);
|
||||
bool _is_visible_() const;
|
||||
public:
|
||||
|
||||
public:
|
||||
enum {
|
||||
|
||||
NOTIFICATION_TRANSFORM_CHANGED=SceneTree::NOTIFICATION_TRANSFORM_CHANGED,
|
||||
NOTIFICATION_ENTER_WORLD=41,
|
||||
NOTIFICATION_EXIT_WORLD=42,
|
||||
NOTIFICATION_VISIBILITY_CHANGED=43,
|
||||
NOTIFICATION_LOCAL_TRANSFORM_CHANGED=44,
|
||||
NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED,
|
||||
NOTIFICATION_ENTER_WORLD = 41,
|
||||
NOTIFICATION_EXIT_WORLD = 42,
|
||||
NOTIFICATION_VISIBILITY_CHANGED = 43,
|
||||
NOTIFICATION_LOCAL_TRANSFORM_CHANGED = 44,
|
||||
};
|
||||
|
||||
Spatial *get_parent_spatial() const;
|
||||
|
||||
|
||||
Ref<World> get_world() const;
|
||||
|
||||
void set_translation(const Vector3& p_translation);
|
||||
void set_rotation(const Vector3& p_euler_rad);
|
||||
void set_rotation_deg(const Vector3& p_euler_deg);
|
||||
void set_scale(const Vector3& p_scale);
|
||||
void set_translation(const Vector3 &p_translation);
|
||||
void set_rotation(const Vector3 &p_euler_rad);
|
||||
void set_rotation_deg(const Vector3 &p_euler_deg);
|
||||
void set_scale(const Vector3 &p_scale);
|
||||
|
||||
Vector3 get_translation() const;
|
||||
Vector3 get_rotation() const;
|
||||
Vector3 get_rotation_deg() const;
|
||||
Vector3 get_scale() const;
|
||||
|
||||
void set_transform(const Transform& p_transform);
|
||||
void set_global_transform(const Transform& p_transform);
|
||||
void set_transform(const Transform &p_transform);
|
||||
void set_global_transform(const Transform &p_transform);
|
||||
|
||||
Transform get_transform() const;
|
||||
Transform get_global_transform() const;
|
||||
|
|
@ -165,24 +156,24 @@ public:
|
|||
|
||||
void set_disable_gizmo(bool p_enabled);
|
||||
void update_gizmo();
|
||||
void set_gizmo(const Ref<SpatialGizmo>& p_gizmo);
|
||||
void set_gizmo(const Ref<SpatialGizmo> &p_gizmo);
|
||||
Ref<SpatialGizmo> get_gizmo() const;
|
||||
|
||||
_FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; }
|
||||
|
||||
Transform get_relative_transform(const Node *p_parent) const;
|
||||
|
||||
void rotate(const Vector3& p_normal,float p_radians);
|
||||
void rotate(const Vector3 &p_normal, float p_radians);
|
||||
void rotate_x(float p_radians);
|
||||
void rotate_y(float p_radians);
|
||||
void rotate_z(float p_radians);
|
||||
void translate(const Vector3& p_offset);
|
||||
void scale(const Vector3& p_ratio);
|
||||
void global_rotate(const Vector3& p_normal,float p_radians);
|
||||
void global_translate(const Vector3& p_offset);
|
||||
void translate(const Vector3 &p_offset);
|
||||
void scale(const Vector3 &p_ratio);
|
||||
void global_rotate(const Vector3 &p_normal, float p_radians);
|
||||
void global_translate(const Vector3 &p_offset);
|
||||
|
||||
void look_at(const Vector3& p_target, const Vector3& p_up_normal);
|
||||
void look_at_from_pos(const Vector3& p_pos,const Vector3& p_target, const Vector3& p_up_normal);
|
||||
void look_at(const Vector3 &p_target, const Vector3 &p_up_normal);
|
||||
void look_at_from_pos(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up_normal);
|
||||
|
||||
void set_notify_local_transform(bool p_enable);
|
||||
bool is_local_transform_notification_enabled() const;
|
||||
|
|
@ -197,13 +188,12 @@ public:
|
|||
void set_hidden(bool p_hidden);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void set_import_transform(const Transform& p_transform) ;
|
||||
void set_import_transform(const Transform &p_transform);
|
||||
Transform get_import_transform() const;
|
||||
#endif
|
||||
|
||||
Spatial();
|
||||
~Spatial();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#if 0
|
||||
|
||||
#include "proximity_area.h"
|
||||
#include "camera.h"
|
||||
#include "proximity_area.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
void SpatialIndexer::add_camera(Camera* p_camera) {
|
||||
|
|
|
|||
|
|
@ -28,29 +28,26 @@
|
|||
/*************************************************************************/
|
||||
#include "spatial_player.h"
|
||||
|
||||
#include "servers/audio_server.h"
|
||||
#include "camera.h"
|
||||
#include "servers/spatial_sound_server.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/spatial_sound_server.h"
|
||||
|
||||
void SpatialPlayer::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
//find the sound space
|
||||
|
||||
source_rid = SpatialSoundServer::get_singleton()->source_create(get_world()->get_sound_space());
|
||||
for(int i=0;i<PARAM_MAX;i++)
|
||||
set_param(Param(i),params[i]);
|
||||
|
||||
for (int i = 0; i < PARAM_MAX; i++)
|
||||
set_param(Param(i), params[i]);
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_transform(source_rid,get_global_transform());
|
||||
SpatialSoundServer::get_singleton()->source_set_transform(source_rid, get_global_transform());
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
|
@ -60,27 +57,23 @@ void SpatialPlayer::_notification(int p_what) {
|
|||
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SpatialPlayer::set_param(Param p_param, float p_value) {
|
||||
|
||||
void SpatialPlayer::set_param( Param p_param, float p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_param,PARAM_MAX);
|
||||
params[p_param]=p_value;
|
||||
if (p_param==PARAM_EMISSION_CONE_DEGREES) {
|
||||
ERR_FAIL_INDEX(p_param, PARAM_MAX);
|
||||
params[p_param] = p_value;
|
||||
if (p_param == PARAM_EMISSION_CONE_DEGREES) {
|
||||
update_gizmo();
|
||||
}
|
||||
if (source_rid.is_valid())
|
||||
SpatialSoundServer::get_singleton()->source_set_param(source_rid,(SpatialSoundServer::SourceParam)p_param,p_value);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_param(source_rid, (SpatialSoundServer::SourceParam)p_param, p_value);
|
||||
}
|
||||
|
||||
float SpatialPlayer::get_param( Param p_param) const {
|
||||
float SpatialPlayer::get_param(Param p_param) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
|
||||
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
|
||||
return params[p_param];
|
||||
|
||||
}
|
||||
|
||||
bool SpatialPlayer::_can_gizmo_scale() const {
|
||||
|
|
@ -90,41 +83,40 @@ bool SpatialPlayer::_can_gizmo_scale() const {
|
|||
|
||||
RES SpatialPlayer::_get_gizmo_geometry() const {
|
||||
|
||||
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
|
||||
Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
|
||||
|
||||
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
|
||||
|
||||
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.05) );
|
||||
mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
|
||||
mat->set_blend_mode( Material::BLEND_MODE_ADD );
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
Ref<FixedMaterial> mat(memnew(FixedMaterial));
|
||||
|
||||
mat->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.0, 0.6, 0.7, 0.05));
|
||||
mat->set_parameter(FixedMaterial::PARAM_EMISSION, Color(0.5, 0.7, 0.8));
|
||||
mat->set_blend_mode(Material::BLEND_MODE_ADD);
|
||||
mat->set_flag(Material::FLAG_DOUBLE_SIDED, true);
|
||||
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
|
||||
|
||||
surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
surface_tool->set_material(mat);
|
||||
|
||||
int sides=16;
|
||||
int sections=24;
|
||||
int sides = 16;
|
||||
int sections = 24;
|
||||
|
||||
// float len=1;
|
||||
float deg=Math::deg2rad(params[PARAM_EMISSION_CONE_DEGREES]);
|
||||
if (deg==180)
|
||||
deg=179.5;
|
||||
// float len=1;
|
||||
float deg = Math::deg2rad(params[PARAM_EMISSION_CONE_DEGREES]);
|
||||
if (deg == 180)
|
||||
deg = 179.5;
|
||||
|
||||
Vector3 to=Vector3(0,0,-1);
|
||||
Vector3 to = Vector3(0, 0, -1);
|
||||
|
||||
for(int j=0;j<sections;j++) {
|
||||
for (int j = 0; j < sections; j++) {
|
||||
|
||||
Vector3 p1=Matrix3(Vector3(1,0,0),deg*j/sections).xform(to);
|
||||
Vector3 p2=Matrix3(Vector3(1,0,0),deg*(j+1)/sections).xform(to);
|
||||
Vector3 p1 = Matrix3(Vector3(1, 0, 0), deg * j / sections).xform(to);
|
||||
Vector3 p2 = Matrix3(Vector3(1, 0, 0), deg * (j + 1) / sections).xform(to);
|
||||
|
||||
for(int i=0;i<sides;i++) {
|
||||
for (int i = 0; i < sides; i++) {
|
||||
|
||||
Vector3 p1r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p1);
|
||||
Vector3 p1s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p1);
|
||||
Vector3 p2s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p2);
|
||||
Vector3 p2r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p2);
|
||||
Vector3 p1r = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i) / sides).xform(p1);
|
||||
Vector3 p1s = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / sides).xform(p1);
|
||||
Vector3 p2s = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / sides).xform(p2);
|
||||
Vector3 p2r = Matrix3(Vector3(0, 0, 1), Math_PI * 2 * float(i) / sides).xform(p2);
|
||||
|
||||
surface_tool->add_normal(p1r.normalized());
|
||||
surface_tool->add_vertex(p1r);
|
||||
|
|
@ -140,25 +132,24 @@ RES SpatialPlayer::_get_gizmo_geometry() const {
|
|||
surface_tool->add_normal(p2r.normalized());
|
||||
surface_tool->add_vertex(p2r);
|
||||
|
||||
if (j==sections-1) {
|
||||
if (j == sections - 1) {
|
||||
|
||||
surface_tool->add_normal(p2r.normalized());
|
||||
surface_tool->add_vertex(p2r);
|
||||
surface_tool->add_normal(p2s.normalized());
|
||||
surface_tool->add_vertex(p2s);
|
||||
surface_tool->add_normal(Vector3(0,0,1));
|
||||
surface_tool->add_normal(Vector3(0, 0, 1));
|
||||
surface_tool->add_vertex(Vector3());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ref<Mesh> mesh = surface_tool->commit();
|
||||
|
||||
Ref<FixedMaterial> mat_speaker( memnew( FixedMaterial ));
|
||||
Ref<FixedMaterial> mat_speaker(memnew(FixedMaterial));
|
||||
|
||||
mat_speaker->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.3,0.3,0.6) );
|
||||
mat_speaker->set_parameter( FixedMaterial::PARAM_SPECULAR,Color(0.5,0.5,0.6) );
|
||||
mat_speaker->set_parameter(FixedMaterial::PARAM_DIFFUSE, Color(0.3, 0.3, 0.6));
|
||||
mat_speaker->set_parameter(FixedMaterial::PARAM_SPECULAR, Color(0.5, 0.5, 0.6));
|
||||
//mat_speaker->set_blend_mode( Material::BLEND_MODE_MIX);
|
||||
//mat_speaker->set_flag(Material::FLAG_DOUBLE_SIDED,false);
|
||||
//mat_speaker->set_flag(Material::FLAG_UNSHADED,true);
|
||||
|
|
@ -166,41 +157,37 @@ RES SpatialPlayer::_get_gizmo_geometry() const {
|
|||
surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
surface_tool->set_material(mat_speaker);
|
||||
|
||||
// float radius=1;
|
||||
// float radius=1;
|
||||
|
||||
|
||||
const int speaker_points=8;
|
||||
Vector3 speaker[speaker_points]={
|
||||
Vector3(0,0,1)*0.15,
|
||||
Vector3(1,1,1)*0.15,
|
||||
Vector3(1,1,0)*0.15,
|
||||
Vector3(2,2,-1)*0.15,
|
||||
Vector3(1,1,-1)*0.15,
|
||||
Vector3(0.8,0.8,-1.2)*0.15,
|
||||
Vector3(0.5,0.5,-1.4)*0.15,
|
||||
Vector3(0.0,0.0,-1.6)*0.15
|
||||
const int speaker_points = 8;
|
||||
Vector3 speaker[speaker_points] = {
|
||||
Vector3(0, 0, 1) * 0.15,
|
||||
Vector3(1, 1, 1) * 0.15,
|
||||
Vector3(1, 1, 0) * 0.15,
|
||||
Vector3(2, 2, -1) * 0.15,
|
||||
Vector3(1, 1, -1) * 0.15,
|
||||
Vector3(0.8, 0.8, -1.2) * 0.15,
|
||||
Vector3(0.5, 0.5, -1.4) * 0.15,
|
||||
Vector3(0.0, 0.0, -1.6) * 0.15
|
||||
};
|
||||
|
||||
int speaker_sides=10;
|
||||
int speaker_sides = 10;
|
||||
|
||||
for (int i = 0; i < speaker_sides; i++) {
|
||||
|
||||
for(int i = 0; i < speaker_sides ; i++) {
|
||||
Matrix3 ma(Vector3(0, 0, 1), Math_PI * 2 * float(i) / speaker_sides);
|
||||
Matrix3 mb(Vector3(0, 0, 1), Math_PI * 2 * float(i + 1) / speaker_sides);
|
||||
|
||||
for (int j = 0; j < speaker_points - 1; j++) {
|
||||
|
||||
Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/speaker_sides);
|
||||
Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/speaker_sides);
|
||||
|
||||
|
||||
for(int j=0;j<speaker_points-1;j++) {
|
||||
|
||||
Vector3 points[4]={
|
||||
Vector3 points[4] = {
|
||||
ma.xform(speaker[j]),
|
||||
mb.xform(speaker[j]),
|
||||
mb.xform(speaker[j+1]),
|
||||
ma.xform(speaker[j+1]),
|
||||
mb.xform(speaker[j + 1]),
|
||||
ma.xform(speaker[j + 1]),
|
||||
};
|
||||
|
||||
Vector3 n = -Plane(points[0],points[1],points[2]).normal;
|
||||
Vector3 n = -Plane(points[0], points[1], points[2]).normal;
|
||||
|
||||
surface_tool->add_normal(n);
|
||||
surface_tool->add_vertex(points[0]);
|
||||
|
|
@ -215,58 +202,45 @@ RES SpatialPlayer::_get_gizmo_geometry() const {
|
|||
surface_tool->add_vertex(points[3]);
|
||||
surface_tool->add_normal(n);
|
||||
surface_tool->add_vertex(points[2]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return surface_tool->commit(mesh);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SpatialPlayer::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_param", "param", "value"), &SpatialPlayer::set_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_param", "param"), &SpatialPlayer::get_param);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_param","param","value"),&SpatialPlayer::set_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_param","param"),&SpatialPlayer::get_param);
|
||||
|
||||
BIND_CONSTANT( PARAM_VOLUME_DB );
|
||||
BIND_CONSTANT( PARAM_PITCH_SCALE );
|
||||
BIND_CONSTANT( PARAM_ATTENUATION_MIN_DISTANCE );
|
||||
BIND_CONSTANT( PARAM_ATTENUATION_MAX_DISTANCE );
|
||||
BIND_CONSTANT( PARAM_ATTENUATION_DISTANCE_EXP );
|
||||
BIND_CONSTANT( PARAM_EMISSION_CONE_DEGREES );
|
||||
BIND_CONSTANT( PARAM_EMISSION_CONE_ATTENUATION_DB );
|
||||
BIND_CONSTANT( PARAM_MAX );
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/volume_db",PROPERTY_HINT_RANGE, "-80,24,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_VOLUME_DB);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/pitch_scale",PROPERTY_HINT_RANGE, "0.001,32,0.001"),_SCS("set_param"),_SCS("get_param"),PARAM_PITCH_SCALE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation/min_distance",PROPERTY_HINT_RANGE, "0.01,4096,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_ATTENUATION_MIN_DISTANCE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation/max_distance",PROPERTY_HINT_RANGE, "0.01,4096,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_ATTENUATION_MAX_DISTANCE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation/distance_exp",PROPERTY_HINT_EXP_EASING, "attenuation"),_SCS("set_param"),_SCS("get_param"),PARAM_ATTENUATION_DISTANCE_EXP);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/emission_cone/degrees",PROPERTY_HINT_RANGE, "0,180,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_EMISSION_CONE_DEGREES);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/emission_cone/attenuation_db",PROPERTY_HINT_RANGE, "-80,24,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_EMISSION_CONE_ATTENUATION_DB);
|
||||
BIND_CONSTANT(PARAM_VOLUME_DB);
|
||||
BIND_CONSTANT(PARAM_PITCH_SCALE);
|
||||
BIND_CONSTANT(PARAM_ATTENUATION_MIN_DISTANCE);
|
||||
BIND_CONSTANT(PARAM_ATTENUATION_MAX_DISTANCE);
|
||||
BIND_CONSTANT(PARAM_ATTENUATION_DISTANCE_EXP);
|
||||
BIND_CONSTANT(PARAM_EMISSION_CONE_DEGREES);
|
||||
BIND_CONSTANT(PARAM_EMISSION_CONE_ATTENUATION_DB);
|
||||
BIND_CONSTANT(PARAM_MAX);
|
||||
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_VOLUME_DB);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/pitch_scale", PROPERTY_HINT_RANGE, "0.001,32,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_PITCH_SCALE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation/min_distance", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_MIN_DISTANCE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation/max_distance", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_MAX_DISTANCE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/attenuation/distance_exp", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION_DISTANCE_EXP);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/emission_cone/degrees", PROPERTY_HINT_RANGE, "0,180,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_EMISSION_CONE_DEGREES);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/emission_cone/attenuation_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_EMISSION_CONE_ATTENUATION_DB);
|
||||
}
|
||||
|
||||
|
||||
SpatialPlayer::SpatialPlayer() {
|
||||
|
||||
params[PARAM_VOLUME_DB]=0.0;
|
||||
params[PARAM_PITCH_SCALE]=1.0;
|
||||
params[PARAM_ATTENUATION_MIN_DISTANCE]=1;
|
||||
params[PARAM_ATTENUATION_MAX_DISTANCE]=100;
|
||||
params[PARAM_ATTENUATION_DISTANCE_EXP]=1.0; //linear (and not really good)
|
||||
params[PARAM_EMISSION_CONE_DEGREES]=180.0; //cone disabled
|
||||
params[PARAM_EMISSION_CONE_ATTENUATION_DB]=-6.0; //minus 6 db attenuation
|
||||
|
||||
params[PARAM_VOLUME_DB] = 0.0;
|
||||
params[PARAM_PITCH_SCALE] = 1.0;
|
||||
params[PARAM_ATTENUATION_MIN_DISTANCE] = 1;
|
||||
params[PARAM_ATTENUATION_MAX_DISTANCE] = 100;
|
||||
params[PARAM_ATTENUATION_DISTANCE_EXP] = 1.0; //linear (and not really good)
|
||||
params[PARAM_EMISSION_CONE_DEGREES] = 180.0; //cone disabled
|
||||
params[PARAM_EMISSION_CONE_ATTENUATION_DB] = -6.0; //minus 6 db attenuation
|
||||
}
|
||||
|
||||
SpatialPlayer::~SpatialPlayer() {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,42 +29,37 @@
|
|||
#ifndef SPATIAL_PLAYER_H
|
||||
#define SPATIAL_PLAYER_H
|
||||
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/resources/sample_library.h"
|
||||
#include "servers/spatial_sound_server.h"
|
||||
#include "scene/main/viewport.h"
|
||||
|
||||
class SpatialPlayer : public Spatial {
|
||||
|
||||
OBJ_TYPE(SpatialPlayer,Spatial);
|
||||
OBJ_TYPE(SpatialPlayer, Spatial);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
enum Param {
|
||||
|
||||
PARAM_VOLUME_DB=SpatialSoundServer::SOURCE_PARAM_VOLUME_DB,
|
||||
PARAM_PITCH_SCALE=SpatialSoundServer::SOURCE_PARAM_PITCH_SCALE,
|
||||
PARAM_ATTENUATION_MIN_DISTANCE=SpatialSoundServer::SOURCE_PARAM_ATTENUATION_MIN_DISTANCE,
|
||||
PARAM_ATTENUATION_MAX_DISTANCE=SpatialSoundServer::SOURCE_PARAM_ATTENUATION_MAX_DISTANCE,
|
||||
PARAM_ATTENUATION_DISTANCE_EXP=SpatialSoundServer::SOURCE_PARAM_ATTENUATION_DISTANCE_EXP,
|
||||
PARAM_EMISSION_CONE_DEGREES=SpatialSoundServer::SOURCE_PARAM_EMISSION_CONE_DEGREES,
|
||||
PARAM_EMISSION_CONE_ATTENUATION_DB=SpatialSoundServer::SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB,
|
||||
PARAM_MAX=SpatialSoundServer::SOURCE_PARAM_MAX
|
||||
PARAM_VOLUME_DB = SpatialSoundServer::SOURCE_PARAM_VOLUME_DB,
|
||||
PARAM_PITCH_SCALE = SpatialSoundServer::SOURCE_PARAM_PITCH_SCALE,
|
||||
PARAM_ATTENUATION_MIN_DISTANCE = SpatialSoundServer::SOURCE_PARAM_ATTENUATION_MIN_DISTANCE,
|
||||
PARAM_ATTENUATION_MAX_DISTANCE = SpatialSoundServer::SOURCE_PARAM_ATTENUATION_MAX_DISTANCE,
|
||||
PARAM_ATTENUATION_DISTANCE_EXP = SpatialSoundServer::SOURCE_PARAM_ATTENUATION_DISTANCE_EXP,
|
||||
PARAM_EMISSION_CONE_DEGREES = SpatialSoundServer::SOURCE_PARAM_EMISSION_CONE_DEGREES,
|
||||
PARAM_EMISSION_CONE_ATTENUATION_DB = SpatialSoundServer::SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB,
|
||||
PARAM_MAX = SpatialSoundServer::SOURCE_PARAM_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
float params[PARAM_MAX];
|
||||
RID source_rid;
|
||||
|
||||
virtual bool _can_gizmo_scale() const;
|
||||
virtual RES _get_gizmo_geometry() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
_FORCE_INLINE_ RID get_source_rid() const { return source_rid; }
|
||||
|
||||
void _notification(int p_what);
|
||||
|
|
@ -72,16 +67,12 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_param( Param p_param, float p_value);
|
||||
float get_param( Param p_param) const;
|
||||
|
||||
void set_param(Param p_param, float p_value);
|
||||
float get_param(Param p_param) const;
|
||||
|
||||
SpatialPlayer();
|
||||
~SpatialPlayer();
|
||||
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( SpatialPlayer::Param );
|
||||
VARIANT_ENUM_CAST(SpatialPlayer::Param);
|
||||
#endif // SPATIAL_PLAYER_H
|
||||
|
|
|
|||
|
|
@ -28,40 +28,38 @@
|
|||
/*************************************************************************/
|
||||
#include "spatial_sample_player.h"
|
||||
|
||||
#include "servers/audio_server.h"
|
||||
#include "camera.h"
|
||||
#include "servers/spatial_sound_server.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/spatial_sound_server.h"
|
||||
|
||||
bool SpatialSamplePlayer::_set(const StringName& p_name, const Variant& p_value) {
|
||||
bool SpatialSamplePlayer::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
String name=p_name;
|
||||
String name = p_name;
|
||||
|
||||
if (name==SceneStringNames::get_singleton()->play_play) {
|
||||
if (name == SceneStringNames::get_singleton()->play_play) {
|
||||
if (library.is_valid()) {
|
||||
|
||||
String what=p_value;
|
||||
if (what=="")
|
||||
String what = p_value;
|
||||
if (what == "")
|
||||
stop_all();
|
||||
else
|
||||
play(what);
|
||||
|
||||
played_back=what;
|
||||
played_back = what;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpatialSamplePlayer::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
bool SpatialSamplePlayer::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
String name = p_name;
|
||||
|
||||
String name=p_name;
|
||||
|
||||
if (name==SceneStringNames::get_singleton()->play_play) {
|
||||
r_ret=played_back;
|
||||
if (name == SceneStringNames::get_singleton()->play_play) {
|
||||
r_ret = played_back;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -70,39 +68,35 @@ bool SpatialSamplePlayer::_get(const StringName& p_name,Variant &r_ret) const {
|
|||
|
||||
void SpatialSamplePlayer::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
String en="";
|
||||
String en = "";
|
||||
if (library.is_valid()) {
|
||||
List<StringName> samples;
|
||||
Ref<SampleLibrary> ncl=library;
|
||||
Ref<SampleLibrary> ncl = library;
|
||||
ncl->get_sample_list(&samples);
|
||||
for (List<StringName>::Element *E=samples.front();E;E=E->next()) {
|
||||
for (List<StringName>::Element *E = samples.front(); E; E = E->next()) {
|
||||
|
||||
en+=",";
|
||||
en+=E->get();
|
||||
en += ",";
|
||||
en += E->get();
|
||||
}
|
||||
}
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
|
||||
}
|
||||
void SpatialSamplePlayer::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_polyphony(get_source_rid(),polyphony);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_polyphony(get_source_rid(), polyphony);
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SpatialSamplePlayer::set_sample_library(const Ref<SampleLibrary>& p_library) {
|
||||
void SpatialSamplePlayer::set_sample_library(const Ref<SampleLibrary> &p_library) {
|
||||
|
||||
library=p_library;
|
||||
library = p_library;
|
||||
_change_notify();
|
||||
update_configuration_warning();
|
||||
}
|
||||
|
|
@ -114,11 +108,10 @@ Ref<SampleLibrary> SpatialSamplePlayer::get_sample_library() const {
|
|||
|
||||
void SpatialSamplePlayer::set_polyphony(int p_voice_count) {
|
||||
|
||||
ERR_FAIL_COND(p_voice_count<0 || p_voice_count>64);
|
||||
polyphony=p_voice_count;
|
||||
ERR_FAIL_COND(p_voice_count < 0 || p_voice_count > 64);
|
||||
polyphony = p_voice_count;
|
||||
if (get_source_rid().is_valid())
|
||||
SpatialSoundServer::get_singleton()->source_set_polyphony(get_source_rid(),polyphony);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_polyphony(get_source_rid(), polyphony);
|
||||
}
|
||||
|
||||
int SpatialSamplePlayer::get_polyphony() const {
|
||||
|
|
@ -126,7 +119,7 @@ int SpatialSamplePlayer::get_polyphony() const {
|
|||
return polyphony;
|
||||
}
|
||||
|
||||
SpatialSamplePlayer::VoiceID SpatialSamplePlayer::play(const String& p_sample,int p_voice) {
|
||||
SpatialSamplePlayer::VoiceID SpatialSamplePlayer::play(const String &p_sample, int p_voice) {
|
||||
|
||||
if (!get_source_rid().is_valid())
|
||||
return INVALID_VOICE;
|
||||
|
|
@ -138,13 +131,11 @@ SpatialSamplePlayer::VoiceID SpatialSamplePlayer::play(const String& p_sample,in
|
|||
float vol_change = library->sample_get_volume_db(p_sample);
|
||||
float pitch_change = library->sample_get_pitch_scale(p_sample);
|
||||
|
||||
VoiceID vid = SpatialSoundServer::get_singleton()->source_play_sample(get_source_rid(),sample->get_rid(),sample->get_mix_rate()*pitch_change,p_voice);
|
||||
VoiceID vid = SpatialSoundServer::get_singleton()->source_play_sample(get_source_rid(), sample->get_rid(), sample->get_mix_rate() * pitch_change, p_voice);
|
||||
if (vol_change)
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_volume_scale_db(get_source_rid(),vid,vol_change);
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_volume_scale_db(get_source_rid(), vid, vol_change);
|
||||
|
||||
return vid;
|
||||
|
||||
|
||||
}
|
||||
//voices
|
||||
void SpatialSamplePlayer::voice_set_pitch_scale(VoiceID p_voice, float p_pitch_scale) {
|
||||
|
|
@ -152,32 +143,28 @@ void SpatialSamplePlayer::voice_set_pitch_scale(VoiceID p_voice, float p_pitch_s
|
|||
if (!get_source_rid().is_valid())
|
||||
return;
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_pitch_scale(get_source_rid(),p_voice,p_pitch_scale);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_pitch_scale(get_source_rid(), p_voice, p_pitch_scale);
|
||||
}
|
||||
|
||||
void SpatialSamplePlayer::voice_set_volume_scale_db(VoiceID p_voice, float p_volume_db) {
|
||||
|
||||
if (!get_source_rid().is_valid())
|
||||
return;
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_volume_scale_db(get_source_rid(),p_voice,p_volume_db);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_voice_set_volume_scale_db(get_source_rid(), p_voice, p_volume_db);
|
||||
}
|
||||
|
||||
bool SpatialSamplePlayer::is_voice_active(VoiceID p_voice) const {
|
||||
|
||||
if (!get_source_rid().is_valid())
|
||||
return false;
|
||||
return SpatialSoundServer::get_singleton()->source_is_voice_active(get_source_rid(),p_voice);
|
||||
|
||||
return SpatialSoundServer::get_singleton()->source_is_voice_active(get_source_rid(), p_voice);
|
||||
}
|
||||
|
||||
void SpatialSamplePlayer::stop_voice(VoiceID p_voice) {
|
||||
|
||||
if (!get_source_rid().is_valid())
|
||||
return;
|
||||
SpatialSoundServer::get_singleton()->source_stop_voice(get_source_rid(),p_voice);
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_stop_voice(get_source_rid(), p_voice);
|
||||
}
|
||||
|
||||
void SpatialSamplePlayer::stop_all() {
|
||||
|
|
@ -185,9 +172,9 @@ void SpatialSamplePlayer::stop_all() {
|
|||
if (!get_source_rid().is_valid())
|
||||
return;
|
||||
|
||||
for(int i=0;i<polyphony;i++) {
|
||||
for (int i = 0; i < polyphony; i++) {
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_stop_voice(get_source_rid(),i);
|
||||
SpatialSoundServer::get_singleton()->source_stop_voice(get_source_rid(), i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,42 +187,34 @@ String SpatialSamplePlayer::get_configuration_warning() const {
|
|||
return String();
|
||||
}
|
||||
|
||||
|
||||
void SpatialSamplePlayer::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_sample_library", "library:SampleLibrary"), &SpatialSamplePlayer::set_sample_library);
|
||||
ObjectTypeDB::bind_method(_MD("get_sample_library:SampleLibrary"), &SpatialSamplePlayer::get_sample_library);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_sample_library","library:SampleLibrary"),&SpatialSamplePlayer::set_sample_library);
|
||||
ObjectTypeDB::bind_method(_MD("get_sample_library:SampleLibrary"),&SpatialSamplePlayer::get_sample_library);
|
||||
ObjectTypeDB::bind_method(_MD("set_polyphony", "voices"), &SpatialSamplePlayer::set_polyphony);
|
||||
ObjectTypeDB::bind_method(_MD("get_polyphony"), &SpatialSamplePlayer::get_polyphony);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_polyphony","voices"),&SpatialSamplePlayer::set_polyphony);
|
||||
ObjectTypeDB::bind_method(_MD("get_polyphony"),&SpatialSamplePlayer::get_polyphony);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("play","sample","voice"),&SpatialSamplePlayer::play,DEFVAL(NEXT_VOICE));
|
||||
ObjectTypeDB::bind_method(_MD("play", "sample", "voice"), &SpatialSamplePlayer::play, DEFVAL(NEXT_VOICE));
|
||||
//voices,DEV
|
||||
ObjectTypeDB::bind_method(_MD("voice_set_pitch_scale","voice","ratio"),&SpatialSamplePlayer::voice_set_pitch_scale);
|
||||
ObjectTypeDB::bind_method(_MD("voice_set_volume_scale_db","voice","db"),&SpatialSamplePlayer::voice_set_volume_scale_db);
|
||||
ObjectTypeDB::bind_method(_MD("voice_set_pitch_scale", "voice", "ratio"), &SpatialSamplePlayer::voice_set_pitch_scale);
|
||||
ObjectTypeDB::bind_method(_MD("voice_set_volume_scale_db", "voice", "db"), &SpatialSamplePlayer::voice_set_volume_scale_db);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("is_voice_active","voice"),&SpatialSamplePlayer::is_voice_active);
|
||||
ObjectTypeDB::bind_method(_MD("stop_voice","voice"),&SpatialSamplePlayer::stop_voice);
|
||||
ObjectTypeDB::bind_method(_MD("stop_all"),&SpatialSamplePlayer::stop_all);
|
||||
|
||||
BIND_CONSTANT( INVALID_VOICE );
|
||||
BIND_CONSTANT( NEXT_VOICE );
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "config/polyphony", PROPERTY_HINT_RANGE, "1,64,1"),_SCS("set_polyphony"),_SCS("get_polyphony"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "config/samples", PROPERTY_HINT_RESOURCE_TYPE,"SampleLibrary"),_SCS("set_sample_library"),_SCS("get_sample_library"));
|
||||
ObjectTypeDB::bind_method(_MD("is_voice_active", "voice"), &SpatialSamplePlayer::is_voice_active);
|
||||
ObjectTypeDB::bind_method(_MD("stop_voice", "voice"), &SpatialSamplePlayer::stop_voice);
|
||||
ObjectTypeDB::bind_method(_MD("stop_all"), &SpatialSamplePlayer::stop_all);
|
||||
|
||||
BIND_CONSTANT(INVALID_VOICE);
|
||||
BIND_CONSTANT(NEXT_VOICE);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "config/polyphony", PROPERTY_HINT_RANGE, "1,64,1"), _SCS("set_polyphony"), _SCS("get_polyphony"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "config/samples", PROPERTY_HINT_RESOURCE_TYPE, "SampleLibrary"), _SCS("set_sample_library"), _SCS("get_sample_library"));
|
||||
}
|
||||
|
||||
|
||||
SpatialSamplePlayer::SpatialSamplePlayer() {
|
||||
|
||||
polyphony=1;
|
||||
|
||||
polyphony = 1;
|
||||
}
|
||||
|
||||
SpatialSamplePlayer::~SpatialSamplePlayer() {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,41 +35,38 @@
|
|||
|
||||
class SpatialSamplePlayer : public SpatialPlayer {
|
||||
|
||||
OBJ_TYPE(SpatialSamplePlayer,SpatialPlayer);
|
||||
public:
|
||||
OBJ_TYPE(SpatialSamplePlayer, SpatialPlayer);
|
||||
|
||||
public:
|
||||
enum {
|
||||
|
||||
INVALID_VOICE=SpatialSoundServer::SOURCE_INVALID_VOICE,
|
||||
NEXT_VOICE=SpatialSoundServer::SOURCE_NEXT_VOICE
|
||||
INVALID_VOICE = SpatialSoundServer::SOURCE_INVALID_VOICE,
|
||||
NEXT_VOICE = SpatialSoundServer::SOURCE_NEXT_VOICE
|
||||
};
|
||||
|
||||
typedef int VoiceID;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Ref<SampleLibrary> library;
|
||||
int polyphony;
|
||||
String played_back;
|
||||
protected:
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
protected:
|
||||
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;
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_sample_library(const Ref<SampleLibrary>& p_library);
|
||||
void set_sample_library(const Ref<SampleLibrary> &p_library);
|
||||
Ref<SampleLibrary> get_sample_library() const;
|
||||
|
||||
void set_polyphony(int p_voice_count);
|
||||
int get_polyphony() const;
|
||||
|
||||
VoiceID play(const String& p_sample,int p_voice=NEXT_VOICE);
|
||||
VoiceID play(const String &p_sample, int p_voice = NEXT_VOICE);
|
||||
//voices
|
||||
void voice_set_pitch_scale(VoiceID p_voice, float p_pitch_scale);
|
||||
void voice_set_volume_scale_db(VoiceID p_voice, float p_volume_db);
|
||||
|
|
@ -82,9 +79,6 @@ public:
|
|||
|
||||
SpatialSamplePlayer();
|
||||
~SpatialSamplePlayer();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // SPATIAL_SAMPLE_PLAYER_H
|
||||
|
|
|
|||
|
|
@ -28,40 +28,37 @@
|
|||
/*************************************************************************/
|
||||
#include "spatial_stream_player.h"
|
||||
|
||||
|
||||
|
||||
int SpatialStreamPlayer::InternalStream::get_channel_count() const {
|
||||
|
||||
return player->sp_get_channel_count();
|
||||
}
|
||||
void SpatialStreamPlayer::InternalStream::set_mix_rate(int p_rate){
|
||||
void SpatialStreamPlayer::InternalStream::set_mix_rate(int p_rate) {
|
||||
|
||||
return player->sp_set_mix_rate(p_rate);
|
||||
}
|
||||
bool SpatialStreamPlayer::InternalStream::mix(int32_t *p_buffer,int p_frames){
|
||||
bool SpatialStreamPlayer::InternalStream::mix(int32_t *p_buffer, int p_frames) {
|
||||
|
||||
return player->sp_mix(p_buffer,p_frames);
|
||||
return player->sp_mix(p_buffer, p_frames);
|
||||
}
|
||||
void SpatialStreamPlayer::InternalStream::update(){
|
||||
void SpatialStreamPlayer::InternalStream::update() {
|
||||
|
||||
player->sp_update();
|
||||
}
|
||||
|
||||
|
||||
int SpatialStreamPlayer::sp_get_channel_count() const {
|
||||
|
||||
return playback->get_channels();
|
||||
}
|
||||
|
||||
void SpatialStreamPlayer::sp_set_mix_rate(int p_rate){
|
||||
void SpatialStreamPlayer::sp_set_mix_rate(int p_rate) {
|
||||
|
||||
server_mix_rate=p_rate;
|
||||
server_mix_rate = p_rate;
|
||||
}
|
||||
|
||||
bool SpatialStreamPlayer::sp_mix(int32_t *p_buffer,int p_frames) {
|
||||
bool SpatialStreamPlayer::sp_mix(int32_t *p_buffer, int p_frames) {
|
||||
|
||||
if (resampler.is_ready() && !paused) {
|
||||
return resampler.mix(p_buffer,p_frames);
|
||||
return resampler.mix(p_buffer, p_frames);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -76,7 +73,7 @@ void SpatialStreamPlayer::sp_update() {
|
|||
//stream depleted data, but there's still audio in the ringbuffer
|
||||
//check that all this audio has been flushed before stopping the stream
|
||||
int to_mix = resampler.get_total() - resampler.get_todo();
|
||||
if (to_mix==0) {
|
||||
if (to_mix == 0) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
|
@ -84,17 +81,15 @@ void SpatialStreamPlayer::sp_update() {
|
|||
return;
|
||||
}
|
||||
|
||||
int todo =resampler.get_todo();
|
||||
int wrote = playback->mix(resampler.get_write_buffer(),todo);
|
||||
int todo = resampler.get_todo();
|
||||
int wrote = playback->mix(resampler.get_write_buffer(), todo);
|
||||
resampler.write(wrote);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpatialStreamPlayer::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
|
|
@ -109,20 +104,18 @@ void SpatialStreamPlayer::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpatialStreamPlayer::set_stream(const Ref<AudioStream> &p_stream) {
|
||||
|
||||
stop();
|
||||
|
||||
stream=p_stream;
|
||||
stream = p_stream;
|
||||
|
||||
if (!stream.is_null()) {
|
||||
playback=stream->instance_playback();
|
||||
playback = stream->instance_playback();
|
||||
playback->set_loop(loops);
|
||||
playback->set_loop_restart_time(loop_point);
|
||||
AudioServer::get_singleton()->lock();
|
||||
resampler.setup(playback->get_channels(),playback->get_mix_rate(),server_mix_rate,buffering_ms,playback->get_minimum_buffer_size());
|
||||
resampler.setup(playback->get_channels(), playback->get_mix_rate(), server_mix_rate, buffering_ms, playback->get_minimum_buffer_size());
|
||||
AudioServer::get_singleton()->unlock();
|
||||
} else {
|
||||
AudioServer::get_singleton()->lock();
|
||||
|
|
@ -137,7 +130,6 @@ Ref<AudioStream> SpatialStreamPlayer::get_stream() const {
|
|||
return stream;
|
||||
}
|
||||
|
||||
|
||||
void SpatialStreamPlayer::play(float p_from_offset) {
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
|
@ -151,13 +143,12 @@ void SpatialStreamPlayer::play(float p_from_offset) {
|
|||
//feed the ringbuffer as long as no update callback is going on
|
||||
sp_update();
|
||||
|
||||
SpatialSoundServer::get_singleton()->source_set_audio_stream(get_source_rid(),&internal_stream);
|
||||
|
||||
// AudioServer::get_singleton()->stream_set_active(stream_rid,true);
|
||||
// AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
|
||||
// if (stream->get_update_mode()!=AudioStream::UPDATE_NONE)
|
||||
// set_idle_process(true);
|
||||
SpatialSoundServer::get_singleton()->source_set_audio_stream(get_source_rid(), &internal_stream);
|
||||
|
||||
// AudioServer::get_singleton()->stream_set_active(stream_rid,true);
|
||||
// AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
|
||||
// if (stream->get_update_mode()!=AudioStream::UPDATE_NONE)
|
||||
// set_idle_process(true);
|
||||
}
|
||||
|
||||
void SpatialStreamPlayer::stop() {
|
||||
|
|
@ -169,7 +160,7 @@ void SpatialStreamPlayer::stop() {
|
|||
|
||||
_THREAD_SAFE_METHOD_
|
||||
//AudioServer::get_singleton()->stream_set_active(stream_rid,false);
|
||||
SpatialSoundServer::get_singleton()->source_set_audio_stream(get_source_rid(),NULL);
|
||||
SpatialSoundServer::get_singleton()->source_set_audio_stream(get_source_rid(), NULL);
|
||||
playback->stop();
|
||||
resampler.flush();
|
||||
//set_idle_process(false);
|
||||
|
|
@ -185,11 +176,10 @@ bool SpatialStreamPlayer::is_playing() const {
|
|||
|
||||
void SpatialStreamPlayer::set_loop(bool p_enable) {
|
||||
|
||||
loops=p_enable;
|
||||
loops = p_enable;
|
||||
if (playback.is_null())
|
||||
return;
|
||||
playback->set_loop(loops);
|
||||
|
||||
}
|
||||
bool SpatialStreamPlayer::has_loop() const {
|
||||
|
||||
|
|
@ -198,9 +188,9 @@ bool SpatialStreamPlayer::has_loop() const {
|
|||
|
||||
void SpatialStreamPlayer::set_volume(float p_vol) {
|
||||
|
||||
volume=p_vol;
|
||||
volume = p_vol;
|
||||
if (stream_rid.is_valid())
|
||||
AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume);
|
||||
AudioServer::get_singleton()->stream_set_volume_scale(stream_rid, volume);
|
||||
}
|
||||
|
||||
float SpatialStreamPlayer::get_volume() const {
|
||||
|
|
@ -210,7 +200,7 @@ float SpatialStreamPlayer::get_volume() const {
|
|||
|
||||
void SpatialStreamPlayer::set_loop_restart_time(float p_secs) {
|
||||
|
||||
loop_point=p_secs;
|
||||
loop_point = p_secs;
|
||||
if (playback.is_valid())
|
||||
playback->set_loop_restart_time(p_secs);
|
||||
}
|
||||
|
|
@ -220,10 +210,9 @@ float SpatialStreamPlayer::get_loop_restart_time() const {
|
|||
return loop_point;
|
||||
}
|
||||
|
||||
|
||||
void SpatialStreamPlayer::set_volume_db(float p_db) {
|
||||
|
||||
if (p_db<-79)
|
||||
if (p_db < -79)
|
||||
set_volume(0);
|
||||
else
|
||||
set_volume(Math::db2linear(p_db));
|
||||
|
|
@ -231,35 +220,31 @@ void SpatialStreamPlayer::set_volume_db(float p_db) {
|
|||
|
||||
float SpatialStreamPlayer::get_volume_db() const {
|
||||
|
||||
if (volume==0)
|
||||
if (volume == 0)
|
||||
return -80;
|
||||
else
|
||||
return Math::linear2db(volume);
|
||||
}
|
||||
|
||||
|
||||
String SpatialStreamPlayer::get_stream_name() const {
|
||||
String SpatialStreamPlayer::get_stream_name() const {
|
||||
|
||||
if (stream.is_null())
|
||||
return "<No Stream>";
|
||||
return stream->get_name();
|
||||
|
||||
}
|
||||
|
||||
int SpatialStreamPlayer::get_loop_count() const {
|
||||
int SpatialStreamPlayer::get_loop_count() const {
|
||||
|
||||
if (playback.is_null())
|
||||
return 0;
|
||||
return playback->get_loop_count();
|
||||
|
||||
}
|
||||
|
||||
float SpatialStreamPlayer::get_pos() const {
|
||||
float SpatialStreamPlayer::get_pos() const {
|
||||
|
||||
if (playback.is_null())
|
||||
return 0;
|
||||
return playback->get_pos();
|
||||
|
||||
}
|
||||
|
||||
float SpatialStreamPlayer::get_length() const {
|
||||
|
|
@ -273,12 +258,11 @@ void SpatialStreamPlayer::seek_pos(float p_time) {
|
|||
if (playback.is_null())
|
||||
return;
|
||||
return playback->seek_pos(p_time);
|
||||
|
||||
}
|
||||
|
||||
void SpatialStreamPlayer::set_autoplay(bool p_enable) {
|
||||
|
||||
autoplay=p_enable;
|
||||
autoplay = p_enable;
|
||||
}
|
||||
|
||||
bool SpatialStreamPlayer::has_autoplay() const {
|
||||
|
|
@ -288,7 +272,7 @@ bool SpatialStreamPlayer::has_autoplay() const {
|
|||
|
||||
void SpatialStreamPlayer::set_paused(bool p_paused) {
|
||||
|
||||
paused=p_paused;
|
||||
paused = p_paused;
|
||||
//if (stream.is_valid())
|
||||
// stream->set_paused(p_paused);
|
||||
}
|
||||
|
|
@ -300,104 +284,97 @@ bool SpatialStreamPlayer::is_paused() const {
|
|||
|
||||
void SpatialStreamPlayer::_set_play(bool p_play) {
|
||||
|
||||
_play=p_play;
|
||||
_play = p_play;
|
||||
if (is_inside_tree()) {
|
||||
if(_play)
|
||||
if (_play)
|
||||
play();
|
||||
else
|
||||
stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool SpatialStreamPlayer::_get_play() const{
|
||||
bool SpatialStreamPlayer::_get_play() const {
|
||||
|
||||
return _play;
|
||||
}
|
||||
|
||||
void SpatialStreamPlayer::set_buffering_msec(int p_msec) {
|
||||
|
||||
buffering_ms=p_msec;
|
||||
buffering_ms = p_msec;
|
||||
}
|
||||
|
||||
int SpatialStreamPlayer::get_buffering_msec() const{
|
||||
int SpatialStreamPlayer::get_buffering_msec() const {
|
||||
|
||||
return buffering_ms;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpatialStreamPlayer::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_stream","stream:AudioStream"),&SpatialStreamPlayer::set_stream);
|
||||
ObjectTypeDB::bind_method(_MD("get_stream:AudioStream"),&SpatialStreamPlayer::get_stream);
|
||||
ObjectTypeDB::bind_method(_MD("set_stream", "stream:AudioStream"), &SpatialStreamPlayer::set_stream);
|
||||
ObjectTypeDB::bind_method(_MD("get_stream:AudioStream"), &SpatialStreamPlayer::get_stream);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("play","offset"),&SpatialStreamPlayer::play,DEFVAL(0));
|
||||
ObjectTypeDB::bind_method(_MD("stop"),&SpatialStreamPlayer::stop);
|
||||
ObjectTypeDB::bind_method(_MD("play", "offset"), &SpatialStreamPlayer::play, DEFVAL(0));
|
||||
ObjectTypeDB::bind_method(_MD("stop"), &SpatialStreamPlayer::stop);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("is_playing"),&SpatialStreamPlayer::is_playing);
|
||||
ObjectTypeDB::bind_method(_MD("is_playing"), &SpatialStreamPlayer::is_playing);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_paused","paused"),&SpatialStreamPlayer::set_paused);
|
||||
ObjectTypeDB::bind_method(_MD("is_paused"),&SpatialStreamPlayer::is_paused);
|
||||
ObjectTypeDB::bind_method(_MD("set_paused", "paused"), &SpatialStreamPlayer::set_paused);
|
||||
ObjectTypeDB::bind_method(_MD("is_paused"), &SpatialStreamPlayer::is_paused);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_loop","enabled"),&SpatialStreamPlayer::set_loop);
|
||||
ObjectTypeDB::bind_method(_MD("has_loop"),&SpatialStreamPlayer::has_loop);
|
||||
ObjectTypeDB::bind_method(_MD("set_loop", "enabled"), &SpatialStreamPlayer::set_loop);
|
||||
ObjectTypeDB::bind_method(_MD("has_loop"), &SpatialStreamPlayer::has_loop);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_volume","volume"),&SpatialStreamPlayer::set_volume);
|
||||
ObjectTypeDB::bind_method(_MD("get_volume"),&SpatialStreamPlayer::get_volume);
|
||||
ObjectTypeDB::bind_method(_MD("set_volume", "volume"), &SpatialStreamPlayer::set_volume);
|
||||
ObjectTypeDB::bind_method(_MD("get_volume"), &SpatialStreamPlayer::get_volume);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_volume_db","db"),&SpatialStreamPlayer::set_volume_db);
|
||||
ObjectTypeDB::bind_method(_MD("get_volume_db"),&SpatialStreamPlayer::get_volume_db);
|
||||
ObjectTypeDB::bind_method(_MD("set_volume_db", "db"), &SpatialStreamPlayer::set_volume_db);
|
||||
ObjectTypeDB::bind_method(_MD("get_volume_db"), &SpatialStreamPlayer::get_volume_db);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_buffering_msec","msec"),&SpatialStreamPlayer::set_buffering_msec);
|
||||
ObjectTypeDB::bind_method(_MD("get_buffering_msec"),&SpatialStreamPlayer::get_buffering_msec);
|
||||
ObjectTypeDB::bind_method(_MD("set_buffering_msec", "msec"), &SpatialStreamPlayer::set_buffering_msec);
|
||||
ObjectTypeDB::bind_method(_MD("get_buffering_msec"), &SpatialStreamPlayer::get_buffering_msec);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_loop_restart_time","secs"),&SpatialStreamPlayer::set_loop_restart_time);
|
||||
ObjectTypeDB::bind_method(_MD("get_loop_restart_time"),&SpatialStreamPlayer::get_loop_restart_time);
|
||||
ObjectTypeDB::bind_method(_MD("set_loop_restart_time", "secs"), &SpatialStreamPlayer::set_loop_restart_time);
|
||||
ObjectTypeDB::bind_method(_MD("get_loop_restart_time"), &SpatialStreamPlayer::get_loop_restart_time);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_stream_name"),&SpatialStreamPlayer::get_stream_name);
|
||||
ObjectTypeDB::bind_method(_MD("get_loop_count"),&SpatialStreamPlayer::get_loop_count);
|
||||
ObjectTypeDB::bind_method(_MD("get_stream_name"), &SpatialStreamPlayer::get_stream_name);
|
||||
ObjectTypeDB::bind_method(_MD("get_loop_count"), &SpatialStreamPlayer::get_loop_count);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_pos"),&SpatialStreamPlayer::get_pos);
|
||||
ObjectTypeDB::bind_method(_MD("seek_pos","time"),&SpatialStreamPlayer::seek_pos);
|
||||
ObjectTypeDB::bind_method(_MD("get_pos"), &SpatialStreamPlayer::get_pos);
|
||||
ObjectTypeDB::bind_method(_MD("seek_pos", "time"), &SpatialStreamPlayer::seek_pos);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_autoplay","enabled"),&SpatialStreamPlayer::set_autoplay);
|
||||
ObjectTypeDB::bind_method(_MD("has_autoplay"),&SpatialStreamPlayer::has_autoplay);
|
||||
ObjectTypeDB::bind_method(_MD("set_autoplay", "enabled"), &SpatialStreamPlayer::set_autoplay);
|
||||
ObjectTypeDB::bind_method(_MD("has_autoplay"), &SpatialStreamPlayer::has_autoplay);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_length"),&SpatialStreamPlayer::get_length);
|
||||
ObjectTypeDB::bind_method(_MD("get_length"), &SpatialStreamPlayer::get_length);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_play","play"),&SpatialStreamPlayer::_set_play);
|
||||
ObjectTypeDB::bind_method(_MD("_get_play"),&SpatialStreamPlayer::_get_play);
|
||||
ObjectTypeDB::bind_method(_MD("_set_play", "play"), &SpatialStreamPlayer::_set_play);
|
||||
ObjectTypeDB::bind_method(_MD("_get_play"), &SpatialStreamPlayer::_get_play);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"AudioStream"), _SCS("set_stream"), _SCS("get_stream") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/play"), _SCS("_set_play"), _SCS("_get_play") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/loop_restart_time"), _SCS("set_loop_restart_time"), _SCS("get_loop_restart_time") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/buffering_ms"), _SCS("set_buffering_msec"), _SCS("get_buffering_msec") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), _SCS("set_stream"), _SCS("get_stream"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream/play"), _SCS("_set_play"), _SCS("_get_play"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "stream/loop_restart_time"), _SCS("set_loop_restart_time"), _SCS("get_loop_restart_time"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "stream/buffering_ms"), _SCS("set_buffering_msec"), _SCS("get_buffering_msec"));
|
||||
}
|
||||
|
||||
|
||||
SpatialStreamPlayer::SpatialStreamPlayer() {
|
||||
|
||||
volume=1;
|
||||
loops=false;
|
||||
paused=false;
|
||||
autoplay=false;
|
||||
_play=false;
|
||||
server_mix_rate=1;
|
||||
internal_stream.player=this;
|
||||
stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream);
|
||||
buffering_ms=500;
|
||||
loop_point=0;
|
||||
|
||||
volume = 1;
|
||||
loops = false;
|
||||
paused = false;
|
||||
autoplay = false;
|
||||
_play = false;
|
||||
server_mix_rate = 1;
|
||||
internal_stream.player = this;
|
||||
stream_rid = AudioServer::get_singleton()->audio_stream_create(&internal_stream);
|
||||
buffering_ms = 500;
|
||||
loop_point = 0;
|
||||
}
|
||||
|
||||
SpatialStreamPlayer::~SpatialStreamPlayer() {
|
||||
AudioServer::get_singleton()->free(stream_rid);
|
||||
resampler.clear();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@
|
|||
#ifndef SPATIAL_STREAM_PLAYER_H
|
||||
#define SPATIAL_STREAM_PLAYER_H
|
||||
|
||||
#include "scene/resources/audio_stream.h"
|
||||
#include "scene/3d/spatial_player.h"
|
||||
#include "scene/resources/audio_stream.h"
|
||||
#include "servers/audio/audio_rb_resampler.h"
|
||||
|
||||
class SpatialStreamPlayer : public SpatialPlayer {
|
||||
|
||||
OBJ_TYPE(SpatialStreamPlayer,SpatialPlayer);
|
||||
OBJ_TYPE(SpatialStreamPlayer, SpatialPlayer);
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
|
|
@ -43,18 +43,17 @@ class SpatialStreamPlayer : public SpatialPlayer {
|
|||
SpatialStreamPlayer *player;
|
||||
virtual int get_channel_count() const;
|
||||
virtual void set_mix_rate(int p_rate); //notify the stream of the mix rate
|
||||
virtual bool mix(int32_t *p_buffer,int p_frames);
|
||||
virtual bool mix(int32_t *p_buffer, int p_frames);
|
||||
virtual void update();
|
||||
};
|
||||
|
||||
|
||||
InternalStream internal_stream;
|
||||
Ref<AudioStreamPlayback> playback;
|
||||
Ref<AudioStream> stream;
|
||||
|
||||
int sp_get_channel_count() const;
|
||||
void sp_set_mix_rate(int p_rate); //notify the stream of the mix rate
|
||||
bool sp_mix(int32_t *p_buffer,int p_frames);
|
||||
bool sp_mix(int32_t *p_buffer, int p_frames);
|
||||
void sp_update();
|
||||
|
||||
int server_mix_rate;
|
||||
|
|
@ -72,16 +71,17 @@ class SpatialStreamPlayer : public SpatialPlayer {
|
|||
bool _play;
|
||||
void _set_play(bool p_play);
|
||||
bool _get_play() const;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_stream(const Ref<AudioStream> &p_stream);
|
||||
Ref<AudioStream> get_stream() const;
|
||||
|
||||
void play(float p_from_offset=0);
|
||||
void play(float p_from_offset = 0);
|
||||
void stop();
|
||||
bool is_playing() const;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -29,15 +29,14 @@
|
|||
#ifndef SPRITE_3D_H
|
||||
#define SPRITE_3D_H
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "scene/2d/animated_sprite.h"
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
|
||||
class SpriteBase3D : public GeometryInstance {
|
||||
|
||||
OBJ_TYPE(SpriteBase3D,GeometryInstance);
|
||||
public:
|
||||
OBJ_TYPE(SpriteBase3D, GeometryInstance);
|
||||
|
||||
public:
|
||||
enum DrawFlags {
|
||||
FLAG_TRANSPARENT,
|
||||
FLAG_SHADED,
|
||||
|
|
@ -52,14 +51,12 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
|
||||
|
||||
bool color_dirty;
|
||||
Color color_accum;
|
||||
|
||||
SpriteBase3D *parent_sprite;
|
||||
List<SpriteBase3D*> children;
|
||||
List<SpriteBase3D*>::Element *pI;
|
||||
List<SpriteBase3D *> children;
|
||||
List<SpriteBase3D *>::Element *pI;
|
||||
|
||||
bool centered;
|
||||
Point2 offset;
|
||||
|
|
@ -67,7 +64,6 @@ private:
|
|||
bool hflip;
|
||||
bool vflip;
|
||||
|
||||
|
||||
Color modulate;
|
||||
float opacity;
|
||||
|
||||
|
|
@ -82,24 +78,22 @@ private:
|
|||
bool pending_update;
|
||||
void _im_update();
|
||||
|
||||
|
||||
void _propagate_color_changed();
|
||||
|
||||
protected:
|
||||
|
||||
Color _get_color_accum();
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
virtual void _draw()=0;
|
||||
_FORCE_INLINE_ void set_aabb(const AABB& p_aabb) { aabb=p_aabb; }
|
||||
_FORCE_INLINE_ RID& get_immediate() { return immediate; }
|
||||
virtual void _draw() = 0;
|
||||
_FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; }
|
||||
_FORCE_INLINE_ RID &get_immediate() { return immediate; }
|
||||
void _queue_update();
|
||||
public:
|
||||
|
||||
public:
|
||||
void set_centered(bool p_center);
|
||||
bool is_centered() const;
|
||||
|
||||
void set_offset(const Point2& p_offset);
|
||||
void set_offset(const Point2 &p_offset);
|
||||
Point2 get_offset() const;
|
||||
|
||||
void set_flip_h(bool p_flip);
|
||||
|
|
@ -111,10 +105,10 @@ public:
|
|||
void set_region(bool p_region);
|
||||
bool is_region() const;
|
||||
|
||||
void set_region_rect(const Rect2& p_region_rect);
|
||||
void set_region_rect(const Rect2 &p_region_rect);
|
||||
Rect2 get_region_rect() const;
|
||||
|
||||
void set_modulate(const Color& p_color);
|
||||
void set_modulate(const Color &p_color);
|
||||
Color get_modulate() const;
|
||||
|
||||
void set_opacity(float p_amount);
|
||||
|
|
@ -126,13 +120,13 @@ public:
|
|||
void set_axis(Vector3::Axis p_amount);
|
||||
Vector3::Axis get_axis() const;
|
||||
|
||||
void set_draw_flag(DrawFlags p_flag,bool p_enable);
|
||||
void set_draw_flag(DrawFlags p_flag, bool p_enable);
|
||||
bool get_draw_flag(DrawFlags p_flag) const;
|
||||
|
||||
void set_alpha_cut_mode(AlphaCutMode p_mode);
|
||||
AlphaCutMode get_alpha_cut_mode() const;
|
||||
|
||||
virtual Rect2 get_item_rect() const=0;
|
||||
virtual Rect2 get_item_rect() const = 0;
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
|
@ -141,13 +135,11 @@ public:
|
|||
~SpriteBase3D();
|
||||
};
|
||||
|
||||
|
||||
class Sprite3D : public SpriteBase3D {
|
||||
|
||||
OBJ_TYPE(Sprite3D,SpriteBase3D);
|
||||
OBJ_TYPE(Sprite3D, SpriteBase3D);
|
||||
Ref<Texture> texture;
|
||||
|
||||
|
||||
bool region;
|
||||
Rect2 region_rect;
|
||||
|
||||
|
|
@ -155,22 +147,21 @@ class Sprite3D : public SpriteBase3D {
|
|||
|
||||
int vframes;
|
||||
int hframes;
|
||||
|
||||
protected:
|
||||
virtual void _draw();
|
||||
static void _bind_methods();
|
||||
|
||||
virtual void _validate_property(PropertyInfo& property) const;
|
||||
virtual void _validate_property(PropertyInfo &property) const;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void set_texture(const Ref<Texture>& p_texture);
|
||||
void set_texture(const Ref<Texture> &p_texture);
|
||||
Ref<Texture> get_texture() const;
|
||||
|
||||
void set_region(bool p_region);
|
||||
bool is_region() const;
|
||||
|
||||
void set_region_rect(const Rect2& p_region_rect);
|
||||
void set_region_rect(const Rect2 &p_region_rect);
|
||||
Rect2 get_region_rect() const;
|
||||
|
||||
void set_frame(int p_frame);
|
||||
|
|
@ -185,7 +176,7 @@ public:
|
|||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
Sprite3D();
|
||||
// ~Sprite3D();
|
||||
// ~Sprite3D();
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
|
@ -219,12 +210,9 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
class AnimatedSprite3D : public SpriteBase3D {
|
||||
|
||||
OBJ_TYPE(AnimatedSprite3D,SpriteBase3D);
|
||||
OBJ_TYPE(AnimatedSprite3D, SpriteBase3D);
|
||||
|
||||
Ref<SpriteFrames> frames;
|
||||
bool playing;
|
||||
|
|
@ -247,39 +235,32 @@ class AnimatedSprite3D : public SpriteBase3D {
|
|||
void _set_playing(bool p_playing);
|
||||
bool _is_playing() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _draw();
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
virtual void _validate_property(PropertyInfo& property) const;
|
||||
virtual void _validate_property(PropertyInfo &property) const;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void set_sprite_frames(const Ref<SpriteFrames> &p_frames);
|
||||
Ref<SpriteFrames> get_sprite_frames() const;
|
||||
|
||||
void play(const StringName& p_animation=StringName());
|
||||
void play(const StringName &p_animation = StringName());
|
||||
void stop();
|
||||
bool is_playing() const;
|
||||
|
||||
void set_animation(const StringName& p_animation);
|
||||
void set_animation(const StringName &p_animation);
|
||||
StringName get_animation() const;
|
||||
|
||||
void set_frame(int p_frame);
|
||||
int get_frame() const;
|
||||
|
||||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
AnimatedSprite3D();
|
||||
};
|
||||
|
||||
|
||||
VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags);
|
||||
VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode);
|
||||
#endif // SPRITE_3D_H
|
||||
|
|
|
|||
|
|
@ -29,25 +29,19 @@
|
|||
#include "test_cube.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
|
||||
|
||||
AABB TestCube::get_aabb() const {
|
||||
|
||||
return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
|
||||
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
}
|
||||
DVector<Face3> TestCube::get_faces(uint32_t p_usage_flags) const {
|
||||
|
||||
return DVector<Face3>();
|
||||
}
|
||||
|
||||
|
||||
TestCube::TestCube() {
|
||||
|
||||
set_base(VisualServer::get_singleton()->get_test_cube());
|
||||
}
|
||||
|
||||
|
||||
TestCube::~TestCube() {
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,29 +29,24 @@
|
|||
#ifndef TEST_CUBE_H
|
||||
#define TEST_CUBE_H
|
||||
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
#include "rid.h"
|
||||
|
||||
#include "scene/3d/visual_instance.h"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class TestCube : public GeometryInstance {
|
||||
|
||||
OBJ_TYPE( TestCube, GeometryInstance );
|
||||
OBJ_TYPE(TestCube, GeometryInstance);
|
||||
|
||||
RID instance;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
||||
TestCube();
|
||||
~TestCube();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -35,20 +35,18 @@ class VehicleBody;
|
|||
|
||||
class VehicleWheel : public Spatial {
|
||||
|
||||
OBJ_TYPE(VehicleWheel,Spatial);
|
||||
|
||||
friend class VehicleBody;
|
||||
OBJ_TYPE(VehicleWheel, Spatial);
|
||||
|
||||
friend class VehicleBody;
|
||||
|
||||
Transform m_worldTransform;
|
||||
Transform local_xform;
|
||||
bool engine_traction;
|
||||
bool steers;
|
||||
|
||||
|
||||
Vector3 m_chassisConnectionPointCS; //const
|
||||
Vector3 m_wheelDirectionCS;//const
|
||||
Vector3 m_wheelAxleCS; // const or modified by steering
|
||||
Vector3 m_chassisConnectionPointCS; //const
|
||||
Vector3 m_wheelDirectionCS; //const
|
||||
Vector3 m_wheelAxleCS; // const or modified by steering
|
||||
|
||||
real_t m_suspensionRestLength;
|
||||
real_t m_maxSuspensionTravelCm;
|
||||
|
|
@ -63,32 +61,31 @@ friend class VehicleBody;
|
|||
|
||||
VehicleBody *body;
|
||||
|
||||
// btVector3 m_wheelAxleCS; // const or modified by steering ?
|
||||
// btVector3 m_wheelAxleCS; // const or modified by steering ?
|
||||
|
||||
real_t m_steering;
|
||||
real_t m_rotation;
|
||||
real_t m_deltaRotation;
|
||||
real_t m_rollInfluence;
|
||||
real_t m_steering;
|
||||
real_t m_rotation;
|
||||
real_t m_deltaRotation;
|
||||
real_t m_rollInfluence;
|
||||
//real_t m_engineForce;
|
||||
real_t m_brake;
|
||||
real_t m_brake;
|
||||
|
||||
real_t m_clippedInvContactDotSuspension;
|
||||
real_t m_suspensionRelativeVelocity;
|
||||
real_t m_clippedInvContactDotSuspension;
|
||||
real_t m_suspensionRelativeVelocity;
|
||||
//calculated by suspension
|
||||
real_t m_wheelsSuspensionForce;
|
||||
real_t m_skidInfo;
|
||||
|
||||
real_t m_wheelsSuspensionForce;
|
||||
real_t m_skidInfo;
|
||||
|
||||
struct RaycastInfo {
|
||||
//set by raycaster
|
||||
Vector3 m_contactNormalWS;//contactnormal
|
||||
Vector3 m_contactPointWS;//raycast hitpoint
|
||||
real_t m_suspensionLength;
|
||||
Vector3 m_hardPointWS;//raycast starting point
|
||||
Vector3 m_wheelDirectionWS; //direction in worldspace
|
||||
Vector3 m_wheelAxleWS; // axle in worldspace
|
||||
Vector3 m_contactNormalWS; //contactnormal
|
||||
Vector3 m_contactPointWS; //raycast hitpoint
|
||||
real_t m_suspensionLength;
|
||||
Vector3 m_hardPointWS; //raycast starting point
|
||||
Vector3 m_wheelDirectionWS; //direction in worldspace
|
||||
Vector3 m_wheelAxleWS; // axle in worldspace
|
||||
bool m_isInContact;
|
||||
PhysicsBody* m_groundObject; //could be general void* ptr
|
||||
PhysicsBody *m_groundObject; //could be general void* ptr
|
||||
} m_raycastInfo;
|
||||
|
||||
void _update(PhysicsDirectBodyState *s);
|
||||
|
|
@ -98,7 +95,6 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_radius(float p_radius);
|
||||
float get_radius() const;
|
||||
|
||||
|
|
@ -130,13 +126,11 @@ public:
|
|||
bool is_used_as_steering() const;
|
||||
|
||||
VehicleWheel();
|
||||
|
||||
};
|
||||
|
||||
|
||||
class VehicleBody : public PhysicsBody {
|
||||
|
||||
OBJ_TYPE(VehicleBody,PhysicsBody);
|
||||
OBJ_TYPE(VehicleBody, PhysicsBody);
|
||||
|
||||
real_t mass;
|
||||
real_t friction;
|
||||
|
|
@ -145,52 +139,48 @@ class VehicleBody : public PhysicsBody {
|
|||
float brake;
|
||||
|
||||
Vector3 linear_velocity;
|
||||
Vector3 angular_velocity;
|
||||
Vector3 angular_velocity;
|
||||
bool ccd;
|
||||
|
||||
real_t m_pitchControl;
|
||||
real_t m_steeringValue;
|
||||
real_t m_currentVehicleSpeedKmHour;
|
||||
real_t m_pitchControl;
|
||||
real_t m_steeringValue;
|
||||
real_t m_currentVehicleSpeedKmHour;
|
||||
|
||||
Set<RID> exclude;
|
||||
|
||||
Vector<Vector3> m_forwardWS;
|
||||
Vector<Vector3> m_axle;
|
||||
Vector<real_t> m_forwardImpulse;
|
||||
Vector<real_t> m_sideImpulse;
|
||||
Vector<Vector3> m_forwardWS;
|
||||
Vector<Vector3> m_axle;
|
||||
Vector<real_t> m_forwardImpulse;
|
||||
Vector<real_t> m_sideImpulse;
|
||||
|
||||
struct btVehicleWheelContactPoint {
|
||||
PhysicsDirectBodyState *m_s;
|
||||
PhysicsBody* m_body1;
|
||||
Vector3 m_frictionPositionWorld;
|
||||
Vector3 m_frictionDirectionWorld;
|
||||
real_t m_jacDiagABInv;
|
||||
real_t m_maxImpulse;
|
||||
PhysicsBody *m_body1;
|
||||
Vector3 m_frictionPositionWorld;
|
||||
Vector3 m_frictionDirectionWorld;
|
||||
real_t m_jacDiagABInv;
|
||||
real_t m_maxImpulse;
|
||||
|
||||
|
||||
btVehicleWheelContactPoint(PhysicsDirectBodyState *s,PhysicsBody* body1,const Vector3& frictionPosWorld,const Vector3& frictionDirectionWorld, real_t maxImpulse);
|
||||
btVehicleWheelContactPoint(PhysicsDirectBodyState *s, PhysicsBody *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse);
|
||||
};
|
||||
|
||||
void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3& pos1, PhysicsBody* body2, const Vector3& pos2, const Vector3& normal, real_t& impulse);
|
||||
real_t _calc_rolling_friction(btVehicleWheelContactPoint& contactPoint);
|
||||
void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse);
|
||||
real_t _calc_rolling_friction(btVehicleWheelContactPoint &contactPoint);
|
||||
|
||||
void _update_friction(PhysicsDirectBodyState *s);
|
||||
void _update_suspension(PhysicsDirectBodyState *s);
|
||||
real_t _ray_cast(int p_idx,PhysicsDirectBodyState *s);
|
||||
void _update_wheel_transform(VehicleWheel& wheel ,PhysicsDirectBodyState *s);
|
||||
void _update_wheel(int p_idx,PhysicsDirectBodyState *s);
|
||||
real_t _ray_cast(int p_idx, PhysicsDirectBodyState *s);
|
||||
void _update_wheel_transform(VehicleWheel &wheel, PhysicsDirectBodyState *s);
|
||||
void _update_wheel(int p_idx, PhysicsDirectBodyState *s);
|
||||
|
||||
|
||||
|
||||
friend class VehicleWheel;
|
||||
Vector<VehicleWheel*> wheels;
|
||||
friend class VehicleWheel;
|
||||
Vector<VehicleWheel *> wheels;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
void _direct_state_changed(Object *p_state);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
void set_mass(real_t p_mass);
|
||||
real_t get_mass() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,71 +28,64 @@
|
|||
/*************************************************************************/
|
||||
#include "visibility_notifier.h"
|
||||
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "scene/3d/physics_body.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
void VisibilityNotifier::_enter_camera(Camera* p_camera) {
|
||||
void VisibilityNotifier::_enter_camera(Camera *p_camera) {
|
||||
|
||||
ERR_FAIL_COND(cameras.has(p_camera));
|
||||
cameras.insert(p_camera);
|
||||
if (cameras.size()==1) {
|
||||
if (cameras.size() == 1) {
|
||||
emit_signal(SceneStringNames::get_singleton()->enter_screen);
|
||||
_screen_enter();
|
||||
}
|
||||
emit_signal(SceneStringNames::get_singleton()->enter_camera,p_camera);
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->enter_camera, p_camera);
|
||||
}
|
||||
|
||||
void VisibilityNotifier::_exit_camera(Camera* p_camera){
|
||||
void VisibilityNotifier::_exit_camera(Camera *p_camera) {
|
||||
|
||||
ERR_FAIL_COND(!cameras.has(p_camera));
|
||||
cameras.erase(p_camera);
|
||||
|
||||
emit_signal(SceneStringNames::get_singleton()->exit_camera,p_camera);
|
||||
if (cameras.size()==0) {
|
||||
emit_signal(SceneStringNames::get_singleton()->exit_camera, p_camera);
|
||||
if (cameras.size() == 0) {
|
||||
emit_signal(SceneStringNames::get_singleton()->exit_screen);
|
||||
|
||||
_screen_exit();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void VisibilityNotifier::set_aabb(const AABB &p_aabb) {
|
||||
|
||||
void VisibilityNotifier::set_aabb(const AABB& p_aabb){
|
||||
|
||||
if (aabb==p_aabb)
|
||||
if (aabb == p_aabb)
|
||||
return;
|
||||
aabb=p_aabb;
|
||||
aabb = p_aabb;
|
||||
|
||||
if (is_inside_world()) {
|
||||
get_world()->_update_notifier(this,get_global_transform().xform(aabb));
|
||||
get_world()->_update_notifier(this, get_global_transform().xform(aabb));
|
||||
}
|
||||
|
||||
_change_notify("aabb");
|
||||
update_gizmo();
|
||||
}
|
||||
|
||||
AABB VisibilityNotifier::get_aabb() const{
|
||||
AABB VisibilityNotifier::get_aabb() const {
|
||||
|
||||
return aabb;
|
||||
}
|
||||
|
||||
|
||||
void VisibilityNotifier::_notification(int p_what) {
|
||||
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
|
||||
get_world()->_register_notifier(this,get_global_transform().xform(aabb));
|
||||
get_world()->_register_notifier(this, get_global_transform().xform(aabb));
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
|
||||
get_world()->_update_notifier(this,get_global_transform().xform(aabb));
|
||||
get_world()->_update_notifier(this, get_global_transform().xform(aabb));
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
||||
|
|
@ -101,75 +94,64 @@ void VisibilityNotifier::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool VisibilityNotifier::is_on_screen() const {
|
||||
|
||||
return cameras.size()!=0;
|
||||
return cameras.size() != 0;
|
||||
}
|
||||
|
||||
void VisibilityNotifier::_bind_methods(){
|
||||
void VisibilityNotifier::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_aabb","rect"),&VisibilityNotifier::set_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"),&VisibilityNotifier::get_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("is_on_screen"),&VisibilityNotifier::is_on_screen);
|
||||
ObjectTypeDB::bind_method(_MD("set_aabb", "rect"), &VisibilityNotifier::set_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"), &VisibilityNotifier::get_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("is_on_screen"), &VisibilityNotifier::is_on_screen);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::_AABB,"aabb"),_SCS("set_aabb"),_SCS("get_aabb"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::_AABB, "aabb"), _SCS("set_aabb"), _SCS("get_aabb"));
|
||||
|
||||
ADD_SIGNAL( MethodInfo("enter_camera",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera")) );
|
||||
ADD_SIGNAL( MethodInfo("exit_camera",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera")) );
|
||||
ADD_SIGNAL( MethodInfo("enter_screen"));
|
||||
ADD_SIGNAL( MethodInfo("exit_screen"));
|
||||
ADD_SIGNAL(MethodInfo("enter_camera", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera")));
|
||||
ADD_SIGNAL(MethodInfo("exit_camera", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera")));
|
||||
ADD_SIGNAL(MethodInfo("enter_screen"));
|
||||
ADD_SIGNAL(MethodInfo("exit_screen"));
|
||||
}
|
||||
|
||||
|
||||
VisibilityNotifier::VisibilityNotifier() {
|
||||
|
||||
aabb=AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
|
||||
|
||||
aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
|
||||
void VisibilityEnabler::_screen_enter() {
|
||||
|
||||
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
|
||||
|
||||
for(Map<Node*,Variant>::Element *E=nodes.front();E;E=E->next()) {
|
||||
|
||||
_change_node_state(E->key(),true);
|
||||
_change_node_state(E->key(), true);
|
||||
}
|
||||
|
||||
visible=true;
|
||||
visible = true;
|
||||
}
|
||||
|
||||
void VisibilityEnabler::_screen_exit() {
|
||||
|
||||
for(Map<Node*,Variant>::Element *E=nodes.front();E;E=E->next()) {
|
||||
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
|
||||
|
||||
_change_node_state(E->key(),false);
|
||||
_change_node_state(E->key(), false);
|
||||
}
|
||||
|
||||
visible=false;
|
||||
visible = false;
|
||||
}
|
||||
|
||||
void VisibilityEnabler::_find_nodes(Node* p_node) {
|
||||
void VisibilityEnabler::_find_nodes(Node *p_node) {
|
||||
|
||||
|
||||
bool add=false;
|
||||
bool add = false;
|
||||
Variant meta;
|
||||
|
||||
if (enabler[ENABLER_FREEZE_BODIES]) {
|
||||
|
||||
RigidBody *rb = p_node->cast_to<RigidBody>();
|
||||
if (rb && ((rb->get_mode()==RigidBody::MODE_CHARACTER || (rb->get_mode()==RigidBody::MODE_RIGID && !rb->is_able_to_sleep())))) {
|
||||
if (rb && ((rb->get_mode() == RigidBody::MODE_CHARACTER || (rb->get_mode() == RigidBody::MODE_RIGID && !rb->is_able_to_sleep())))) {
|
||||
|
||||
|
||||
add=true;
|
||||
meta=rb->get_mode();
|
||||
add = true;
|
||||
meta = rb->get_mode();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,63 +159,58 @@ void VisibilityEnabler::_find_nodes(Node* p_node) {
|
|||
|
||||
AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();
|
||||
if (ap) {
|
||||
add=true;
|
||||
add = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
|
||||
p_node->connect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed",varray(p_node),CONNECT_ONESHOT);
|
||||
nodes[p_node]=meta;
|
||||
_change_node_state(p_node,false);
|
||||
p_node->connect(SceneStringNames::get_singleton()->exit_tree, this, "_node_removed", varray(p_node), CONNECT_ONESHOT);
|
||||
nodes[p_node] = meta;
|
||||
_change_node_state(p_node, false);
|
||||
}
|
||||
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
Node *c = p_node->get_child(i);
|
||||
if (c->get_filename()!=String())
|
||||
if (c->get_filename() != String())
|
||||
continue; //skip, instance
|
||||
|
||||
_find_nodes(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VisibilityEnabler::_notification(int p_what){
|
||||
void VisibilityEnabler::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
if (get_tree()->is_editor_hint())
|
||||
return;
|
||||
|
||||
|
||||
Node *from = this;
|
||||
//find where current scene starts
|
||||
while(from->get_parent() && from->get_filename()==String())
|
||||
from=from->get_parent();
|
||||
while (from->get_parent() && from->get_filename() == String())
|
||||
from = from->get_parent();
|
||||
|
||||
_find_nodes(from);
|
||||
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
|
||||
if (get_tree()->is_editor_hint())
|
||||
return;
|
||||
|
||||
|
||||
for (Map<Node*,Variant>::Element *E=nodes.front();E;E=E->next()) {
|
||||
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
|
||||
|
||||
if (!visible)
|
||||
_change_node_state(E->key(),true);
|
||||
E->key()->disconnect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed");
|
||||
_change_node_state(E->key(), true);
|
||||
E->key()->disconnect(SceneStringNames::get_singleton()->exit_tree, this, "_node_removed");
|
||||
}
|
||||
|
||||
nodes.clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void VisibilityEnabler::_change_node_state(Node* p_node,bool p_enabled) {
|
||||
void VisibilityEnabler::_change_node_state(Node *p_node, bool p_enabled) {
|
||||
|
||||
ERR_FAIL_COND(!nodes.has(p_node));
|
||||
|
||||
|
|
@ -245,59 +222,52 @@ void VisibilityEnabler::_change_node_state(Node* p_node,bool p_enabled) {
|
|||
}
|
||||
|
||||
{
|
||||
AnimationPlayer *ap=p_node->cast_to<AnimationPlayer>();
|
||||
AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();
|
||||
|
||||
if (ap) {
|
||||
|
||||
ap->set_active(p_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void VisibilityEnabler::_node_removed(Node* p_node) {
|
||||
void VisibilityEnabler::_node_removed(Node *p_node) {
|
||||
|
||||
if (!visible)
|
||||
_change_node_state(p_node,true);
|
||||
p_node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,"_node_removed");
|
||||
_change_node_state(p_node, true);
|
||||
p_node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, "_node_removed");
|
||||
nodes.erase(p_node);
|
||||
|
||||
}
|
||||
|
||||
void VisibilityEnabler::_bind_methods(){
|
||||
void VisibilityEnabler::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabler","enabler","enabled"),&VisibilityEnabler::set_enabler);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabler_enabled","enabler"),&VisibilityEnabler::is_enabler_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("_node_removed"),&VisibilityEnabler::_node_removed);
|
||||
ObjectTypeDB::bind_method(_MD("set_enabler", "enabler", "enabled"), &VisibilityEnabler::set_enabler);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabler_enabled", "enabler"), &VisibilityEnabler::is_enabler_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("_node_removed"), &VisibilityEnabler::_node_removed);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_animations"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_ANIMATIONS );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/freeze_bodies"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_FREEZE_BODIES);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "enabler/pause_animations"), _SCS("set_enabler"), _SCS("is_enabler_enabled"), ENABLER_PAUSE_ANIMATIONS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "enabler/freeze_bodies"), _SCS("set_enabler"), _SCS("is_enabler_enabled"), ENABLER_FREEZE_BODIES);
|
||||
|
||||
BIND_CONSTANT( ENABLER_FREEZE_BODIES );
|
||||
BIND_CONSTANT( ENABLER_PAUSE_ANIMATIONS );
|
||||
BIND_CONSTANT( ENABLER_MAX);
|
||||
BIND_CONSTANT(ENABLER_FREEZE_BODIES);
|
||||
BIND_CONSTANT(ENABLER_PAUSE_ANIMATIONS);
|
||||
BIND_CONSTANT(ENABLER_MAX);
|
||||
}
|
||||
|
||||
void VisibilityEnabler::set_enabler(Enabler p_enabler,bool p_enable){
|
||||
|
||||
ERR_FAIL_INDEX(p_enabler,ENABLER_MAX);
|
||||
enabler[p_enabler]=p_enable;
|
||||
void VisibilityEnabler::set_enabler(Enabler p_enabler, bool p_enable) {
|
||||
|
||||
ERR_FAIL_INDEX(p_enabler, ENABLER_MAX);
|
||||
enabler[p_enabler] = p_enable;
|
||||
}
|
||||
bool VisibilityEnabler::is_enabler_enabled(Enabler p_enabler) const{
|
||||
bool VisibilityEnabler::is_enabler_enabled(Enabler p_enabler) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_enabler,ENABLER_MAX,false);
|
||||
ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false);
|
||||
return enabler[p_enabler];
|
||||
|
||||
}
|
||||
|
||||
VisibilityEnabler::VisibilityEnabler() {
|
||||
|
||||
for(int i=0;i<ENABLER_MAX;i++)
|
||||
enabler[i]=true;
|
||||
|
||||
visible=false;
|
||||
for (int i = 0; i < ENABLER_MAX; i++)
|
||||
enabler[i] = true;
|
||||
|
||||
visible = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,39 +34,36 @@
|
|||
class Camera;
|
||||
class VisibilityNotifier : public Spatial {
|
||||
|
||||
OBJ_TYPE(VisibilityNotifier,Spatial);
|
||||
OBJ_TYPE(VisibilityNotifier, Spatial);
|
||||
|
||||
Set<Camera*> cameras;
|
||||
Set<Camera *> cameras;
|
||||
|
||||
AABB aabb;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _screen_enter() {}
|
||||
virtual void _screen_exit() {}
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
friend class SpatialIndexer;
|
||||
friend class SpatialIndexer;
|
||||
|
||||
void _enter_camera(Camera* p_camera);
|
||||
void _exit_camera(Camera* p_camera);
|
||||
void _enter_camera(Camera *p_camera);
|
||||
void _exit_camera(Camera *p_camera);
|
||||
|
||||
public:
|
||||
|
||||
void set_aabb(const AABB& p_aabb);
|
||||
void set_aabb(const AABB &p_aabb);
|
||||
AABB get_aabb() const;
|
||||
bool is_on_screen() const;
|
||||
|
||||
VisibilityNotifier();
|
||||
};
|
||||
|
||||
|
||||
class VisibilityEnabler : public VisibilityNotifier {
|
||||
|
||||
OBJ_TYPE(VisibilityEnabler,VisibilityNotifier);
|
||||
public:
|
||||
OBJ_TYPE(VisibilityEnabler, VisibilityNotifier);
|
||||
|
||||
public:
|
||||
enum Enabler {
|
||||
ENABLER_PAUSE_ANIMATIONS,
|
||||
ENABLER_FREEZE_BODIES,
|
||||
|
|
@ -74,33 +71,29 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _screen_enter();
|
||||
virtual void _screen_exit();
|
||||
|
||||
bool visible;
|
||||
|
||||
void _find_nodes(Node* p_node);
|
||||
void _find_nodes(Node *p_node);
|
||||
|
||||
Map<Node*,Variant> nodes;
|
||||
void _node_removed(Node* p_node);
|
||||
Map<Node *, Variant> nodes;
|
||||
void _node_removed(Node *p_node);
|
||||
bool enabler[ENABLER_MAX];
|
||||
|
||||
void _change_node_state(Node* p_node,bool p_enabled);
|
||||
void _change_node_state(Node *p_node, bool p_enabled);
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_enabler(Enabler p_enabler,bool p_enable);
|
||||
void set_enabler(Enabler p_enabler, bool p_enable);
|
||||
bool is_enabler_enabled(Enabler p_enabler) const;
|
||||
|
||||
VisibilityEnabler();
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VisibilityEnabler::Enabler);
|
||||
|
||||
|
||||
#endif // VISIBILITY_NOTIFIER_H
|
||||
|
|
|
|||
|
|
@ -28,49 +28,45 @@
|
|||
/*************************************************************************/
|
||||
#include "visual_instance.h"
|
||||
|
||||
#include "servers/visual_server.h"
|
||||
#include "baked_light_instance.h"
|
||||
#include "room_instance.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "baked_light_instance.h"
|
||||
#include "servers/visual_server.h"
|
||||
#include "skeleton.h"
|
||||
|
||||
AABB VisualInstance::get_transformed_aabb() const {
|
||||
|
||||
return get_global_transform().xform( get_aabb() );
|
||||
return get_global_transform().xform(get_aabb());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void VisualInstance::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
switch (p_what) {
|
||||
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
||||
// CHECK ROOM
|
||||
Spatial * parent = get_parent_spatial();
|
||||
Room *room=NULL;
|
||||
Spatial *parent = get_parent_spatial();
|
||||
Room *room = NULL;
|
||||
bool is_geom = cast_to<GeometryInstance>();
|
||||
|
||||
while(parent) {
|
||||
while (parent) {
|
||||
|
||||
room = parent->cast_to<Room>();
|
||||
if (room)
|
||||
break;
|
||||
|
||||
if (is_geom && parent->cast_to<BakedLightSampler>()) {
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_sampler(get_instance(),parent->cast_to<BakedLightSampler>()->get_instance());
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_sampler(get_instance(), parent->cast_to<BakedLightSampler>()->get_instance());
|
||||
break;
|
||||
}
|
||||
|
||||
parent=parent->get_parent_spatial();
|
||||
parent = parent->get_parent_spatial();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (room) {
|
||||
|
||||
VisualServer::get_singleton()->instance_set_room(instance,room->get_instance());
|
||||
VisualServer::get_singleton()->instance_set_room(instance, room->get_instance());
|
||||
}
|
||||
// CHECK SKELETON => moving skeleton attaching logic to MeshInstance
|
||||
/*
|
||||
|
|
@ -79,21 +75,20 @@ void VisualInstance::_notification(int p_what) {
|
|||
VisualServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() );
|
||||
*/
|
||||
|
||||
VisualServer::get_singleton()->instance_set_scenario( instance, get_world()->get_scenario() );
|
||||
VisualServer::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
Transform gt = get_global_transform();
|
||||
VisualServer::get_singleton()->instance_set_transform(instance,gt);
|
||||
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
||||
VisualServer::get_singleton()->instance_set_scenario( instance, RID() );
|
||||
VisualServer::get_singleton()->instance_set_room(instance,RID());
|
||||
VisualServer::get_singleton()->instance_attach_skeleton( instance, RID() );
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
|
||||
|
||||
VisualServer::get_singleton()->instance_set_scenario(instance, RID());
|
||||
VisualServer::get_singleton()->instance_set_room(instance, RID());
|
||||
VisualServer::get_singleton()->instance_attach_skeleton(instance, RID());
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID());
|
||||
|
||||
} break;
|
||||
}
|
||||
|
|
@ -111,8 +106,8 @@ RID VisualInstance::_get_visual_instance_rid() const {
|
|||
|
||||
void VisualInstance::set_layer_mask(uint32_t p_mask) {
|
||||
|
||||
layers=p_mask;
|
||||
VisualServer::get_singleton()->instance_set_layer_mask(instance,p_mask);
|
||||
layers = p_mask;
|
||||
VisualServer::get_singleton()->instance_set_layer_mask(instance, p_mask);
|
||||
}
|
||||
|
||||
uint32_t VisualInstance::get_layer_mask() const {
|
||||
|
|
@ -120,75 +115,61 @@ uint32_t VisualInstance::get_layer_mask() const {
|
|||
return layers;
|
||||
}
|
||||
|
||||
|
||||
void VisualInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_get_visual_instance_rid"),&VisualInstance::_get_visual_instance_rid);
|
||||
ObjectTypeDB::bind_method(_MD("set_base","base"), &VisualInstance::set_base);
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"), &VisualInstance::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid);
|
||||
ObjectTypeDB::bind_method(_MD("set_base", "base"), &VisualInstance::set_base);
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_mask", "mask"), &VisualInstance::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"), &VisualInstance::get_layer_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_transformed_aabb"), &VisualInstance::get_transformed_aabb);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "layers",PROPERTY_HINT_ALL_FLAGS), _SCS("set_layer_mask"), _SCS("get_layer_mask"));
|
||||
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_ALL_FLAGS), _SCS("set_layer_mask"), _SCS("get_layer_mask"));
|
||||
}
|
||||
|
||||
void VisualInstance::set_base(const RID &p_base) {
|
||||
|
||||
void VisualInstance::set_base(const RID& p_base) {
|
||||
|
||||
VisualServer::get_singleton()->instance_set_base(instance,p_base);
|
||||
VisualServer::get_singleton()->instance_set_base(instance, p_base);
|
||||
}
|
||||
|
||||
|
||||
VisualInstance::VisualInstance()
|
||||
{
|
||||
VisualInstance::VisualInstance() {
|
||||
|
||||
instance = VisualServer::get_singleton()->instance_create();
|
||||
VisualServer::get_singleton()->instance_attach_object_instance_ID( instance, get_instance_ID() );
|
||||
layers=1;
|
||||
VisualServer::get_singleton()->instance_attach_object_instance_ID(instance, get_instance_ID());
|
||||
layers = 1;
|
||||
}
|
||||
|
||||
|
||||
VisualInstance::~VisualInstance() {
|
||||
|
||||
VisualServer::get_singleton()->free(instance);
|
||||
}
|
||||
|
||||
void GeometryInstance::set_material_override(const Ref<Material> &p_material) {
|
||||
|
||||
|
||||
|
||||
void GeometryInstance::set_material_override(const Ref<Material>& p_material) {
|
||||
|
||||
material_override=p_material;
|
||||
VS::get_singleton()->instance_geometry_set_material_override(get_instance(),p_material.is_valid() ? p_material->get_rid() : RID());
|
||||
material_override = p_material;
|
||||
VS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID());
|
||||
}
|
||||
|
||||
Ref<Material> GeometryInstance::get_material_override() const{
|
||||
Ref<Material> GeometryInstance::get_material_override() const {
|
||||
|
||||
return material_override;
|
||||
}
|
||||
|
||||
void GeometryInstance::set_draw_range_begin(float p_dist) {
|
||||
|
||||
|
||||
void GeometryInstance::set_draw_range_begin(float p_dist){
|
||||
|
||||
draw_begin=p_dist;
|
||||
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end);
|
||||
draw_begin = p_dist;
|
||||
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(), draw_begin, draw_end);
|
||||
}
|
||||
|
||||
float GeometryInstance::get_draw_range_begin() const{
|
||||
float GeometryInstance::get_draw_range_begin() const {
|
||||
|
||||
return draw_begin;
|
||||
}
|
||||
|
||||
|
||||
void GeometryInstance::set_draw_range_end(float p_dist) {
|
||||
|
||||
draw_end=p_dist;
|
||||
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end);
|
||||
|
||||
draw_end = p_dist;
|
||||
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(), draw_begin, draw_end);
|
||||
}
|
||||
|
||||
float GeometryInstance::get_draw_range_end() const {
|
||||
|
|
@ -198,7 +179,7 @@ float GeometryInstance::get_draw_range_end() const {
|
|||
|
||||
void GeometryInstance::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_WORLD) {
|
||||
if (p_what == NOTIFICATION_ENTER_WORLD) {
|
||||
|
||||
if (flags[FLAG_USE_BAKED_LIGHT]) {
|
||||
|
||||
|
|
@ -207,51 +188,47 @@ void GeometryInstance::_notification(int p_what) {
|
|||
|
||||
_update_visibility();
|
||||
|
||||
} else if (p_what==NOTIFICATION_EXIT_WORLD) {
|
||||
} else if (p_what == NOTIFICATION_EXIT_WORLD) {
|
||||
|
||||
if (flags[FLAG_USE_BAKED_LIGHT]) {
|
||||
|
||||
if (baked_light_instance) {
|
||||
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
baked_light_instance=NULL;
|
||||
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed, this, SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
baked_light_instance = NULL;
|
||||
}
|
||||
_baked_light_changed();
|
||||
|
||||
}
|
||||
|
||||
} if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
}
|
||||
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
|
||||
_update_visibility();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GeometryInstance::_baked_light_changed() {
|
||||
|
||||
if (!baked_light_instance)
|
||||
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
|
||||
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(), RID());
|
||||
else
|
||||
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
|
||||
|
||||
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(), baked_light_instance->get_baked_light_instance());
|
||||
}
|
||||
|
||||
void GeometryInstance::_find_baked_light() {
|
||||
|
||||
Node *n=get_parent();
|
||||
while(n) {
|
||||
Node *n = get_parent();
|
||||
while (n) {
|
||||
|
||||
BakedLightInstance *bl=n->cast_to<BakedLightInstance>();
|
||||
BakedLightInstance *bl = n->cast_to<BakedLightInstance>();
|
||||
if (bl) {
|
||||
|
||||
baked_light_instance=bl;
|
||||
baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
baked_light_instance = bl;
|
||||
baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed, this, SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
_baked_light_changed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
n=n->get_parent();
|
||||
n = n->get_parent();
|
||||
}
|
||||
|
||||
_baked_light_changed();
|
||||
|
|
@ -263,36 +240,35 @@ void GeometryInstance::_update_visibility() {
|
|||
return;
|
||||
|
||||
_change_notify("geometry/visible");
|
||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(),VS::INSTANCE_FLAG_VISIBLE,is_visible() && flags[FLAG_VISIBLE]);
|
||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_VISIBLE, is_visible() && flags[FLAG_VISIBLE]);
|
||||
}
|
||||
|
||||
void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
|
||||
void GeometryInstance::set_flag(Flags p_flag, bool p_value) {
|
||||
|
||||
ERR_FAIL_INDEX(p_flag,FLAG_MAX);
|
||||
if (p_flag==FLAG_CAST_SHADOW) {
|
||||
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
|
||||
if (p_flag == FLAG_CAST_SHADOW) {
|
||||
if (p_value == true) {
|
||||
set_cast_shadows_setting(SHADOW_CASTING_SETTING_ON);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
set_cast_shadows_setting(SHADOW_CASTING_SETTING_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags[p_flag]==p_value)
|
||||
if (flags[p_flag] == p_value)
|
||||
return;
|
||||
|
||||
flags[p_flag]=p_value;
|
||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(),(VS::InstanceFlags)p_flag,p_value);
|
||||
if (p_flag==FLAG_VISIBLE) {
|
||||
flags[p_flag] = p_value;
|
||||
VS::get_singleton()->instance_geometry_set_flag(get_instance(), (VS::InstanceFlags)p_flag, p_value);
|
||||
if (p_flag == FLAG_VISIBLE) {
|
||||
_update_visibility();
|
||||
}
|
||||
if (p_flag==FLAG_USE_BAKED_LIGHT) {
|
||||
if (p_flag == FLAG_USE_BAKED_LIGHT) {
|
||||
|
||||
if (is_inside_world()) {
|
||||
if (!p_value) {
|
||||
if (baked_light_instance) {
|
||||
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
baked_light_instance=NULL;
|
||||
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed, this, SceneStringNames::get_singleton()->_baked_light_changed);
|
||||
baked_light_instance = NULL;
|
||||
}
|
||||
_baked_light_changed();
|
||||
} else {
|
||||
|
|
@ -302,21 +278,19 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
|
|||
}
|
||||
}
|
||||
|
||||
bool GeometryInstance::get_flag(Flags p_flag) const{
|
||||
bool GeometryInstance::get_flag(Flags p_flag) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
|
||||
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
|
||||
|
||||
if (p_flag == FLAG_CAST_SHADOW) {
|
||||
if (shadow_casting_setting == SHADOW_CASTING_SETTING_OFF) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return flags[p_flag];
|
||||
|
||||
}
|
||||
|
||||
void GeometryInstance::set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting) {
|
||||
|
|
@ -333,102 +307,98 @@ GeometryInstance::ShadowCastingSetting GeometryInstance::get_cast_shadows_settin
|
|||
|
||||
void GeometryInstance::set_baked_light_texture_id(int p_id) {
|
||||
|
||||
baked_light_texture_id=p_id;
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),baked_light_texture_id);
|
||||
|
||||
baked_light_texture_id = p_id;
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(), baked_light_texture_id);
|
||||
}
|
||||
|
||||
int GeometryInstance::get_baked_light_texture_id() const{
|
||||
int GeometryInstance::get_baked_light_texture_id() const {
|
||||
|
||||
return baked_light_texture_id;
|
||||
}
|
||||
|
||||
void GeometryInstance::set_extra_cull_margin(float p_margin) {
|
||||
|
||||
ERR_FAIL_COND(p_margin<0);
|
||||
extra_cull_margin=p_margin;
|
||||
VS::get_singleton()->instance_set_extra_visibility_margin(get_instance(),extra_cull_margin);
|
||||
ERR_FAIL_COND(p_margin < 0);
|
||||
extra_cull_margin = p_margin;
|
||||
VS::get_singleton()->instance_set_extra_visibility_margin(get_instance(), extra_cull_margin);
|
||||
}
|
||||
|
||||
float GeometryInstance::get_extra_cull_margin() const{
|
||||
float GeometryInstance::get_extra_cull_margin() const {
|
||||
|
||||
return extra_cull_margin;
|
||||
}
|
||||
|
||||
void GeometryInstance::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_material_override","material"), &GeometryInstance::set_material_override);
|
||||
ObjectTypeDB::bind_method(_MD("set_material_override", "material"), &GeometryInstance::set_material_override);
|
||||
ObjectTypeDB::bind_method(_MD("get_material_override"), &GeometryInstance::get_material_override);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_flag","flag","value"), &GeometryInstance::set_flag);
|
||||
ObjectTypeDB::bind_method(_MD("get_flag","flag"), &GeometryInstance::get_flag);
|
||||
ObjectTypeDB::bind_method(_MD("set_flag", "flag", "value"), &GeometryInstance::set_flag);
|
||||
ObjectTypeDB::bind_method(_MD("get_flag", "flag"), &GeometryInstance::get_flag);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance::set_cast_shadows_setting);
|
||||
ObjectTypeDB::bind_method(_MD("get_cast_shadows_setting"), &GeometryInstance::get_cast_shadows_setting);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_range_begin","mode"), &GeometryInstance::set_draw_range_begin);
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_range_begin", "mode"), &GeometryInstance::set_draw_range_begin);
|
||||
ObjectTypeDB::bind_method(_MD("get_draw_range_begin"), &GeometryInstance::get_draw_range_begin);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_range_end","mode"), &GeometryInstance::set_draw_range_end);
|
||||
ObjectTypeDB::bind_method(_MD("set_draw_range_end", "mode"), &GeometryInstance::set_draw_range_end);
|
||||
ObjectTypeDB::bind_method(_MD("get_draw_range_end"), &GeometryInstance::get_draw_range_end);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id);
|
||||
ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id", "id"), &GeometryInstance::set_baked_light_texture_id);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin);
|
||||
ObjectTypeDB::bind_method(_MD("set_extra_cull_margin", "margin"), &GeometryInstance::set_extra_cull_margin);
|
||||
ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"),&GeometryInstance::get_aabb);
|
||||
ObjectTypeDB::bind_method(_MD("get_aabb"), &GeometryInstance::get_aabb);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"), FLAG_VISIBLE);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "geometry/material_override", PROPERTY_HINT_RESOURCE_TYPE, "Material"), _SCS("set_material_override"), _SCS("get_material_override"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), _SCS("set_cast_shadows_setting"), _SCS("get_cast_shadows_setting"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE_IN_ALL_ROOMS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"),FLAG_USE_BAKED_LIGHT);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/baked_light_tex_id"), _SCS("set_baked_light_texture_id"), _SCS("get_baked_light_texture_id"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"), FLAG_RECEIVE_SHADOWS);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/range_begin", PROPERTY_HINT_RANGE, "0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/range_end", PROPERTY_HINT_RANGE, "0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "geometry/extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin"));
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"), FLAG_BILLBOARD);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"), FLAG_BILLBOARD_FIX_Y);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"), FLAG_DEPH_SCALE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"), FLAG_VISIBLE_IN_ALL_ROOMS);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"), FLAG_USE_BAKED_LIGHT);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/baked_light_tex_id"), _SCS("set_baked_light_texture_id"), _SCS("get_baked_light_texture_id"));
|
||||
|
||||
// ADD_SIGNAL( MethodInfo("visibility_changed"));
|
||||
// ADD_SIGNAL( MethodInfo("visibility_changed"));
|
||||
|
||||
BIND_CONSTANT(FLAG_VISIBLE );
|
||||
BIND_CONSTANT(FLAG_CAST_SHADOW );
|
||||
BIND_CONSTANT(FLAG_RECEIVE_SHADOWS );
|
||||
BIND_CONSTANT(FLAG_BILLBOARD );
|
||||
BIND_CONSTANT(FLAG_BILLBOARD_FIX_Y );
|
||||
BIND_CONSTANT(FLAG_DEPH_SCALE );
|
||||
BIND_CONSTANT(FLAG_VISIBLE_IN_ALL_ROOMS );
|
||||
BIND_CONSTANT(FLAG_MAX );
|
||||
BIND_CONSTANT(FLAG_VISIBLE);
|
||||
BIND_CONSTANT(FLAG_CAST_SHADOW);
|
||||
BIND_CONSTANT(FLAG_RECEIVE_SHADOWS);
|
||||
BIND_CONSTANT(FLAG_BILLBOARD);
|
||||
BIND_CONSTANT(FLAG_BILLBOARD_FIX_Y);
|
||||
BIND_CONSTANT(FLAG_DEPH_SCALE);
|
||||
BIND_CONSTANT(FLAG_VISIBLE_IN_ALL_ROOMS);
|
||||
BIND_CONSTANT(FLAG_MAX);
|
||||
|
||||
BIND_CONSTANT(SHADOW_CASTING_SETTING_OFF);
|
||||
BIND_CONSTANT(SHADOW_CASTING_SETTING_ON);
|
||||
BIND_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED);
|
||||
BIND_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
|
||||
|
||||
}
|
||||
|
||||
GeometryInstance::GeometryInstance() {
|
||||
draw_begin=0;
|
||||
draw_end=0;
|
||||
for(int i=0;i<FLAG_MAX;i++) {
|
||||
flags[i]=false;
|
||||
draw_begin = 0;
|
||||
draw_end = 0;
|
||||
for (int i = 0; i < FLAG_MAX; i++) {
|
||||
flags[i] = false;
|
||||
}
|
||||
|
||||
flags[FLAG_VISIBLE]=true;
|
||||
flags[FLAG_CAST_SHADOW]=true;
|
||||
flags[FLAG_RECEIVE_SHADOWS]=true;
|
||||
shadow_casting_setting=SHADOW_CASTING_SETTING_ON;
|
||||
baked_light_instance=NULL;
|
||||
baked_light_texture_id=0;
|
||||
extra_cull_margin=0;
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
|
||||
|
||||
|
||||
flags[FLAG_VISIBLE] = true;
|
||||
flags[FLAG_CAST_SHADOW] = true;
|
||||
flags[FLAG_RECEIVE_SHADOWS] = true;
|
||||
shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
|
||||
baked_light_instance = NULL;
|
||||
baked_light_texture_id = 0;
|
||||
extra_cull_margin = 0;
|
||||
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(), 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,84 +29,77 @@
|
|||
#ifndef VISUAL_INSTANCE_H
|
||||
#define VISUAL_INSTANCE_H
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "face3.h"
|
||||
#include "rid.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/resources/material.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class VisualInstance : public Spatial {
|
||||
|
||||
OBJ_TYPE( VisualInstance, Spatial );
|
||||
OBJ_TYPE(VisualInstance, Spatial);
|
||||
OBJ_CATEGORY("3D Visual Nodes");
|
||||
|
||||
RID instance;
|
||||
uint32_t layers;
|
||||
|
||||
|
||||
RID _get_visual_instance_rid() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
public:
|
||||
enum GetFacesFlags {
|
||||
FACES_SOLID=1, // solid geometry
|
||||
FACES_ENCLOSING=2,
|
||||
FACES_DYNAMIC=4 // dynamic object geometry
|
||||
FACES_SOLID = 1, // solid geometry
|
||||
FACES_ENCLOSING = 2,
|
||||
FACES_DYNAMIC = 4 // dynamic object geometry
|
||||
|
||||
};
|
||||
|
||||
RID get_instance() const;
|
||||
virtual AABB get_aabb() const=0;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const=0;
|
||||
virtual AABB get_aabb() const = 0;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const = 0;
|
||||
|
||||
virtual AABB get_transformed_aabb() const; // helper
|
||||
|
||||
void set_base(const RID& p_base);
|
||||
void set_base(const RID &p_base);
|
||||
|
||||
void set_layer_mask(uint32_t p_mask);
|
||||
uint32_t get_layer_mask() const;
|
||||
|
||||
|
||||
VisualInstance();
|
||||
~VisualInstance();
|
||||
|
||||
};
|
||||
|
||||
class BakedLightInstance;
|
||||
|
||||
class GeometryInstance : public VisualInstance {
|
||||
|
||||
OBJ_TYPE( GeometryInstance, VisualInstance );
|
||||
public:
|
||||
OBJ_TYPE(GeometryInstance, VisualInstance);
|
||||
|
||||
public:
|
||||
enum Flags {
|
||||
FLAG_VISIBLE=VS::INSTANCE_FLAG_VISIBLE,
|
||||
FLAG_CAST_SHADOW=VS::INSTANCE_FLAG_CAST_SHADOW,
|
||||
FLAG_RECEIVE_SHADOWS=VS::INSTANCE_FLAG_RECEIVE_SHADOWS,
|
||||
FLAG_BILLBOARD=VS::INSTANCE_FLAG_BILLBOARD,
|
||||
FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
|
||||
FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE,
|
||||
FLAG_VISIBLE_IN_ALL_ROOMS=VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
|
||||
FLAG_USE_BAKED_LIGHT=VS::INSTANCE_FLAG_USE_BAKED_LIGHT,
|
||||
FLAG_MAX=VS::INSTANCE_FLAG_MAX,
|
||||
FLAG_VISIBLE = VS::INSTANCE_FLAG_VISIBLE,
|
||||
FLAG_CAST_SHADOW = VS::INSTANCE_FLAG_CAST_SHADOW,
|
||||
FLAG_RECEIVE_SHADOWS = VS::INSTANCE_FLAG_RECEIVE_SHADOWS,
|
||||
FLAG_BILLBOARD = VS::INSTANCE_FLAG_BILLBOARD,
|
||||
FLAG_BILLBOARD_FIX_Y = VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
|
||||
FLAG_DEPH_SCALE = VS::INSTANCE_FLAG_DEPH_SCALE,
|
||||
FLAG_VISIBLE_IN_ALL_ROOMS = VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
|
||||
FLAG_USE_BAKED_LIGHT = VS::INSTANCE_FLAG_USE_BAKED_LIGHT,
|
||||
FLAG_MAX = VS::INSTANCE_FLAG_MAX,
|
||||
};
|
||||
|
||||
enum ShadowCastingSetting {
|
||||
SHADOW_CASTING_SETTING_OFF=VS::SHADOW_CASTING_SETTING_OFF,
|
||||
SHADOW_CASTING_SETTING_OFF = VS::SHADOW_CASTING_SETTING_OFF,
|
||||
SHADOW_CASTING_SETTING_ON = VS::SHADOW_CASTING_SETTING_ON,
|
||||
SHADOW_CASTING_SETTING_DOUBLE_SIDED=VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED,
|
||||
SHADOW_CASTING_SETTING_SHADOWS_ONLY=VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY
|
||||
SHADOW_CASTING_SETTING_DOUBLE_SIDED = VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED,
|
||||
SHADOW_CASTING_SETTING_SHADOWS_ONLY = VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool flags[FLAG_MAX];
|
||||
ShadowCastingSetting shadow_casting_setting;
|
||||
Ref<Material> material_override;
|
||||
|
|
@ -119,13 +112,13 @@ private:
|
|||
|
||||
void _baked_light_changed();
|
||||
void _update_visibility();
|
||||
protected:
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_flag(Flags p_flag,bool p_value);
|
||||
public:
|
||||
void set_flag(Flags p_flag, bool p_value);
|
||||
bool get_flag(Flags p_flag) const;
|
||||
|
||||
void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);
|
||||
|
|
@ -137,7 +130,7 @@ public:
|
|||
void set_draw_range_end(float p_dist);
|
||||
float get_draw_range_end() const;
|
||||
|
||||
void set_material_override(const Ref<Material>& p_material);
|
||||
void set_material_override(const Ref<Material> &p_material);
|
||||
Ref<Material> get_material_override() const;
|
||||
|
||||
void set_baked_light_texture_id(int p_id);
|
||||
|
|
@ -149,8 +142,7 @@ public:
|
|||
GeometryInstance();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST( GeometryInstance::Flags );
|
||||
VARIANT_ENUM_CAST( GeometryInstance::ShadowCastingSetting );
|
||||
|
||||
VARIANT_ENUM_CAST(GeometryInstance::Flags);
|
||||
VARIANT_ENUM_CAST(GeometryInstance::ShadowCastingSetting);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue