sjg Posted January 26, 2017 Share Posted January 26, 2017 I'm working on finding a better way to find out if two entities are (a) close to each other and (b) facing each other. Initially I thought it was a good idea to bolt a trigger onto them, offset on the local Z-axis and have each entity "carry" one around in front of them but I've now noticed that the physics timestep doesn't line up with the UPS, so if the framerate goes above 60 or so, my game loop doesn't detect a collision during some of those frames. It's probably an overly expensive way of calculating it as well. Ideally I'd like to have some simple detection happening that ticks those first two boxes above, but which I can put in my game loop so it's called once each App::Loop frame, rather than with a collision hook which is only called every physics update. I'm reasonably new to programming (a year or so) and haven't done much in the way of game stuff before, so there are a lot of concepts I'm ignorant about, but is raycasting something I should be reading up on to help me with this or am I barking up the wrong tree? Quote Link to comment Share on other sites More sharing options...
macklebee Posted January 26, 2017 Share Posted January 26, 2017 Maybe just try a simple raycast via World:Pick()or Entity:Pick()? Granted the API Reference recommends a World:Pick() over an Entity:Pick() because it would be faster, but both give the ability for you to control the length of the raycast which you can indirectly use as a way control how close you have to be to trigger a conversation. 1 Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Josh Posted January 26, 2017 Share Posted January 26, 2017 Couldn't you just check the distance between the two entities, and then get the dot product of their directions? The entity Z direction is returned by Transform:Normal(0,0,1,entity,nil). 2 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
sjg Posted January 26, 2017 Author Share Posted January 26, 2017 Thanks Looks like I have some reading and fiddling to do! Quote Link to comment Share on other sites More sharing options...
sjg Posted January 26, 2017 Author Share Posted January 26, 2017 Whew! So far I've done what Josh recommended and I'm also reading up on how to use Pick()... still trying to get my head around it, as I've never really used anything like it before. Josh's suggestion works well, but I'm missing something in my implementation of it because it returns a lot of (not false) positives (such as in the case of two entities standing back to back - they're close and facing opposite directions, after all). It's probably simple to narrow it down, it's just not apparent to me right at this second. Thank you for the swift suggestions! You'll make a man of me yet. Quote Link to comment Share on other sites More sharing options...
sjg Posted January 26, 2017 Author Share Posted January 26, 2017 I did it! Not only that, but also in the most immature way possible. First I thought trigonometry could help me... somehow. I'm horrible at maths, so I abandoned that idea. Then I remembered there was more than one way to skin a cat. I went back to the old idea of bolting a pivot onto the front of an entity, but this time I used two empty ones, slightly offset on -x and +x, and I did a check to see which was closest to the target entity: the left pivot, the right pivot, or the main pivot; this told me in a very cheap and nasty way if the target entity was in front or behind the player (or whatever entity for that matter). Couple that with the priceless "facing directions dot product" tip, and I now have something that can be used every game loop frame. Quote Link to comment Share on other sites More sharing options...
Josh Posted January 26, 2017 Share Posted January 26, 2017 The dot product returns 1.0 when two vectors are the same and -1.0 when they are opposite (or the reverse, I can't remember!). If the dot product is zero, then the vectors are at 90 degrees from each other. So your test would be something like if dot()<-0.5 the entities can see each other, or possibly if dot()>0.5. 2 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
sjg Posted January 26, 2017 Author Share Posted January 26, 2017 Yeah, I checked it more or less as such, but the thing I hadn't taken into account was that if they're standing back to back it's also -1. That's why I had to also chech which side of the player was closest to the other entity. As I mentioned, I'm not much chop when it comes to mathematics, I tend to MacGyver my way through that area. That's been slowly changing since I got into programming; I come from a musical background. Here's what I tested for after I worked out which entity was closest to the player. I don't usually comment my code but there is a shoutout. if (closest != nullptr) { double testIfFacing = facingDirection.Dot(closest->getFacingDirection()); // 1 same, -1 opposite... cheers once again, josh offset = body->getChestPivotLeft()->GetPosition(true) - closest->getBody()->getMainPivot()->GetPosition(); distance = std::sqrt(std::pow(offset.x, 2) + std::pow(offset.y, 2) + std::pow(offset.z, 2)); offset = body->getChestPivotRight()->GetPosition(true) - closest->getBody()->getMainPivot()->GetPosition(); double distance2 = std::sqrt(std::pow(offset.x, 2) + std::pow(offset.y, 2) + std::pow(offset.z, 2)); bool distanceTest = Leadwerks::Math::Min(distance, distance2) < closest->getDistanceFromPlayer(); if (testIfFacing <= -0.6 && distanceTest) { // tweak this setConTarget(closest); } } edit::WHOA, just caught a massive bug. Glad I pasted that in a public forum. Fixed. Whew. Quote Link to comment Share on other sites More sharing options...
Josh Posted January 26, 2017 Share Posted January 26, 2017 There is a command to get the distance between two entities, which will make your code above a bit simpler: http://www.leadwerks.com/werkspace/page/api-reference/_/entity/entitygetdistance-r800 This is the source code for the Vec3::Dot command: float Vec3::Dot(const Vec3& v) { return x * v.x + y * v.y + z * v.z; } 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
cassius Posted January 27, 2017 Share Posted January 27, 2017 I use GetDistance to check when two characters are close and I use Point to make one face the other. Dead simple. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
mdgunn Posted January 27, 2017 Share Posted January 27, 2017 I use GetDistance to check when two characters are close and I use Point to make one face the other. Dead simple. You meant you do this? store the current rotation turn the source to point at the target log the rotation compare original rotation to rotation to target turn back to original heading so everthing appears as it was for the screen refresh? If that's what you mean then that is what I ended up recently to do an enemy FOV check, though I suspected that using 'proper' math, vectors and trigonometry may be faster and potentially more useful for me to understand. I stumbled one or two articles I think but I've yet to read through it properly and get a grip of this. I suspect it will all be terribly useful for constructing a 'radar' or in-game dynamic map. Quote Link to comment Share on other sites More sharing options...
cassius Posted January 27, 2017 Share Posted January 27, 2017 In my game I needed a character to warn my main character not to go into a nearby castle because it was dangerous. I used the GetDistance command to check when the character was close to the main character and I used point command to make character face main character when at the required distance. Nothing more. But maybe you need some other requirements. 1 Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Ma-Shell Posted January 27, 2017 Share Posted January 27, 2017 You can also find an implementation that works without the pivots here (that's only the facing-directions-test without the distance-test, but the latter one is straight forward): http://www.leadwerks.com/werkspace/topic/15187-swordfight-prob-c/#entry102424 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.