Every thing is static, nothing change over frame. If it is just main thread, no problem. Also 1 thread(just for testing) also no problem. When it is 2 or more threads, result become weird. Here is the code I manage to reproduce:

extends Spatial

var direct_state: PhysicsDirectSpaceState
onready var start: Spatial = $Start
onready var end: Spatial = $End

export(int, 0, 16) var thread_count: int = 4

func _ready():
	direct_state = PhysicsServer.space_get_direct_state(get_world().space)

func _physics_process(_delta):
	if thread_count == 0:
		print("Main: ", ray_test())
	else:
		var thread: Array = []
		for _i in range(thread_count):
			thread.append(Thread.new())
		for t in thread:
			t.start(self, "ray_test")
		for i in range(thread.size()):
			print("Thread ", i+1, ": ", thread[i].wait_to_finish())
	print("-----")

func ray_test(_o = null):
	var col: Dictionary
	var last_pos: Vector3 = start.global_transform.origin
	var last_obj: Node = null
	while true:
		col = direct_state.intersect_ray(last_pos, end.global_transform.origin, [last_obj])
		if col.empty():
			return [last_obj, last_pos]
		last_pos = col.position
		last_obj = col.collider

Result:

Is it normal or something wrong with my code?

No one discuss this thing here, I will assume this is a bug. Gonna research this more and issue it on Github.

I looked at this post, but frankly am a bit weirded out you are spawning and waiting on threads in _physics_process() (a time critical function).

Since you are calling into the physics-server, I am not even certain you are getting anything from it, because I assume the server is its own threading context and you are spawning several threads the 'engine' context that hammer the same server instance from multiple threads.

In fact I am not even certain a single instance of physics_direct_state should be used by multiple threads since this may represent a 'package' of parameters to the physics server that multiple threads are using concurrently.

So one other thing, since your ray-cast is right on the boundary of a collided object, I am not certain quite how bullet will respond to a ray-cast that might fall inside a collidable (because floating point)

In my project, yes, this raycast thing is time critical operation so I need to put it in fixed update frame function and demand it to complete in single frame. That why wait_to_finish() is next to start(), just to load balance thing, not to do thing in background.

I believe this encourage everyone to using lots of PhysicsServer instance with Thread.

I also don't know if PhysicsDirectSpaceState is thread-safe or not, but I believe all my code is just read data in thread, never write, so should yield no problem. I also test this by give each thread it own direct state, same result. If intersect_ray() is in PhysicsServer, I would happy to use that instant of direct state class.

This makes them ideal for code that creates dozens of thousands of instances in servers and controls them from threads. Of course, it requires a bit more code, as this is used directly and not within the scene tree.

If you mean the above statement, I find that vague. It says instances in servers. That suggests server side objects, manipulated in threads in godot.

OK my reason for raising an issue with creating threads in _physics_process and pending in physics process is that all this smacks of huge latencies introduced your engine fixed-rate calls which must be budgeted in with everything else you will be doing.

You can only demand it completes in a single frame if the processing time (the round trip to the server) of all threads completes in < 60th of second. I have found instancing scene stuff in _physics_process(), A Bad Idea. Threads may be no different. They are usually 'semi' costly to create and start up.

I also don't expect them run synchronously with your _physics_process() call or run at the same, lower or higher priority.

I think it might be cheaper to simply cast ray_test() N times in physics process.

I don't know of intersect_ray() is guaranteed to be 'immediate', that is, not subject to injecting a physics frame delay, so I might expect that could be a cause of your issue. I played around with lots of calls using direct state and at some point _physics_process was running well longer than 60th of a second. I think I had 15 or so calls going on and these were motion casts on shapes (more expensive than ray cast).

My worry about physics direct state had been that it might be state-full at least on the 'godot' side. But distinct instances show the same problem so it rules out this worry of mine.

I have experimented with physics-direct-state calls verses say using RayCast node or 'casting' KinematicBodies with move_and_slide in test motion mode, and found the latter faster and less hassle. At the very least, the calls and nodes have been written with those specific tasks in mind and they are running in C++ not a script.

RayCast is nice because you set it up, enable it and wait a physics_frame and it has nice collision report for you at any other time. Just read and enjoy and it is updated so long as it's enabled and in the scene.

So if you know about the RayCast Node, you might try the same thing you are doing manually but instance several ray-cast nodes in your scene and have each of them do the same thing ray_test() is.

Basically scoop up your code and stuff it in a RayCast.

RayCasts seem to only work if you make them look_at() their target (end) and set the cast_to vector to a scaled Vector3.FORWARD. The length should be from ray_cast origin to the target (end). Placing it at 'start' and having aim and end is the way to go. The look_at part may not be necessary for a statically position node, but i move mine around so it might caused some issue look_at solved

-- I think the thing to be said here is the ray-casts are happening on the server side. Throwing threads on the godot side doesn't change how the server decides to handle the multiple requests. If it runs them synchronously and in its own threads (cores) I don't really thing you are getting anything.

I will start with edited discussion first.

Agree, thing package thing is also concern me if direct state has to write some data internal but it shouldn't.

Floating point error is acceptable, if result is not swing, of course. But even fire raycast from start to target with more exclude collision every time still yield swing result.

I don't think Thread is scene object, but server object itself. But still I should keep it in mind that I should cache stuffs that I will reuses a lot for good practice.

In my project, I originally did this raycast stuff in main thread. And yes, I found that it was over budge. And when I use thread, thing became smooth again. (Yes, I concern that when I add more physics thing, this will get worse again. But I will ignore it for now) The current scene in project I setup the way it might be worst case scenario that map procedural generator might be generate.

Say PhysicsServer, I seriously want to do most physics thing in server. I try to setup area in server, it can be monitorable, but I want some of my area to monitoring too. PhysicsServer.area_set_monitor_callback() is never call back, do you have any idea? So I have to go back to node based method again.

I don't think simulate a simple point collision with a whole shape collision is faster or even just better.

For me, RayCast is more headache than intersect_ray(). And as you can see, I need my ray to pierce through object until it reach target, so I would need to force_raycast_update() a lot.

I didn't test RayCast method yet. I already attempt and got headache so I stop and I will test it other time.

Thread isn't a scene object, but it is not a PhysicsServer object.

From its interface, and the most common portable package threads would be p-threads (POSIX threads) which are supported on Unix(MacOS/iOS/Andriod) and Windows. (confirmed by looking at engine source). Even PlayStation runs a hacked up version of BSD. You'd see something like p-threads there too.

Threads have nothing to do with the physics engine and are part of your computer/device's OS. They run in the godot engine process (to use the Unix terminology) and are used by it.

The servers themselves likely run in separate threads.

I would recommend though you make use of the profiler or use OS.get_usec_time (or whatever it's called to get an idea of the time 4 threads take.

If all you are trying to do is 'see' through several objects, it may be better to pop an area into existence and have it capture all the objects that intersect it, but it won't help if you need the points of intersection.

you can also cast for contacts with a very thin capsule using physics_direct_state. (but the docs say points when contacts are point/normal pairs).

I have played a bit with casting shapes or using rigid-bodies in kinematic mode for probes. If you set one up to be in no physics layer but its mask to detect the bodies you are interested in, you can turn on contact monitoring (and up the reported contacts to 8 or so (depending on how many bodies you expect) and look at the bodies by implementing integrate_forces (physics-body-direct-state): or physics_process() you may automatically see all of them in sequence. -but- the way collision detection works it will report the contacts furthest from the center of a collision shape. if you need contact points, you'd need to 'scan' from end to start.

I don't know why my recent discussion gone, I am not gonna write it again ;-; But I want to say that I love the idea that use Area instant of raycast in my project. But not to use body for just detect.

2 years later