1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

# New Camera Raycast and Sensor API (Update 01.162 DEV)

Discussion in 'Programming (In-game)' started by Drui, Nov 17, 2016.

This last post in this thread was made more than 31 days old.

Messages:
498
2. ### Ronin1973Master Engineer

Messages:
4,841
One of the parameters is "distance." Go back to the original post and scroll through. The raycast function can only be used through the programmable block. So you have to have some basic competence in C# programming. Each camera has a cool-down period related to the distance that you are raycasting. The shorter the distance the less time required between raycasts. You can balance this by limiting the range of your raycast or using multiple cameras clustered together. The real trick is how often do you really need to update the information? Ships can travel at a maximum of 100m/s. So the furthest possible distance between two grids is 200 m/s.

Again, go back to the original post and you will find that when you raycast and successfully hit an object with the ray, there's a bevy of information about that object available to be teased out of the camera block.

3. ### RegnTrainee Engineer

Messages:
74
camera.Raycast().HitPosition will give you the vector you're looking for, from which you can calculate distance. To find the distance between two vectors there's (VectorA - VectorB).Length(). As for when the distance is known and you want to travel to some place in between two known vectors there's distance * Vector3.Normalize(destination - ShipPosition) + shipPosition that will return coordinates. There's also simply controller.WorldMatrix.Forward * distance, so that you just need to aim the ship in the direction you want to go. I use controller.TryGetPlanetPosition() and camera.Raycast().Position to find the position of planets, which I then store in a database, and pull out of the database whenever I need to get the distance or coordinates to travel to.

A friend of mine's server has a command that you can write in chat to get the distance of whatever you're aiming your crosshair at. It seems to be more reliable than raycast, and it has no cooldown, but I don't know if it's common on all servers, or just something he made for his.

Also, like Ronin said, distance can also be found via Newton's law if you can figure out the right formula. The great thing about Newton's law is that it also works in reverse. For instance, from distance (maximum and minimum elevation) and minimum gravity (acceleration), I can find the maximum gravity on the surface of planets without having to actually visit the surface. I just need to get into the gravity field in space, is all. And from ship mass, acceleration, and elevation, you can find out the distance until your ship (would otherwise) smash into the ground.

4. ### Michael Viktor StarbergTrainee Engineer

Messages:
18
@rexxar I just had to try this out. Took me 10 minutes to get this into my script. That includes a coffee break. And now I can see stuff.

Pretty amazing how the new API is so easy to work with. Go back to the snippets thread and then feel proud of yourself. Adding kudos to teacher @Malware

5. ### EnjoyCokeTrainee Engineer

Messages:
72
When will this be available?

Messages:
2,788
it already is. here is the definition of IMyCameraBlock
Code:
```public interface IMyCameraBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
//
// Summary:
//	 Determines whether this camera is currently in use.
bool IsActive { get; }
//
// Summary:
//	 The maximum distance that this camera can scan, based on the time since the last
//	 scan.
double AvailableScanRange { get; }
//
// Summary:
//	 When this is true, the available raycast distance will count up, and power usage
//	 is increased.
bool EnableRaycast { get; set; }
//
// Summary:
//	 Returns the maximum positive angle you can apply for pitch and yaw.
float RaycastConeLimit { get; }
//
// Summary:
//	 Returns the maximum distance you can request a raycast. -1 means infinite.
double RaycastDistanceLimit { get; }

//
// Summary:
//	 Checks if the camera can scan the given distance.
//
// Parameters:
//  distance:
bool CanScan(double distance);
//
// Summary:
//	 Checks if the camera can scan to the given direction and distance.
//
// Parameters:
//  distance:
//
//  direction:
bool CanScan(double distance, Vector3D direction);
//
// Summary:
//	 Checks if the camera can scan to the given target
//
// Parameters:
//  target:
bool CanScan(Vector3D target);
//
// Summary:
//	 Does a raycast in the direction the camera is facing. Pitch and Yaw are in degrees.
//	 Will return an empty struct if distance or angle are out of bounds.
//
// Parameters:
//  distance:
//
//  pitch:
//
//  yaw:
MyDetectedEntityInfo Raycast(double distance, float pitch = 0, float yaw = 0);
//
// Summary:
//	 Does a raycast to the given point. Will return an empty struct if distance or
//	 angle are out of bounds.
//
// Parameters:
//  targetPos:
MyDetectedEntityInfo Raycast(Vector3D targetPos);
//
// Summary:
//	 Does a raycast in the given direction. Will return an empty struct if distance
//	 or angle are out of bounds.
//
// Parameters:
//  distance:
//
//  targetDirection:
MyDetectedEntityInfo Raycast(double distance, Vector3D targetDirection);
//
// Summary:
//	 Returns the number of milliseconds until the camera can do a raycast of the given
//	 distance.
//
// Parameters:
//  distance:
int TimeUntilScan(double distance);
}```
and because its a whole data structure of its own, here is MyDetectedEntityInfo exposed
Code:
```public struct MyDetectedEntityInfo
{
//
// Summary:
//	 The entity's EntityId
//
// Summary:
//	 The entity's display name if it is friendly, or a generic descriptor if it is
//	 not
//
// Summary:
//	 Enum describing the type of entity
//
// Summary:
//	 Position where the raycast hit the entity. (can be null if the sensor didn't
//	 use a raycast)
//
// Summary:
//	 The entity's absolute orientation at the time it was detected
//
// Summary:
//	 The entity's absolute velocity at the time it was detected
//
// Summary:
//	 Relationship between the entity and the owner of the sensor
//
// Summary:
//	 The entity's world-aligned bounding box
//
// Summary:
//	 Time when the entity was detected. This field counts milliseconds, compensated
//	 for simspeed

public MyDetectedEntityInfo(long entityId, string name, MyDetectedEntityType type, Vector3D? hitPosition, MatrixD orientation, Vector3 velocity, MyRelationsBetweenPlayerAndBlock relationship, BoundingBoxD boundingBox, long timeStamp);

//
// Summary:
//	 The entity's position (center of the Bounding Box)
public Vector3D Position { get; }

//
// Summary:
//	 Determines if this structure is empty; meaning it does not contain any meaningful
//	 data
public bool IsEmpty();```

7. ### EnjoyCokeTrainee Engineer

Messages:
72
From line 88 I get 19 errors.
It continues.

I don't know what game you're playing, but it sure ain't Space Engineers roflmao

Messages:
2,788
thats not code.
thats the exposed API. its a dictionary on what the interface for the camera contains, and how to use it within your code.
i dont know what language you program in, but it isnt C# roflmao

• Funny x 1
9. ### thefinnTrainee Engineer

Messages:
5
I wonder if putting the raycast range to zero could be put into server settings. Logged into a server today, spent most of the day building up, built a ship started up a lidar program - range 0.

Would've been nice to know before I joined.

10. ### MazenTrainee Engineer

Messages:
7
I build myself a little targeting ship to designate targets for a missile.
I'm using a camera to raycast 10km ahead every 5 seconds and display the result on an LCD in the cockpit.

This works perfectly fine in singleplayer. No issues detecting targets up to 10km.

Now I build this system with the idea in mind to implement it on an online server where I play with a few friends. After having to use a dedicated server to up the syncdistance to 10km so I can even see targets on such distance I got to another problem which I can't seem to fix.
Even though I can see the target the camera seems unable to detect it. Unfortunately I can't enable Debug Draw on an online server to see what the camera is doing.
The camera only detects targets in a range < 1km. It's not a distance problem, since if I turn around I can detect the planet from 9km away easily. So its no server limitations in regard of the scan distance.

I also noticed that the crosshair is slightly offset when zooming in far with the camera. I installed Whips Camera Overlay to eliminate this problem. So I'm very sure that I'm aiming directly at the target.

Any ideas on this one? Maybe desync? Lag? The target however is stationary and not moving. So desync or lag seems unlikely.

Edit:
Found the issue. Unfortunately it doesn't seem like it can be fixed by me.
The origin of this behaviour is a desync between Client and Server Ship-Attitude. This difference is only minimal but on a distance of 10km a .1° difference is what makes you hit a target with your raycast or not.

At first I noticed very light rubberbanding. Like my ship would jump back to its original orientation after slightly altering it.
Then I noticed that my ships orientation changes slightly if I leave and enter the cockpit again.

So it looks like the camera raycast is done using the orientation the server thinks the ship/camera has. Unfortunately this makes it impossible to target relatively small (or even larger) targets on distances greater than a few kilometers.

Last edited: Oct 26, 2019
11. ### Ronin1973Master Engineer

Messages:
4,841

Check the settings of the server and see if raycasting is enabled. It can be disabled as well as modified in regards to frequency and maximum distance.

12. ### MazenTrainee Engineer

Messages:
7
To quote myself from the post you quoted:

"The camera only detects targets in a range < 1km. It's not a distance problem, since if I turn around I can detect the planet from 9km away easily. So its no server limitations in regard of the scan distance."

13. ### Ronin1973Master Engineer

Messages:
4,841
I went back and reread it. At 10km, your stuck at a scan every 5 seconds from a single camera. Could you use a rotor to go from large grid to small grid (assuming you're using large grid to begin with) and mount a bank of 9 small grid cameras to the rotor. You could set the center camera to straight ahead and the 8 other to be off by a small fraction to cover a larger area. You could add more cameras yet, but I'm not sure what that's going to do to your game speed. But a bank of 9 to 25 should get you passed any issues with desync'ing.

EDIT

Also, just to cover all possibilities, the crosshairs when viewing through a camera aren't necessarily accurate to center of the camera, especially if your control seat isn't directly behind the camera. The crosshairs can be slightly off. So trying to pinpoint a target 10km away, centering the target with the crosshairs, may be misleading. I would double check your raycast by using a known fixed position in the world and calculating if the camera in your grid is truly aligned with that known position.

Last edited: Nov 16, 2019