Map Editor Design Issues

Started by
6 comments, last by Dawoodoz 13 years, 6 months ago
I starting to build a map editor (for 3D worlds) with interface like Valve Hammer Editor, but ofcourse alot simpler in terms of functionality. I want to support following things for now -

-4 Window Interface with some quick access buttons on left and others on right panel
-Creating simple objects
-Prefabs (Meshes Provided by D3DX library teaport,etc) and XFiles - without animation
-Placing Some Entities like Lights,etc (Animated Meshes will be a entity type like player etc)
-Abitlity to apply Textures & Materials to objects
-Placing Other Game related Entities which will be developed over time like a Entity_playerstart, Entity_loadNextMap,etc


I have some design/implementation issues ( also included possible solutions i can think of currently) and need some expert advise before i can move on -

1) How to implement grid; ????
Sol : As a large grid texture equal to size of map or as Lines.

2) How to change Grid size at runtime, I mean how can we change interspacing between grid lines from 1->2->4->8 & vice-versa ????
Sol : Maybe If using lines modify vertex buffer everytime but that won't be a proper way i think.


3) How to implement the ability to select a individual vertex and change its position ????
I know how to select a mesh in 3D using ray and boundingSphere but individual vertex ????
Then move it means many vertexbuffer locking n unlocking i hope Creating Managed Vertex Buffer should be enough.


4) I can't think of Map File format to store 3D objects.
Sol : The only way i can think of is to store vertex buffers and index buffers as they are in memory with SRT data.
For XFiles i can simply store its FileName and WorldMatrix.
Is there any better way ?
Valves Hammer editor store it as planes and faces are determined at load time by planes intersection, can't understand why store it that way?


5) Also how to render and Update 4 windows simultaneously ????
Sol : I found a good tutorial to implement this using 4 viewports -
http://www.mvps.org/directx/articles/rendering_to_multiple_windows.htm
Is there any better way to do this ?



Two Optional Features that i want to implement but not a priority for now.

6) Clipping Objects both hollow and solid.
Sol : No idea in 3D. (Studied an algorith (can't remember its name) for clipping 2D polygons as pointlist but i don't think it will help here.)

7) 3D Grids i mean implementing grids in 3D perspective view also.
Sol : No idea.

I will be using C++/DirectX for Rendering and C++.NET or C# for GUI as C++ win32 is very time consuming in GUI.

Please provide your expert advice on these issues along with refrences to any tutorials,links,books,etc that can be helpful in this project.

EDIT :
By 3D Grid i meant is it would be great if i can show Grid around 3D objects.
(scroll down for a screenshot)

[Edited by - Chetanhl on October 15, 2010 5:35:49 PM]

My Game Development Blog : chetanjags.wordpress.com

Advertisement
I can tell you how I implemented some of activities you describe in a 3D editor of mine (Dx9.0c). They all work with that particular application but, obviously, there is inter-dependence and you can take them as suggestions rather than design "requirements."

First: The methods for storage, etc., were designed to simplify the implementation of an "undo" stack.

4 Window (pane) Interface
I use a single backbuffer and an array of four structures containing pane information such as view (user 3D free camera, orthographic front/right/top and texture edit), viewport rectangle, options such as wireframe, textured/untextured, lit/unlit, etc. User can select single pane, double pane vert or horizontal align or four pane. EDIT: I don't believe DX10 and later support viewports. If so, it appears you'll have to render to separate surfaces as described in the referenced article.

For each of the currently displayed panes - set eye location, viewport and projection from the pane-info; set renderstates (wireframe, textured, etc.); clear the buffer and render that pane. Repeat for all panes. Then set a viewport to the backbuffer and Present it. DX9 viewports are convenient for this as device->Clear(..), BeginScene, etc., clears and renders to the current viewport only. I draw pane separators using GDI and an HDC obtained from the backbuffer before Present.

Grid For 3D view, I let the user set the total grid size and delta between grid lines; create a vertexbuffer of lines; position the grid under the "normalized" eye-position for the current pane, where "normalized" means closest integer multiple of grid size. The grid "travels" with the eyepoint.

Selecting vertices and faces (individual triangles)
User can select point or rectangle selection modes. E.g., for vertices selection mode: load a vertexbuffer with points for each vertex from the vertexbuffer of the selected object; render points after the object is rendered. The user drags a selection rectangle. For each vertex, unproject the point and use PtInRect to determine if vertex selected. Either set the vertex color to determine it's selection (red for selected, blue for unselected) or push the selected vertex indices into a std::vector. Yes, lots of locking and unlocking of mesh vertexbuffers and vertex buffers. Supports "shift-drag" to add to current selection, "ctrl-drag" to toggle selection, etc.

For face selection, default to point-and-click. Project the mousepoint to a 3D ray and use D3DXIntersect to determine which face(s) in the selected object are selected. User has option of backface-culling of faces or not for selection.

After vertex selection, user selects Translate, Rotate or Scale. Draw 3 partially transparent axis arrows (green=X, blue=Y, red=Z) at the average position of the selected vertices. Then user clicks-and-drags one of the 3 axis arrows (pick one of the arrows on button-down and lock on that axis until button-up). Display-mesh* vertices are updated with new positions during the axis drag. Not as slow as you might think. EDIT: alternately, you can use keyboard arrows to move the vertices a quantized amount (one world unit). Let the user select the movement amount.

*Note: to implement "undo" on this type of operation, I maintain a "base" mesh and a "display" mesh. When vertices are moved, I stack the operation as a vector of the selected vertices and the delta-move and apply it to the display mesh. On "undo" or ctrl-Z, the last operation is removed from the operation stack, the display mesh is released and a new display mesh cloned from the base mesh. The operation stack is then applied to the display mesh. The user can choose to "freeze" the object which means: release the base mesh; clone a new base mesh from the display mesh and clear the operation stack.

Storing objects
I have my own file format to support the editor as I have named clusters (mesh attribute groups of faces) with material and texture info (as well as other info needed by the editor - whether a texture is from a file or from a WAD, etc.) Optionally, the user can save any (mesh) object to x-file format.

Just some ideas.

EDIT: other objects (air- and ground-nodes, trigger boxes, etc.) are stored in my own file format. They're uniquely named and added to the current "scene" either from a saved "scene" file or when load is requested by the user.

EDIT2: The Hammer files save planes and faces to be used by the compiling tool because the final product is a BSP file, not a "mesh" file.

EDIT3: Applying textures, etc. - the user selects faces and creates a "cluster." Use a dialog box to set the material colors and texture selection. Selection options include cylindrical, spherical or spatial tex coords. When the dialog box is closed, calculate the tex coords according to the options for the faces in the selected cluster. The selected "cluster" now becomes an attribute group for the D3DXMESH. I also implemented a tex coord edit view for a pane, to allow tuning of the tex coords for selected faces/vertices.

Suggestion: when you have a very basic editor working, save the project and/or the files somewhere. Eventually you'll want to create another editor with slightly different features and you definitely don't want to start from scratch. (I've done that [sad])

[Edited by - Buckeye on October 14, 2010 9:57:12 PM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thnx Buckeye for that gr8 response. It helped me recosider many things in better way.
Initially i was considering 1 texture per object but with your sugestion of clusters i can overcome that limitation.
Also 3D View will be for preview only and SRT operation will be done in 2D views as in Hammer (should have mentioned it earlier as it isn't neccessary all people have used hammer). But it will be quite handy to implement vertex SRT operation in 3D also as you suggested, but that will be something for Phase 2 when i have a working editor.

My Game Development Blog : chetanjags.wordpress.com

Quote:i was considering 1 texture per object but with your sugestion of clusters i can overcome that limitation.

I think you'll find that easier than you might anticipate. Just think of it as adding attributes to a mesh.
Quote:.. 3D View will be for preview only..

That will really simplify things. As you say, you can add a "user 3D view" pane option later, if desired.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I'm working on a similar thing (see signature).

3D grid: lines. What do you mean by "no idea?" Can you render/transform anything in 3D?

point picking: I converted the world space coordinates to screen space coordinates, so all I had to do is check if a point is inside a small rectangle around the cursor (mouse point)

2D grid: lines. It's an infinite grid, but it's faked: I calculate the starting and ending line at runtime, so there are always a finite number of lines on the screen. I added a "level of detail effect": if the distance between two lines are smaller than a given value, the grid size will be multiplied by 10.
So the spacing is calculated by this formula:
(float)pow(10,(int)floor(log10((UnfoldView.zoom)*10.0))+1);

I did these grids in immediate mode, since the number of lines are controlled, so there will never be too many.

4 windows: It's not real windows, if you want the 3ds Max like system. It's 4 "viewports" Google "render to multiple viewports" or something.
Quote:Original post by szecs
I'm working on a similar thing (see signature).

3D grid: lines. What do you mean by "no idea?" Can you render/transform anything in 3D?



No you got it wrong i can render thigns in 3D infact 3ds Max kinda grid in 3D.
But i meant is it would be great if i can show Grid around 3D objects in perspective view something like in this screenshot -

My Game Development Blog : chetanjags.wordpress.com

A simple approach would be to draw the 3D object. Then draw the same object in wireframe.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Adding, removing and optimizing matter can be performed without rounding errors by letting large office buildings be a collection of axis aligned bounding boxes represented by 3 integer intervals. This is matematically the same as a 3D array of voxels in extreme resolution.

There are 2 basic rules to apply when reducing the number of boxes:

1. If BoxA and BoxB have shared intervals in 2 dimensions and touch each other in a third dimension, merge them into one box.

2. If BoxA and BoxB together forms an L shape, change who the middle part belongs to by random so that step one can be applied.

2D Example of how the 2 steps works progressively while you wait:
112402433Step 2111402433Step 1111400433Step 1111400400Step 1111000000Step 1000000000


This basic principle made my level editor both stable and easy to use because all I see is a set of voxels bounded by the range of the chosen integer type.
I can easily make a giant castle of voxels that would take months of crashes and gaps with polygon based geometry.

This topic is closed to new replies.

Advertisement