Collaborative Sci-Fantasy Tech Demo for an Official Panda3D Showcase

But they do keep showing up: that paycheck is a tie that keeps them coming back.

That’s fair, but conversely, volunteer projects are I think somewhat notorious for dissipating.

I’m not sure that it really does inflate that much. A little–we’ll want to figure out how to get the pieces inter-operating, and how to make the portals, for example–but it shouldn’t be a huge difference, I feel.

Conversely, we have less concern about our various contributions matching and working directly with each other, which may reduce the effort involved.

Agreed on all points, I think! :slight_smile:

So the new plan is thus:

  • Sections 1 and 2 will feature the existing, but improved, procedural generation and spaceflight ideas, in a roughly standard sci-fi treatment
  • Starting at Section 3, the player will encounter portals inside the space station which can transport them to a few different world variations that show off different code and art styles
  • The last two Sections will be co-developed and then linked together with only the portal dynamic as a bridge between the separate code

I definitely like this idea, but I acknowledge we’ve lost a bit of cohesion here, unfortunately. I do feel a bit like we’re attempting to rescue a dying language, as much as it pains me to say that. I do not like Unreal or Unity nearly as much as Panda3D, but it makes our work that much harder when our few “speakers” cannot decide on so much as a style convention or which exporter to use.

Well, let’s wait for Epihaius (and perhaps others) to weigh in before we consider it settled, I think!

For myself, I was thinking of taking it further, and not as far:

Instead, I was thinking that Section 2 would end with a portal, with Section 3 then taking place entirely in a new environ. It likewise would end in a portal, which would lead to Section 4 which in turn would have its own environ and style.

This would, I think, be far less work than having multiple world variations within Section 3.

Indeed, I would caution that we keep this project simple: there are only a few of us working on it, and that likely in spare time.

I don’t think that we can’t do those things. The style convention in particular we could very much find agreement on, I do think!

Rather, I feel that as a showcase a variety of styles might actually be better.

The matter of the exporter is, to a large degree, a matter in Panda: Panda has no single unified pipeline, after all.

All that said, the thing is that Panda is an engine with a smaller user-base than those others; I’m not sure that it has been more widely-used, or at least not for a long time. It’s a niche engine. As a result, there are fewer of us available to make such a thing as this.

Quite possibly! Teams usually coordinate their effort though, in a shared style, to achieve something greater than a single one of them could have achieved alone.

I mean, that’s technically true – but YABEE hasn’t been actively maintained for some time now, and I don’t think any of us are keen to take that over, including yourself!

Pushing the date further and further into the future for adopting PBR has limited and decreasing benefits, to my eye. I’m not sure why, besides code inertia, one would want to use severely outdated tools to build a game. That’s probably the first thing a new, serious, developer is looking at when picking an engine – is it maintainable? Does it actually work with modern assets? And so forth.

Conversely, I daresay that most teams aren’t working on a project that aims to showcase a breadth of possibilities.

As to something greater, in a sense we would still be doing that by the combination of our various contributions.

That is fair.

Code inertia, familiarity, the tools working well with the desired style, the tools still working well, and so on.

“Old” is not necessarily a synonym for “bad”, remember. (Neither is “new”, to be clear.)

Further, while I imagine that I’ll at some stage pick up a later version of Blender and whatever exporter I settle on, it’s not likely to be in the short term. For this project, Blender 2.79 + YABEE is the toolset that I’m familiar with and in a position to use; if we’re vetoing it, then I’m not in much of a position to contribute as much, I fear.

(With PBR I’ll confess that I do worry that it’ll be harder to make certain non-realistic styles. (I seldom aim for photorealism, myself.) Is it feasible to have a PBR material that doesn’t include things like low-angle reflectiveness, for example?)

And the other sections, at least, arguably do answer that.

Argh – I appreciate that you are among the top Panda3D developers in the world, and I’m happy to give you infinite leeway with your personal projects. But actually collaborating with tool differences this vast, is, I’ll admit, not something I care to do. Though, please keep up your great contributions of Panda knowledge to the forum and to your own work.

This is a fair artistic concern. I think it is possible to eliminate low-angle reflectivity by setting the Specular amount to 0 and/or by using a simple texture. The “PBR texture slots” aren’t necessarily opinionated about this stuff – I’m afraid I may be speaking outside my technical expertise here though.

I may have to consider abandoning the demo if it’s only myself and Epihaius working on it – though I will 100% finish the procedural code section because that is super cool and we already have an 90% working solution for that. I’m not going to solo the whole demo by myself – I do have a number of other real-life projects that require my attention.

I hear you.

But I also suggest that, if we do have separate sections as I’ve proposed, then perhaps the tool differences aren’t that significant. The stuff made for one section needn’t affect another.

After all, the space-flight section isn’t likely to use the first-person guns from the shooter section, and so on.

Alternatively, we could just say that you and Epihaius handle the modelling (perhaps incorporating third-party assets, if called for), and the handling of the PBR pipeline perhaps. I doubt that any of the first-person-shooter code for example is particularly affected by how its models are being rendered, or what format they’re stored in.

There’s an argument to be made that this would be better for me, as it would lighten my side-project workload.

It would also allow for a return to a unified aesthetic, if you prefer.

But I may want specular highlights nevertheless.

However, I may be worrying about nothing–I’m not familiar with PBR, and so am not familiar with what is feasible with it.

Thanks – and don’t worry about it! :slight_smile: As soon as I have integrated my motion system into the ship-generation code, I’ll upload it all into the experiments folder.

Thanks! :slight_smile: Will check it out soon (I’m a bit busy today).

Sounds good to me. :slight_smile:
It does indeed seem like a good way to draw the player in by starting off with “pure/standard” sci-fi in the first two sections and then gradually introduce a more fantasy-like setting. The space station could be harboring a terrible secret, related to an alien menace from a different dimension for example, which could explain the sudden appearance of fantasy-themed props, weapons and/or enemies. This should make it easier for the player to accept/digest the fantasy element, more than if it were there from the start, I think.

Hmm, I’m not sure I agree here. The portals were mostly intended to form a kind of puzzle segment, where the player needs to figure out which ones to go through in order to leave the space station. Spreading them out to earlier sections would dilute that concept, I feel.
How do you imagine the starship to enter that portal, by the way? In a deliberate fashion, to escape enemy fighter ships at the end of the space battle, or purely by accident, or perhaps manoeuvred into it by the enemy?

Regardless of art style, the worlds inside these portals would be very hostile, such that the player shouldn’t have to stick around long; each “world” could therefore be just a single scene from which to quickly escape through another portal – which should not immediately be recognizable as such.

An example: you see a poster of an old movie on a wall and only by moving alongside it do you notice apparent depth behind said “poster”. Let’s say it’s a poster for the 1977 movie “The Car”, where said car is pictured inside of a garage. Not having seen the movie, you decide to jump through the poster-portal, only to discover to your horror that this car is actually alive, indestructable and hell-bent on killing you. Revving its engine as if possessed (and it is!) and honking like mad (which it is too!), it starts to exhaust its deadly fumes and the garage door cannot be opened. Then your eye catches a painting on the wall…
See where I’m going with this? :wink:

But should this prove too difficult to implement, then alternative ideas are welcome of course!

For the time being I wouldn’t worry too much about the exact file format the models are exported to. Perhaps it’s best to focus on the shape of the models right now, and add materials to them later. Applying textures to them should already give a good idea of where you’re going with them, art-style wise. So I don’t see an immediate problem with using .egg files.
Let’s just do what we can with the tools we’re most comfortable with – there should always be a way afterwards to convert the model files to a more preferable format.

That said, this may be a good time to discuss the future of the .egg file format.

Totally understandable – there’s life outside of Panda3D! :slight_smile: And I’m also working on another project as well, although I’ve put it on hold right now, so I can focus on this one.

Let’s just take our time with this and work on it one small step at a time – I don’t think anyone is expecting this demo to be finished any time soon. The longer it takes, the more ideas and insights will develop naturally – just look at the myriad of ideas we’ve already gathered since the original concept was introduced! Besides, the development of Panda itself isn’t all that fast (and understandably so); if we can get it together before that elusive Panda3D version 2.0 is released, I’ll be pretty glad already!

2 Likes

My pleasure, and fair enough, respectively! :slight_smile:

Ah, hmm–I hadn’t remembered there being previous discussion of portals, I think. (Although it does seem familiar, now that you mention it.)

No, what I was proposing was separate from that: I hadn’t envisaged any in-level portals, but only portals between levels. They would simply provide a means of accounting for a significant change in setting. (And maybe a loading screen.)

If we’re contemplating in-level portals and a bunch of mini-scenarios in Section 3, then let me give a note of caution: the more complex and varied that we make this, the longer it’s likely to take, and the more likely that we’ll drift away from working on it.

I’d suggest rather that we keep things simple, focus on making something straightforward that looks good and plays well.

Don’t misunderstand me: what you suggest sounds cool, especially with the “hidden portal” concept! I just worry that all of that might be a bit much for three people in their spare time–especially if (as in my case) we have other side-projects in progress as well.

I hadn’t really given the story very much thought, I’ll confess! ^^;

Hmm… In all fairness, I do gather that PBR materials are quite different to standard ones, and thus conversion might require going into each model and remaking those materials.

However, I might be mistaken in this–I’m not expert in PBR!

Hi all, I’d love to help out with this if possible, it looks great!

I’m very busy for the next two weeks but I should have plenty of time for this after that. So far, I’ve just skimmed the thread, is there a github repo with the current state of this project on it?

3 Likes

Welcome! :slight_smile:

There is indeed a GitHub page (which holds four repositories–one for each section)–you should find it here:

Thanks, I’ll have a look

1 Like

I’m glad you’re here Epihaius.

Thanks for making this post. I agree with Moguri on this one.

I’m willing to give it a year. :slight_smile:

Panda3D 2.0, whenever it comes, may end up being the best game engine in the world by a few metrics. :slight_smile: I am optimistic on the overall future of our engine – I think the compactness, the framework-like minimalism of it will be great benefits as other codebases continue to grow to massive size and complexity.

Cool! We would appreciate any other collaborators. For non-members of P3D Space Tech Demo, I would suggest forking whichever repo you want to contribute to (IE Section 2 Spaceflight and Docking), and submit Pull requests for us to review. Our license is BSD-3 to fit Panda. There are project outlines in the Project section of each Section repository that you can check out to get an idea of what we’re working on.

I’ve added our GitHub group to the original post for newcomers and potential collaborators. I’ve also added a few images to show the progress we’ve made in just 16 days of development.

Portals the Lazy Way

I thought I’d knock off one of the harder problems, which is to create portal programming logic at a basic level.

I’ll provide the code after a short description here. Basically what’s going on is that I’m putting a texture buffer in a new render node, attaching a camera to that, and then projecting that scene-texture onto a plane in regular render space. Then, I’m defining a Task that updates the portal-camera’s H value and FOV based upon the camera handling logic of the player character.

The FOV increases with the decreasing distance of the player to the portal. Then, when the player is within a certain range, I use set_pos() to teleport the player character to the portal scene which is deceptively rendered far-off on the normal render space graph, as well as the portal render node.

portals_again

        # portal #1 begins
        # make a new texture buffer, render node, and attach a camera
        mirror_buffer = self.win.make_texture_buffer("mirror_buff", 4096, 4096)
        mirror_render = NodePath("mirror_render")
        mirror_render.set_shader(scene_shader)
        self.mirror_cam = self.make_camera(mirror_buffer)
        self.mirror_cam.reparent_to(mirror_render)
        self.mirror_cam.set_pos(0, -60, 5)
        self.mirror_cam.set_hpr(0, 25, 0)
        self.mirror_cam.node().get_lens().set_focal_length(10)
        self.mirror_cam.node().get_lens().set_fov(90)
        
        mirror_filters = CommonFilters(mirror_buffer, self.mirror_cam)
        # mirror_filters.set_high_dynamic_range()
        mirror_filters.set_exposure_adjust(1.1)
        # mirror_filters.set_gamma_adjust(1.3)
        
        # load in a mirror/display object model in normal render space
        self.mirror_model = self.loader.loadModel('models/wide_screen_video_display.egg')
        self.mirror_model.reparent_to(self.render)
        self.mirror_model.set_pos(-20, 0, 1)
        self.mirror_model.set_sz(3)
        # self.mirror_model.flatten_strong()
        
        # mirror scene model load-in
        # reparent to mirror render node
        house_uv = self.loader.load_model('models/hangar_1.gltf')
        house_uv.reparent_to(mirror_render)
        windows = house_uv.find('**/clear_arches')
        windows.hide()
        house_uv.set_pos(0, 0, 0)
        house_uv.set_scale(1)
        
        # the portal ramp
        house_uv = self.loader.load_model('models/ramp_1.gltf')
        house_uv.reparent_to(mirror_render)
        house_uv.set_h(180)
        house_uv.set_scale(1.5)
        house_uv.set_pos(0, -50, 0)

        # mirror scene lighting
        # point light generator
        for x in range(0, 1):
            plight_1 = PointLight('plight')
            # add plight props here
            plight_1_node = mirror_render.attach_new_node(plight_1)
            # group the lights close to each other to create a sun effect
            plight_1_node.set_pos(random.uniform(-21, -20), random.uniform(-21, -20), random.uniform(20, 21))
            mirror_render.set_light(plight_1_node)
        
        # set the live buffer texture to the mirror/display model in normal render space
        self.mirror_model.set_texture(mirror_buffer.get_texture())
        
        # secret hangar far off somewhere on the graph
        house_uv = self.loader.load_model('models/hangar_1.gltf')
        house_uv.reparent_to(self.render)
        windows = house_uv.find('**/clear_arches')
        windows.hide()
        house_uv.set_pos(400, 400, -1)
        
        # the portal ring
        house_uv = self.loader.load_model('models/ring_1.gltf')
        house_uv.reparent_to(self.render)
        house_uv.set_h(90)
        house_uv.set_pos(-20, 0, -2)
        
        # the portal ramp
        house_uv = self.loader.load_model('models/ramp_1.gltf')
        house_uv.reparent_to(self.render)
        house_uv.set_h(0)
        house_uv.set_pos(-20, -5.5, 0)
        r_pos = house_uv.get_pos()
        make_collision_from_model(house_uv, 0, 0, self.world, (r_pos[0], r_pos[1], r_pos[2] + 1), 0)
        
        self.count_frames_1 = 0
        self.screen_cap_num = 1
        
        def make_screenshot():
            # Ensure the frame is rendered.
            base.graphicsEngine.render_frame()

            # Grab the screenshot into a big image
            full = PNMImage()
            base.win.get_screenshot(full)

            # Now reduce it
            reduced = PNMImage(500, 300)
            reduced.gaussianFilterFrom(1, full)

            # And write it out.
            reduced.write(Filename('screen_cap_' + str(self.screen_cap_num) + '.jpg'))
            
            self.screen_cap_num += 1
        
        def update_portal_cam(Task):
            if self.count_frames_1 < 30:
                self.count_frames_1 += 1
            
            if self.count_frames_1 == 15:
                pass
                # make_screenshot()
                
            if self.count_frames_1 == 29:
                self.count_frames_1 = 0
            
            p_dist = (self.player.get_pos() - self.mirror_model.get_pos(base.render)).length()
            target_fov = 115

            if p_dist < 2.25:
                target_fov = 145
                self.player.set_pos(400, 400, 3)
                # adjust the ground plane
                self.ground_plane.set_pos(0, 0, 0)
                # move the normal point lights
                lights = self.render.find_all_matches('**/plight*')
                for l in lights:
                    l.set_pos(400, 400, 21)
            
            player_h = self.player.get_h()
            self.mirror_cam.set_h(player_h)
            self.mirror_cam.node().get_lens().set_fov(target_fov)

            return Task.cont
            
        self.task_mgr.add(update_portal_cam)
        
        # portal #2 begins
        # the portal ring
        house_uv = self.loader.load_model('models/ring_1.gltf')
        house_uv.reparent_to(self.render)
        house_uv.set_h(90)
        house_uv.set_pos(400, 400, -2)
        
        # the portal ramp
        house_uv = self.loader.load_model('models/ramp_1.gltf')
        house_uv.reparent_to(self.render)
        house_uv.set_h(180)
        house_uv.set_pos(400, 405.5, 0)
        r_pos = house_uv.get_pos()
        make_collision_from_model(house_uv, 0, 0, self.world, (r_pos[0], r_pos[1], r_pos[2] + 1), 180)

Here’s a bonus screen capture function:

        def make_screenshot():
            # Ensure the frame is rendered.
            base.graphicsEngine.render_frame()

            # Grab the screenshot into a big image
            full = PNMImage()
            base.win.get_screenshot(full)

            # Now reduce it
            reduced = PNMImage(500, 300)
            reduced.gaussianFilterFrom(1, full)

            # And write it out.
            reduced.write(Filename('screen_cap_' + str(self.screen_cap_num) + '.jpg'))
            
            self.screen_cap_num += 1
1 Like

That is more or less the classic way to do it, I believe–and is so for a reason, I daresay! Nicely done I do think! Indeed, this looks like a good way of handling the feature! :slight_smile:

I’ve been meaning to ask: is anyone working on the space-flight section? I’m tempted to sketch up the basic gameplay at some stage, but don’t want to step on any toes.

(I won’t likely start before Monday, if then, so there’s time.)

1 Like

I have some ideas about it, but I haven’t started prototyping that section yet. We need several things there that I listed in the Project of that section, like a geographic terrain sphere for one, and some outside modeling of the hangar area.

I did open an issue on that section on GitHub, which is whether or not we want to add gamepad support. I’d be willing to self-assign this (adding gamepad support to the demo) if there are no objections to exercising Panda’s gamepad support.

Fair enough; I’m happy to leave it to you, then.

In all fairness, we should be able to start prototyping the mechanics without those things, or at most with stand-ins for them, I do think.

If you want to take it on, then I have no argument!

1 Like

Thanks, but I am curious what your thoughts were here? There are several ways to implement the flight controls, and indeed the whole traversal/shift of the environment.

Well, in all fairness my first question was likely to have been that of whether we’re going for full six-degrees-of-freedom flight, or a more constrained “shmup, but in 3D, moving on a 2D plane” approach. Both have noteworthy advantages and disadvantages, for both development and showcasing, I think. And of course, the answer would have a significant impact on the implementation.

I hadn’t really thought of the “leaving the planet” element, to be honest–I’d overlooked that it was involved. How it’s handled may depend on what we want to do: If we just want the ship to leave the planet, then we can perhaps just have a large, curving surface fall away. Conversely, if we want the player to be able to fly freely over the planet, then things get more complex, I fear.

Oh, I daresay we don’t have the time budget in the 10 minutes to remake Flight Simulator (not that this is what you were suggesting of course). I’d be fine with a short flight. It would only take a few minutes to get to space in real life (~7 minutes by rocket if I recall correctly), and we can fudge that time down from reality even more.

I think 6DOF wouldn’t be too hard! We can handle that with set_quat() or even just hpr. Adding some semi-randomized turbulence could add some additional character to the flight, too.

Also, I added my portal programming demo to Section3SpaceStation/portal_programming at main · P3D-Space-Tech-Demo/Section3SpaceStation · GitHub