Jump to content
The Dark Mod Forums

Scaling func_statics in DR - how to implement ?


Recommended Posts

I can only see two ways this could be done, one give the ability to Darkradiant to open, modify and save, lwo or ASE files directly, it already saves BSP geometry to ASE files afaik. Second read the original file data (as it already does) put an exact copy of the model into memory, display it in the editor, scale and modify this copy has needed, then save it to a special custom file that only Darkradiant and the engine used need to know about.

Link to comment
Share on other sites

I can only see two ways this could be done, one give the ability to Darkradiant to open, modify and save, lwo or ASE files directly, it already saves BSP geometry to ASE files afaik. Second read the original file data (as it already does) put an exact copy of the model into memory, display it in the editor, scale and modify this copy has needed, then save it to a special custom file that only Darkradiant and the engine used need to know about.

 

You don't need to save / edit anything. DR would render scaled model from RAM. Physical copy stays as is. Same thing with rotations - models on HDD aren't rotated. They are only rotated in the viewports.

Link to comment
Share on other sites

Models. And as you can see "important" note says rotation hack is not recommended. So I want to see if we can implement proper scaling.

It's not recommended because of in-game side-effects, so that sounds like something unsupported in the engine, not just the editor.

well yes and no, all I have had to do is make the model a 'noclipmodel' '1' and then said model behaved just fine. Fyi I did this with the galleon model so it was small enough to look like a scaled model on some nobel's desk.

Link to comment
Share on other sites

Proper way is, like I said, to have "scale" spawn arg (vector) that scales model internally in the DR, without messing with the file itself.

 

On the engine side "scale" will let engine know that the model needs to be rendered in scale, and collision model would be generated accordingly. Again, source ASE/LWO file will remain as-is.

 

I guess what I am asking is for OrbWeaver to point me to the code where scale spawn arg can be introduced (reading/writing/updating) and where render model can be updated, based on the scale spawn argument. Also would be interested to know where in the code we would be able to enable scaling (Rotate and Scale UI) and where in the code rotation widget is handled (would be nice to add scaling widget).

Link to comment
Share on other sites

 

You don't need to save / edit anything. DR would render scaled model from RAM. Physical copy stays as is. Same thing with rotations - models on HDD aren't rotated. They are only rotated in the viewports.

 

Yes a new model format is not necessary now that i thought better about it, but you still need to save that extra scale info to the map file, just like rotations, and yes the original mesh file stays as is, why id never officially supported mesh scaling is strange, but perhaps they didn't needed it, their map making style was still based heavily on BSP not meshes, even tho Doom 3 used meshes heavily on the hell and caves maps.

Link to comment
Share on other sites

A additional spawn argument would be redundant. A transformation matrix is already stored in the rotation spawn argument. That takes care of translation, rotation and scale.

 

Ideally you'd have a widget in DR to manipulate the scale but it's not all that difficult to manage without it. Wanna scale a model by 2.5? Multiply all nine values in the matrix by 2.5.

 

One caveat you will find is that the collision for models scaled in this way is broken. If you wanted to fix it I imagine the code that handles the rotation spawn argument is where you'd look.

Link to comment
Share on other sites

If you're starting with a model that has no rotation applied the matrix would be [1 0 0 0 1 0 0 0 1] and then [2.5 0 0 0 2.5 0 0 0 2.5] if you're scaling it to 2.5.

 

But you have to think about the complexity of the rules your crafting for yourself. Do I apply the scale before I rotate or after? What's the default matrix look like? Which positions do you modify again?

 

IMHO, it's much easier to simply multiply against everything. There are no special cases to worry about. It just works.

Link to comment
Share on other sites

Widget is a must, since scaling/rotation is done in place where model is kitbashed. We'll haven to look into the matrix stuff. Not everyone feels comfortable working with matrices :-)

As for collisions, it's the engine's thing. Should be easy to fix.

 

EDIT: I am guessing it would be nice to simply do this [1 0 0 0 1 0 0 0 1]*2.5 in the transformations spawnarg to scale up model uniformly, until scaling widget becomes a reality (or have an extra field for scale). DR would do rotations first, then scaling. This way it's easy to position the model, then scale it up/down, reposition it, adjust scale.

Edited by motorsep
Link to comment
Share on other sites

Tested - all numbers in the matrix have to be multiplied by the scale factor. Before or after rotations - doesn't matter. So for uniform scaling it's easy. For non-uniform scaling it doesn't work.

 

Although no collisions on scaled models.

 

Now we just need to figure out how to add either "scale" field to entity inspector and multiply matrix or enable scaling in Arbitrary Transforms window.

Edited by motorsep
Link to comment
Share on other sites

I guess using the rotation matrix or a separate scale spawnarg would work equally well, it's just a question of what is easier for users. A separate scale argument is perhaps more intuitive and allows mappers to enter a value like "1.2" manually without having to edit a 9-value matrix, but the disadvantage is slightly increased (although pretty trivial) map file size, and a bit more code support required.

 

Regarding the implementation in DR I suggest you look at the plugins/entity/eclassmodel/EclassModel.{h,cpp} file pair, which already has support for the "angle", "rotation" and "origin" keys which are combined into a transformation matrix in the updateTransform method. So it would probably be fairly easy to add an additional "scale" spawnarg into this calculation if you wanted to. You would also need to add the appropriate key observer stuff but again this is likely to be fairly similar to the existing spawnarg handling.

 

For the widget, I don't know if you are thinking of an actual draggable manipulator that you would interact with in the 2D view, or a PropertyEditor that you would use from the Entity Inspector. The PropertyEditor would be pretty simple to implement I think: just like there is already a property editor for editing angle keys (with 9 arrow buttons), you could add one that included a draggable slider wxWidget.

 

If you want a 2D manipulator then I have no idea, since this is not part of the DR code I have ever worked with, but you might find the existing scale/rotation tools to be instructive.

Link to comment
Share on other sites

Thanks for the tips.

 

Now that I think about it more, I think the easiest would be making Python plugin where designer could type something like scale 1.5 in the console, and selected model would scale up. Basically Python script would get scale value, multiply matrix by it, and set updated spawnarg on the selected entity. Plus add scale spawnarg (for Quake 3).

 

Can someone savvy in DR and Python create such plugin please?

Link to comment
Share on other sites

Thanks rich! Crazy awesome stuff!

 

I tested it and I got a few suggestions/questions about workflow.

 

When scale is set to 0, it should do nothing. Currently model disappears.

 

Is it possible to keep dialog always visible and always on top ? It's too much of console > dialog > type scale > Enter. I am thinking either have dialog always up, or binding scaleModel cmd to a hot key (not sure if it's possible at all) or simply typing in the console (this is the quickest IMO) are optimal workflows.

 

Also wondering if it's possible to add "scaleModel reset", which would reset transformation matrix to original state ("1 0 0 0 1 0 0 0 1" as I recall).

 

Is it also possible to add "modelscale" "<scaleModel value>" spawnarg to the respective entity (or update it if the spawnarg already exists). "modelscale" spawnarg would be for Quake 3 compatibility, since DR can now be used for Quake 3 mapping.

 

Thanks beforehand!

Link to comment
Share on other sites

Yeah I figured you'd have feature requests. The link has been updated.

 

Scale is now validated to be a numerical value greater than zero. A checkbox has been added to accommodate Q3.

 

I cannot make the window persist or be on top nor can I parse command line parameters. The API doesn't appear to support any of that. If you'd like to reset the matrix, delete the rotation and modelscale key/value pairs.

 

For the record, an ideal version of this plugin would have no dialog at all. I'd be able to draw a scaling widget directly in the orthographic views and you could drag around it's handles to scale the object the same way rotation currently operates. Any perception of poor workflow is not by choice but rather a product of working within constraints.

  • Like 1
Link to comment
Share on other sites

Thanks again rich!

 

I thought it's a bit more advanced (the API that is). Widget is the goal, but it'll take time for us to implement.

 

If I hit Cancel without entering any value, I get the following error:

Error while executing file: commands\scale.py: 
Traceback (most recent call last):
  File "G:/games/DarkRadiant203pre5/scripts/commands\scale.py", line 74, in <module>
    execute()
  File "G:/games/DarkRadiant203pre5/scripts/commands\scale.py", line 59, in execute
    if scale > 0:
UnboundLocalError: local variable 'scale' referenced before assignment

Also, how to I turn on a checkbox by default? (so it's always on)

 

Thanks beforehand!

Edited by motorsep
Link to comment
Share on other sites

Thanks! I'll test it after work.

 

I did some tests on the subject of kitbashing and draw calls. If func_statics are inlined, there will be same number of draw calls as if there is only one func_static in the view. Unfortunately if entities are not inlined, there is no batching happens. That's another thing on our to-do list (or rather it needs to be investigated and determined whether it worth the effort to batch static models in the run time; it would definitely require running batching on a separate thread to maintain performance)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
    • nbohr1more

      Please vote in the 15th Anniversary Contest Theme Poll
       
      · 0 replies
×
×
  • Create New...