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:
Rémi Verschelde 2017-03-19 00:36:26 +01:00
parent 1d418afe86
commit f8db8a3faa
1308 changed files with 147754 additions and 174357 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -237,7 +237,6 @@ void CharacterCamera::_compute_camera() {
new_pos = character_pos + rel_n * l;
#endif
follow_pos=new_pos;

View file

@ -29,7 +29,6 @@
#ifndef CHARACTER_CAMERA_H
#define CHARACTER_CAMERA_H
#include "scene/3d/camera.h"
#if 0
class CharacterCamera : public Camera {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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