ENIGMA Forums

Contributing to ENIGMA => Function Peer Review => Topic started by: IsmAvatar on January 07, 2011, 04:05:11 pm

Title: move_towards_point
Post by: IsmAvatar on January 07, 2011, 04:05:11 pm
Code: (C++) [Select]
void motion_set(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->direction.rval.d = newdir;
  inst->speed.rval.d = newspd;
  inst->hspeed.rval.d = newspd * cos(newdir);
  inst->vspeed.rval.d = newspd * sin(newdir);
}

inline void move_towards_point(double x, double y, double spd) {
  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);
}

motion_set was borrowed from action_move (http://enigma-dev.org/forums/index.php?topic=667.0). It's just used as a convenience method to set both speed and direction efficiently. There have been some concerns over radians vs. degrees, and I haven't looked into them fully, but oddly enough action_move seemed to work...
Title: Re: move_towards_point
Post by: RetroX on January 07, 2011, 04:10:44 pm
In addition, motion_add:
Code: (C++) [Select]
void motion_add(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->hspeed.rval.d += newspd * cos(newdir);
  inst->vspeed.rval.d += newspd * sin(newdir);
  inst->direction.rval.d = point_direction(0, 0, inst->hspeed.rval.d, inst->vspeed.rval.d);
  inst->speed.rval.d = abs(hypot(inst->hspeed.rval.d, inst->vspeed.rval.d));
}

Untested, but it's mathematically sound.
Title: Re: move_towards_point
Post by: RetroX on January 07, 2011, 10:11:30 pm
Also, random thing to mention, but:
Code: (C++) [Select]
void motion_set(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->direction.rval.d = newdir;
  inst->speed.rval.d = newspd;
  inst->hspeed.rval.d = newspd * cos(newdir);
  inst->vspeed.rval.d = newspd * sin(newdir);
}

inline void move_towards_point(double x, double y, double spd) {
  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);
}

void motion_add(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->hspeed.rval.d += newspd * cos(newdir);
  inst->vspeed.rval.d += newspd * sin(newdir);
  inst->direction.rval.d = point_direction(0, 0, inst->hspeed.rval.d, inst->vspeed.rval.d);
  inst->speed.rval.d = abs(hypot(inst->hspeed.rval.d, inst->vspeed.rval.d));
}
Title: Re: move_towards_point
Post by: serprex on January 08, 2011, 02:55:22 pm
No, they shouldn't
Title: Re: move_towards_point
Post by: RetroX on January 08, 2011, 05:34:03 pm
move_towards_point should be inline, at least. :V
Title: Re: move_towards_point
Post by: Fede-lasse on January 09, 2011, 09:41:40 am
I think also did this one (move_towards_point). Is anyone actually reading this?
Title: Re: move_towards_point
Post by: RetroX on January 09, 2011, 06:22:56 pm
I think also did this one (move_towards_point). Is anyone actually reading this?
In GML, not C++.
Title: Re: move_towards_point
Post by: Fede-lasse on January 10, 2011, 02:57:58 am
EDL :eng101:
Title: Re: move_towards_point
Post by: MrGriggs on January 11, 2011, 03:44:14 am
Also, random thing to mention, but:
Code: (C++) [Select]
void motion_set(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->direction.rval.d = newdir;
  inst->speed.rval.d = newspd;
  inst->hspeed.rval.d = newspd * cos(newdir);
  inst->vspeed.rval.d = newspd * sin(newdir);
}

inline void move_towards_point(double x, double y, double spd) {
  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);
}

void motion_add(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->hspeed.rval.d += newspd * cos(newdir);
  inst->vspeed.rval.d += newspd * sin(newdir);
  inst->direction.rval.d = point_direction(0, 0, inst->hspeed.rval.d, inst->vspeed.rval.d);
  inst->speed.rval.d = abs(hypot(inst->hspeed.rval.d, inst->vspeed.rval.d));
}

Tried to use move towards point from this, and my word it's CRAAAAAAAZZZZZZYYYY, have you tested it?
Title: Re: move_towards_point
Post by: r9k on January 11, 2011, 08:43:15 am
Probably because hes giving a non radian angle to sin and cos.
Title: Re: move_towards_point
Post by: RetroX on January 11, 2011, 04:14:14 pm
Yeah, it is.  Updated:
Code: [Select]
void motion_set(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->direction.rval.d = newdir;
  inst->speed.rval.d = newspd;
  inst->hspeed.rval.d = newspd * cos(degtorad(newdir));
  inst->vspeed.rval.d = newspd * sin(degtorad(newdir));
}

inline void move_towards_point(double x, double y, double spd) {
  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);
}

void motion_add(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->hspeed.rval.d += newspd * cos(degtorad(newdir));
  inst->vspeed.rval.d += newspd * sin(degtorad(newdir));
  inst->direction.rval.d = point_direction(0, 0, inst->hspeed.rval.d, inst->vspeed.rval.d);
  inst->speed.rval.d = abs(hypot(inst->hspeed.rval.d, inst->vspeed.rval.d));
}

Suggestion: point_direction_radians
Title: Re: move_towards_point
Post by: polygone on January 11, 2011, 04:18:44 pm
Quoting Ism:
Quote
There have been some concerns over radians vs. degrees, and I haven't looked into them fully, but oddly enough action_move seemed to work...

Because of the way rval.d works, the code is correct without degtorad. This got me too.
Title: Re: move_towards_point
Post by: RetroX on January 11, 2011, 04:49:46 pm
oh, well, ignore what I posted, then
Title: Re: move_towards_point
Post by: Josh @ Dreamland on January 11, 2011, 07:16:55 pm
Actually, I have no idea why the fuck Ism's implementation works. direction.rval.d is in degrees. Or at least it's supposed to be. There is the possibility that it is only in degrees when it is the last variable set.
Title: Re: move_towards_point
Post by: MrGriggs on January 12, 2011, 04:22:36 am
Have any of these been tested and found to function as desired?
Title: Re: move_towards_point
Post by: RetroX on January 12, 2011, 08:24:59 am
Nope. :P
Title: Re: move_towards_point
Post by: polygone on January 12, 2011, 12:34:30 pm
Actually, I have no idea why the fuck Ism's implementation works. direction.rval.d is in degrees. Or at least it's supposed to be. There is the possibility that it is only in degrees when it is the last variable set.
Funny you said that to me when I mentioned it. But then Ism quite rightly pointed out that you were actually the one who used that code first:

I'm actually too tired and lazy right now to do the trivial amount of text insertion required to put that to code. >.<

-sigh-

Code: (C++) [Select]
const double dir = ((enigma::object_planar*)enigma::instance_event_iterator->inst)->direction.dval = chosendirs[choices];
((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed.dval = chosendirs[choices] == -1 ? 0 : argspeed;
hspeed.dval = speed.dval * cos(dir), vspeed.dval = speed.dval * sin(dir);

Assuming all the rest of your code is right, and that I'm remembering the name of my own class member correctly.
She doesn't know why the fuck it works either
Title: Re: move_towards_point
Post by: MrGriggs on January 14, 2011, 08:10:35 pm
All of these make it run away from the position rather than move towards as it's supposed to.

Here's a corrected version.
Code: [Select]
void motion_set(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->direction.rval.d = newdir;
  inst->speed.rval.d = newspd;
  inst->hspeed.rval.d = newspd * cos(degtorad(newdir));
  inst->vspeed.rval.d = -newspd * sin(degtorad(newdir));
}

inline void move_towards_point(double x, double y, double spd) {
  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);
}

void motion_add(double newdir, double newspd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  inst->hspeed.rval.d += newspd * cos(degtorad(newdir));
  inst->vspeed.rval.d += newspd * sin(degtorad(newdir));
  inst->direction.rval.d = point_direction(0, 0, inst->hspeed.rval.d, inst->vspeed.rval.d);
  inst->speed.rval.d = abs(hypot(inst->hspeed.rval.d, inst->vspeed.rval.d));
}



"inst->vspeed.rval.d = -newspd * sin(degtorad(newdir));"

making it negative corrects the issue. :)
Title: Re: move_towards_point
Post by: MrGriggs on January 20, 2011, 12:54:02 pm
Code: [Select]
inline void move_point_stop(double x, double y, double spd) {

    enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
    if (inst->x==x && inst->y==y)
return void;
else
{

  motion_set(point_direction(
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
    ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
    x,y),spd);

}



}




How do you like these apples? Or are they dysfunctional apples?
Title: Re: move_towards_point
Post by: IsmAvatar on January 20, 2011, 02:05:35 pm
When you introduce the inst variable, you shouldn't keep it inline anymore I don't think, and it's redundant to return void to a void returning function. Also, indentation. This would be more likely:

Code: (C++) [Select]
void move_point_stop(double x, double y, double spd) {
  enigma::object_planar* const inst = ((enigma::object_planar*)enigma::instance_event_iterator->inst);
  if (inst->x!=x || inst->y!=y)
    motion_set(point_direction(inst->x,inst->y,x,y),spd);
}

Or this:
Code: (C++) [Select]
inline void move_point_stop(double x, double y, double spd) {
  if (((enigma::object_planar*)enigma::instance_event_iterator->inst)->x!=x
  ||  ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y!=y)
    motion_set(point_direction(
      ((enigma::object_planar*)enigma::instance_event_iterator->inst)->x,
      ((enigma::object_planar*)enigma::instance_event_iterator->inst)->y,
      x,y),spd);
}

In addition, this doesn't stop when it has reached the point. It only ceases to set the motion. Recall that an object in motion continues to stay in motion until acted upon.

Append this prior to the last closing curly brace:
Code: (C++) [Select]
else ((enigma::object_planar*)enigma::instance_event_iterator->inst)->speed = 0;Or if you already have inst defined:
Code: (C++) [Select]
else inst->speed = 0;
Title: Re: move_towards_point
Post by: MrGriggs on January 21, 2011, 06:36:09 am
Ah yeah, I forgot hspeed and vspeed doesn't cease until instructed to.
Title: Re: move_towards_point
Post by: Fede-lasse on January 21, 2011, 10:44:44 am
Ugh.
Title: Re: move_towards_point
Post by: MrGriggs on January 24, 2011, 04:21:05 am
Ugh.
You've done this in EDL, already?

It needs to be done in C++ so that it can be compiled directly into ENIGMA though, doesn't it?  :v:
Title: Re: move_towards_point
Post by: MrGriggs on January 24, 2011, 04:24:12 am
Another thought, isn't it best if the functions don't use other function to complete their tasks, as when the time comes to allow the user to remove particular functions from instances and checks, removing something such as motion_set but not move_towards_point then using the latter, will cause issues for the user, and they probably will have no idea what the issue is...
Title: Re: move_towards_point
Post by: Fede-lasse on January 24, 2011, 09:50:10 am
GML scripts allowed?
If they work when added as a function in Whitespace, or are really worth porting, I don't see why not.
I already sent it to Josh but I'm not even sure he still has it.
Title: Re: move_towards_point
Post by: MrGriggs on January 24, 2011, 11:47:20 am
Oh ok, that's good then. Shouldn't your version have been implemented already then?

Also, about my other post, you have any answers for that?  ???
Title: Re: move_towards_point
Post by: IsmAvatar on January 24, 2011, 12:13:44 pm
I don't see a reason to disable motion_set while keeping move_towards_point. It seems to me that if you want to disable one, you'll want to disable the other as well (e.g. bulk removal of motion-related functions). That said, if you still wanted to disable motion_set but keep move_towards_point, you might be able to set motion_set to be private access, so that it's not visible to outside files (this might just be Java rubbing off on me)... but there's not much use in that, because the function is still there, it's just not visible anymore - in which case you might as well just keep the function and not use it. Point is, move_towards_point needs motion_set one way or the other, whether it's in a function called motion_set, or unrolled. The benefit of using motion_set is that it eliminates duplicate code.
Title: Re: move_towards_point
Post by: RetroX on January 24, 2011, 04:49:03 pm
IsmAvatar - C++ doesn't allow setting access to globals.  All globals are public.  Only members of structs and classes can be set with access specifiers.

What could be done is merely not including the code for that header in the game, or just not linking the object.  If the header provides a declaration and no implementation is provided, it will still compile as long as the function isn't being used.  Alternatively, you can add these flags to the GCC:
-fdata-sections -ffunction-sections
which compiles everything into separate sections in the actual object, and:
-Wl,-gc-sections
which will remove unused sections from the program upon linking.

On that matter, for debugging purposes, it would be nice to be able to add -g -O0, which will provide C++ debugging symbols, which GDB can use.  It's extraordinarily useful.
Title: Re: move_towards_point
Post by: Fede-lasse on January 25, 2011, 04:54:29 am
Oh ok, that's good then. Shouldn't your version have been implemented already then?
Yes, it should. Damn Josh >: |. But I guess you guys could do it better either way. I can program in ActionScript 3.0 and C# but I dunno if that's of any use.
Title: Re: move_towards_point
Post by: MrGriggs on January 25, 2011, 05:26:51 am
C# is pretty similar in many ways, but in many ways it also is not. Action Script is compleeeetely different in my opinion, i HATE the syntax of it, it's so backward (my opinion).

Maybe there's justification for the backward syntax, but i haven't looked into it, if you use it, i'm sure it has it's uses.
Title: Re: move_towards_point
Post by: Josh @ Dreamland on January 25, 2011, 08:41:43 am
A motion_set that's five lines in GML isn't really worth porting. Those kinds of functions are more like blueprints or suggestions than code. It doesn't help me if you just take advantage of ENIGMA's scoping system to do things that are a pain in the ass in plain, general C++.

Though, with the new instance system, they're now much easier to produce.
Title: Re: move_towards_point
Post by: MrGriggs on January 25, 2011, 09:06:37 am
I would've thought writing code in GML for functions would add to the compile time, though. Or does it only need to be coverted once?
Title: Re: move_towards_point
Post by: RetroX on January 26, 2011, 04:55:49 pm
GML functions are slower in nature because they use var.  But compared to the speed of GM, it's already loads faster anyways.

Besides, if you code something in GML, post it here, and someone will likely be able to convert it to C++ for you.
Title: Re: move_towards_point
Post by: MrGriggs on January 27, 2011, 05:58:44 am
Slow how? Takes more processing during run time? I thought the code was parsed straight to C++ at compile anyways? Or do you mean because of GML not being definitive in its types that it takes more memory?

So my initial thought was right anyways, that it's best to write the functions within C++ with the instance interator for Josh so that it doesn't have to be parsed during compile?
Title: Re: move_towards_point
Post by: RetroX on January 27, 2011, 01:10:10 pm
Well, basic integers are handled quickly by the processor.  var has to check, at every calculation, what variable type is being used and how to handle it.  It's not a huge notice, but if you take an entire project and convert it from var to primitive types, you'll see a relatively decent increase in speed.
Title: Re: move_towards_point
Post by: Fede-lasse on January 27, 2011, 03:45:59 pm
Besides, if you code something in GML, post it here, and someone will likely be able to convert it to C++ for you.
I did!
Title: Re: move_towards_point
Post by: Josh @ Dreamland on January 28, 2011, 12:54:16 am
with (obj) direction=dir, speed=spd; isn't worth porting, considering the corresponding C++ is completely different.
Title: Re: move_towards_point
Post by: MrGriggs on January 28, 2011, 04:50:07 am
Well, basic integers are handled quickly by the processor.  var has to check, at every calculation, what variable type is being used and how to handle it.  It's not a huge notice, but if you take an entire project and convert it from var to primitive types, you'll see a relatively decent increase in speed.

Will defining our types before using them increase the speed at all, for example

int varname
string strname

so on and so forth.

To get the boost will we also have to include the variable type in the if statements and other such checks when referncing the varname
?
Title: Re: move_towards_point
Post by: TheExDeus on January 28, 2011, 05:27:17 am
Quote
Will defining our types before using them increase the speed at all, for example
Of course. The biggest speed increase is in for cycles like
Code: [Select]
for (int i=0; i<10000000; i++){}will work A LOT faster than
Code: [Select]
for (i=0; i<10000000; i++){}
Quote
To get the boost will we also have to include the variable type in the if statements and other such checks when referncing the varname
?
No, in c++ you have to set the type only when declaring them. When used in if checks and so on the type doesn't need to be set again. Unless you want to cast them as another type, like:
Code: [Select]
double d=1.23;
int i=1;
if ((int)d == i){}
Dunno if ENIGMA allows this right now, but I also never really saw the reason to do that (unless in coding in c++ where functions can take only certain types of varaibles).
Title: Re: move_towards_point
Post by: MrGriggs on January 28, 2011, 05:59:43 am
Yeah, I know how C++ works, I just didn't know if the way ENIGMA compiled it would cause me to have to do this, thanks for clearing that up :)
Title: Re: move_towards_point
Post by: Josh @ Dreamland on January 28, 2011, 08:21:07 am
Indeed. I've managed to make variant work as fast as double, but double is still slower than int. Granted, they are hundreds (int thousands) of times faster than Game Maker, but best practice is to declare them. local int varname; will take care of all your woes.

You can stick a cast anywhere in an expression you like in ENIGMA. Just like ++, or !. Casts are just another unary operator.
Title: Re: move_towards_point
Post by: MrGriggs on January 28, 2011, 09:40:55 am
But the .gmk that declares the data types won't work with GM as well wil it? As GM does not allow type casting...
Title: Re: move_towards_point
Post by: Josh @ Dreamland on January 28, 2011, 09:50:29 am
Correct. Game Maker will complain, hence, ENIGMA is backwards-compatible.
Title: Re: move_towards_point
Post by: MrGriggs on January 28, 2011, 09:52:37 am
LOL, ahhhhhhh. Great!