Rodrigues’s formula will do that. Basically, you find the height of a point above a plane (defined by the axis and a point), drop it straight down onto said plane, rotate it there, then lift the result back up again by the height.
Admittedly haven’t yet had a look at your latest package, but is sounds like you’re getting places impressively quickly. Glad you’re having fun with it!
I see your point with the rotations now. It might be worth reading up on gimbal locks and euler angles. Not about to pretend I’m any kind of physicist here, but I’m aware that it’s a common problem in physics engines and just seeing what other engines do to compensate for it might give you enough guidance to implement something here.
@StarCrunch thanks for that and I’m familiar with that approach. However, richard11’s design doesn’t update any points. Instead, he caries the original points matrix and three angles. I think richard11’s latest suggestion is what I need to do. Assuming an object has a local, tilted axis, a rotation around a global axis will result in an adjustment to those angles.
Euler… here I come.
Unity - Scripting API: Transform.eulerAngles looks like a good place to start. Apologies for linking to the competition here, ha.
In a nutshell, it looks like just actioning rotations in a particular order is the way to go, internally keeping track of absolute rotations for each axis as that happens so that each time a rotation is requested, the system can effectively update the internally stored axis, reset the object to 0,0,0, and then repeat the rotation for each axis in the defined order. If that makes sense?
E.g. if I call rotate(x=5) on an object, the system would internally store x=5,y=0,z=0, and then set the object to 0,0,0 and rotate z by 0, then x by 5, and then y by 0. Later if I call rotate(x=2,y=3) then the system would update those internals to x=7,y=3,z=0, reset the object to 0,0,0 and finally rotate z by 0, x by 7, and y by 3.
At least, that’s my understanding.
This next question is probably the result of my relatively weak coding skills. I would like to integrate the 3d objects into composer scenes but I can’t seem to figure out how this would be accomplished. If not composer scenes, perhaps you could tell me how I can destroy the q3d objects after they have been created.
Much of the Q3d structure is actually based on one of my other engines, Qiso, and as it happens Composer support was built in to Qiso already so I can answer this one with a bit of copy + paste and hackery of Qiso code. Full disclosure, this isn’t tested, but:
In rendering.lua you should see near the top the engine creates a display group called q3dcanvas. This is where all rendering is performed, so it should just be a case of creating a new function to insert this group into Composer as the parent. So add this to rendering.lua:
module.setParentGroup = function(parentGroup)
parentGroup:insert(q3dcanvas)
end
Also add this new function to the module.init function at the bottom, which I noted you’d already figured out the point of when adding those new shapes:
main.setParentGroup = module.setParentGroup
This should be all you need to do within the plugin code. Then just call this new function from Composer’s scene:create function before doing any other Q3d stuff, and move the usual q3d.activate() into Composer’s scene.show. There’s also a q3d.deactivate() you can add to scene.hide. These functions are all in control.lua already.
So your Composer code should look like this, I think. Again untested - I’m just ripping up an old Qiso test project and hacking a basic Q3d project in…
local q3d = require "plugin.q3dengine"
local composer = require "composer"
local scene = composer.newScene()
function scene:create( event )
local sceneGroup = self.view
q3d.setParentGroup(sceneGroup)
q3d.setAssetsFolder("assets")
q3d.addCube({ name = "test" })
q3d.moveCamera({ x = 0, y = 6, z = -10 })
q3d.rotateCamera({ x = -30, y = 0, z = 0 })
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
q3d.activate()
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
end
end
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is on screen (but is about to go off screen)
elseif ( phase == "did" ) then
-- Code here runs immediately after the scene goes entirely off screen
q3d.deactivate()
end
end
function scene:destroy( event )
local sceneGroup = self.view
-- Code here runs prior to the removal of scene's view
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
Thanks for sharing Richard! I remember when we were all chatting about 3D projects a while back and you were looking into making a voxel engine. This project is great! It makes we want to go back and try to make a 3D engine with 4-point perspective - which was my brainstorm in that old chat.
I think my mind started looking towards voxel some time after I’d gotten this engine working actually. It sat dormant for a long time before I created this thread, and even that was some time ago now.
I do actually have some notes somewhere, which I made after a series of shower-time brainstorms. Funny how our moments of genius arrive in the shower rather than at keyboards . I’ll try to dig them out again. Long story short, at some point I did come up with a brilliant array based method of raytracing in voxel space without having to actually do any kind of “is this object on screen?” checks. Something to do with pseudo rotations. I’ll do some digging!
Yeah, I had to take a break from all my Solar2D work and now that I’m back I can’t tell what’s brilliant and what’s buffoonery!
A year on, I’ve finally gotten around to uploading this to Github.
@baukburg if you want to officially create a fork for your own changes please do.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.