Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  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.

  1. Elfi Wolfe Apprentice Engineer

    Messages:
    498
  2. Ronin1973 Master Engineer

    Messages:
    4,763
    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. Regn Trainee 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 Starberg Trainee 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. EnjoyCoke Trainee Engineer

    Messages:
    72
    When will this be available?
     
  6. Sinbad Senior Engineer

    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
    		public readonly long EntityId;
    		//
    		// Summary:
    		//	 The entity's display name if it is friendly, or a generic descriptor if it is
    		//	 not
    		public readonly string Name;
    		//
    		// Summary:
    		//	 Enum describing the type of entity
    		public readonly MyDetectedEntityType Type;
    		//
    		// Summary:
    		//	 Position where the raycast hit the entity. (can be null if the sensor didn't
    		//	 use a raycast)
    		public readonly Vector3D? HitPosition;
    		//
    		// Summary:
    		//	 The entity's absolute orientation at the time it was detected
    		public readonly MatrixD Orientation;
    		//
    		// Summary:
    		//	 The entity's absolute velocity at the time it was detected
    		public readonly Vector3 Velocity;
    		//
    		// Summary:
    		//	 Relationship between the entity and the owner of the sensor
    		public readonly MyRelationsBetweenPlayerAndBlock Relationship;
    		//
    		// Summary:
    		//	 The entity's world-aligned bounding box
    		public readonly BoundingBoxD BoundingBox;
    		//
    		// Summary:
    		//	 Time when the entity was detected. This field counts milliseconds, compensated
    		//	 for simspeed
    		public readonly long TimeStamp;
    
    		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. EnjoyCoke Trainee Engineer

    Messages:
    72
    Your code doesn't work.
    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
     
  8. Sinbad Senior Engineer

    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 Funny x 1
  9. thefinn Trainee 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. Mazen Trainee 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. Ronin1973 Master Engineer

    Messages:
    4,763

    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. Mazen Trainee 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."