To all SSC Station occupants
Thank you for the donations over the past year (2024), it is much appreciated. I am still trying to figure out how to migrate the forums to another community software (probably phpbb) but in the meantime I have updated the forum software to the latest version. SSC has been around a while so their is some very long time members here still using the site, thanks for making SSC home and sorry I haven't been as vocal as I should be in the forums I will try to improve my posting frequency.
Thank you again to all of the members that do take the time to donate a little, it helps keep this station functioning on the outer reaches of space.
-D1-
ok, let's start it out.
what we need first is a idea, of course.
let's say we have allready a imagination of the ship
what i did first was to draw a little sketch,
it was that little, that i've lost it (a note).
but i'm pretty shure it wasn't much more then this
[attachment=658:rapier_sketch.jpg]
from the start i had the idea to create a model that should include most of the possible commands used for scripted models.
---
next step is to workout the model either on a grided paper sheet, mm grid, but .4 or .5 cm will work to, because we draw only integer vectors, or alternatively you can do that with a paint program to, just setup a grid for the project and make shure that it locks on the grid.
[attachment=660:rap_top_s2.jpg]
(the workout of a texture idea is not very important).
sorry for the bad quality, i did my best, but lead pencil is very bright after scanning.
personally i did the first model free handed, which means i just started to put the first parts together, but i guess for most it's better to make such a drawing or maybe two.
as you can see i noted on the drawing allready the main vectors of the model, so i have a idea of it's dimensions.
sadly i did a small mistake and the drawing is to small for the suggested units (wings should be 10 units wide but i counted only nine).
but that's more or less unimportant, you will see later how i fixed that, for the model it won't matter.
let's assume you did such a drawing for all 3 sides, i've only made a second one for the front and rear view of the ship (partwisely).
---
to make life easy for you i made a pic from the final mesh and wrote in the vectors.
[attachment=659:rap_wire.jpg]
HINT, print the mesh view with the vector number out and use it besides of your screen to find the right vectors.
if the most important vectors are known, you can start a script by localizing each vector you need for the first step.
you might wonder why only the right side of the ships vectors are numbered, we won't need more to start left side is simply the negative x value.
if you look at the pivot in center you see three arrows, red is for the x axis or vector, blue marks y vector and green z depth.
where you start to number your model won't matter much, but best use allways the same system, it will help you to keep in mind which way around you have to create the faces for the model (polygon winding).
usually i start at the front right side and number all RIGHT SIDE VECTORS EVEN and the LEFT SIDE VECTORS ODD,
this keeps your vectors list neat and clear to understand. you can make exceptions to that rule and sometimes you have to. usually starting at front is for left handed models, but it won't matter much, just use allways the same rule.
another thing you should know before you start is that you allready at beginning should think about which polygons build which part of the ship.
group the vector numbers for each part.
i.e. if one part finishes at vector 13, choose 20 to start for the next part, first, that leaves some extra space between,
second, it helps you later to find certain vectors of a part.
a lot of theory now before we really start. 🙁
left handed, right handed, what's the meaning of that?
there are two general ways to look at a model or a 3 dimensional geometry.
the system used is called Cartesian coordinates system, based on the ideas of Mr. Descartez who figured that out.
simplified that is just if you look at your hands, you have to spread thumb, forefinger and middle finger so each shows in one direction of the three dimensions.
-- the thumb points upwards marking +y
-- the fore finger points to you and shows +z depth (needs some agility).
-- the middle finger points then to the right side and marks +x
now you can turn the hand around (as far as possible) and you will allways know in which direction a vector is heading
that can help you sometimes if polygon winding is not to clear maybe.
---
why is that green arrow in the picture showing in the wrong direction?
simply because it's a left handed coordinate system that blender uses, like most CAD programs. you can make that proof by using the above system by looking at your left hand.
further many programs have depth (z) as height, i guess that is a leftover from architects who look at their models from top, while game worlds are defined by z as depth. but since you know now how that works, you can use your hands to evaluate what's x, y, or z.
do you recognized that right handed models will point away from you while left handed will point towards you, when you look at them from front (for models x points allways to the right and marks positive values)? yes, ok.
enough theory by know.
now something different, the models header.
this specifies your model for what it is being used and what specifications it will have
info = {
scale = .75,
lod_pixels = {.1,1,5,0},
bounding_radius = 15,
materials = {'cv0', 'grey', 'chrome', 'layer', 'matte', 'red', 'pit',
'win', 'glow0', 'glow1', 'glow2', 'e_glow', 'hole', 'squad'},
tags = {'ship'},
ship_defs = {
{
name='Rapier',
forward_thrust = -383e4,
reverse_thrust = 128e4,
up_thrust = 1e6,
down_thrust = -1e6,
left_thrust = -1e6,
right_thrust = 1e6,
angular_thrust = 2e6,
gun_mounts =
{
{ v(0,.5,-16), v(0,0,-1) },
{ v(0,0,0), v(0,0,1) },
},
max_cargo = 11,
max_laser = 1,
max_missile = 2,
max_cargolifesupport = 0,
max_fuelscoop = 0,
capacity = 11,
hull_mass = 2,
price = 35000,
hyperdrive_class = 1,
}
}
},
same .... again but with some explanations to each value
define_model('rapier', { -- here's the models unique name, it is important to have a unique one for each model or submodel you create/use.
info = { -- this marks the specifications table
scale = .75, -- that's the final overall scale of your model. needed because you remember we start with integer values mostly due to that your model is possibly far to big.
lod_pixels = {.1,20,50,0}, -- this and the value below go together, LOD is a abbreviation for LEVEL OF DETAIL. lod_pixels means simply visible amount of pixels on screen. so 20 means a size of 20 pixels for lod 2 everything bigger is lod 2 up to 49 pixels, then 50 marks lod 3 and the 0 means infinite (what is that .1 for you will see, usually it would be > 1 and marking lod 1)
bounding_radius = 15, -- this should encompass you whole model or part, with a wrong value the lod won't work right. further this is the boundary of the ship in shipyards view and the max. depth zoom in outside view.
materials = {'cv0', 'grey', 'chrome', 'layer', 'matte', 'red', 'pit', 'win', 'glow', 'e_glow', 'hole'}, -- this is a rather simple one, all materials used must be listed here
tags = {'ship'}, -- tags will define your model for what it is used, if it's a ship, a building or a spaceport
ship_defs = { -- here goes all the interesting tweaking stuff
{
name='Rapier', -- this is the name of the model as it appears in the shipyard
forward_thrust = -383e4, -- mostly self explaining since alpha9, "e" stands for exponent e.g. "^"( -383e4 = -3830000)
reverse_thrust = 128e4, -- thrust is in Nm
up_thrust = 1e6,
down_thrust = -1e6,
left_thrust = -1e6,
right_thrust = 1e6,
angular_thrust = 2e6,
gun_mounts =
{
{ v(0,.5,-16), v(0,0,-1) }, -- the positions of your laser guns (tips).
{ v(0,0,0), v(0,0,1) },
},
max_cargo = 11, -- defaults to 0 and will be entered usually, it represents the cargo capacity of your ship in tonnes.
max_laser = 1, -- defaults to 0, actually only 2 are supported by pioneer.
max_missile = 2, -- defaults to 0, up to 9 can be made visible on the ship.
max_cargolifesupport = 0, -- defaults to 1, i would disable this for all ships < ~80t. or show me where or how tonnes of people will find space in a fighter.
max_fuelscoop = 0, --defaults to 1, i would disable for fighters (< 30t), but it's your opinion.
capacity = 11, -- again cargo capacity, this one is used for commodities space, usually equal to max_cargo, defaults to 0.
hull_mass = 2, -- your ships hull in tonnes, defaults to 0
price = 35000, -- the price of the ship in whole credits, defaults to 0
hyperdrive_class = 1, -- hyperdrive class fitted at purchase, defaults to "none" (that's not the same like "0")
possible commodities
max_cargo = defaults to 0 and will be entered usually, it represents the cargo capacity of your ship in tonnes
max_engine = defaults to 1 and i can't see any use except you would like to have no hyperdrive.
max_laser = defaults to 0, actually only 2 are supported by pioneer.
max_missile = defaults to 0, up to 9 can be made visible on the ship.
max_ecm = defaults to 1, this is the missile jammer
max_scanner = defaults to 1, this represents the scanner you see in mid of the HUD.
max_radarmapper = defaults to 1, this will analyze targeted ships.
max_hypercloud = defaults to 1, used to analyze hypercloud remnants.
max_hullautorepair = defaults to 1, a special device using nano-bots to keep your ship in shape. i would set this to 0 for ships smaller then ~200t.
max_energybooster = defaults to 1, this will reload shields much faster (and for pioneer even the hullautorepair, i'm pretty shure).
max_atmoshield = defaults to 1, this is the heat shielding for atmosphere flight and keeps us out of trouble. setting 0 for tiny fighters makes it interesting.
max_fuelscoop = defaults to 1, i would disable for fighters (< 30t), but it's your opinion.
max_lasercooler = defaults to 1,
max_cargolifesupport = defaults to 1, i would disable this for all ships < ~80t. or show me where or how tonnes of people will find space in a fighter.
max_autopilot = defaults to 1, can be disabled to make some ships more hard to use
}
}
}, -- don't forget the commas!
static = function(lod) -- now we start
-- here goes all the models static mesh stuff
end, -- this ends the static function, the comma will tell the program that there is something following in the table, allways. a table is opened with { and closed with }
dynamic = function(lod)
end -- this ends the dynamic function
}) -- and this the whole model (eof, end of file)
but start of the first few vectors to localize
again,
local v0 = v(1,-.5,8)
local v1 = v(-1,-.5,8)
local v2 = v(2,-1,7)
local v3 = v(-2,-1,7)
local v4 = v(2,-1,-5)
local v4b = v(2,1,-5)
local v5 = v(-2,-1,-5)
local v5b = v(-2,1,-5)
local v6 = v(1,-1,-15)
local v7 = v(-1,-1,-15)
local v8 = v(2,1.16,-3)
local v9 = v(-2,1.16,-3)
local v10 = v(1,1.5,8)
local v11 = v(-1,1.5,8)
local v12 = v(2,2,7)
local v13 = v(-2,2,7)
local v14 = v(1,2,-3)
local v15 = v(-1,2,-3)
local v16 = v(1,2,-5)
local v17 = v(-1,2,-5)
local v18 = v(1,1,-7)
local v19 = v(-1,1,-7)
local v20 = v(.75,0,-16)
local v21 = v(-.75,0,-16)
local v22 = v(1.5,1.16,-3)
local v24 = v(1.5,1,-5)
-- that's all we need for the first few triangles and quads, they form our ships fuselage.
-- btw, use -- to mark a comment, use --[[ --]] --[[ if you like to close out a whole section
--]]
-- our first two polygons
-- body
--[[ comment to mark to which part the the poly(s) belong, this can be important, because if you later like to apply a texture, you might have to reorganize the polygons.
we could make a "quad(v0,v2,v12,v10)" for our first poly, but we go ahead and use "xref_" this will simply mirror the polygon, saves a lot of work and you see now why i write down only the rightside coordinates mostly --]]
xref_quad(v2,v4,v4b,v12) -- what? 4b, well sometimes you have to shift in a vector i told you i had no sketch.
xref_quad(v6,v20,v4b,v4) --[[ this is a problematic quad, it forms a "crease" and if the unseen edge of the triangles is rotated wrong the quad will "sink" in. but we started 6,20,4b that forms the first tri of the quad and that's why it comes out fine. i must say i did that one wrong myself (look at the mesh above) but as i wrote this tutorial i thought "is that ok this way? i guess not" i checked the model in the modelviewer by switching to collision mesh and "NO, it's wrong, the quad is folded wrong, to the inside". it's a nearly unseen one, because the difference between v6 and v20 is only 0.25 units (while v4 and v4b have no difference in horizontal dimension = x) --]]
-- some more from the side view
xref_tri(v12,v8,v14) -- and we got the complete side, except for the window, we do later.
crease is ok
[attachment=662:2011-01-16_174152.jpg]
crease is wrong, quad is sunk in
[attachment=661:2011-01-16_174310.jpg]
you miss something?
right the mesh has no material yet.
ok, we gave it one, put this right after the vectors list (leave some space, there are many more vectors to come).
blue?, red?, green?, ok a basic metallic looking one
set_material('n_cv',.45,.55,.6,1,.5,.5,.6,50)
what's that name "n_cv"?, short for non colorvariable, i use that one often, even for the mesh so i know later what material it will have and it is complementary to cv_0 and cv_1, which means colorvariable_0 (1).
ahh..., you like to have a colorvariable (random) material, well then you would have to add this under
use_material('cv_0')
"your mesh"
end, -- !
dynamic = function(lod)
set_material('cv_0', get_arg_material(0))
end
})
indent the lines please, that's why i chose the code form here, especially for if requests,
don't forget that ALL materials have to be listed in the header!
"dings"
if "variable2" < "n" then
"bums"
else
"dingsbums"
end
end
the machine won't need that, BUT YOU! it keeps things neat.
i guess, i can leave you alone with this, the rest of the fuselage is mainly the same quad, xref_quad, tri, xref_tri stuff.
before we go ahead a present.
to script a cockpit will be a real treat, so i build one in blender, using the output of the modelviewer (GLxtractor,OGLE).
i have another scripted model up, for which i will do a scripted one.
this i will offer you, the rest of the model you will have to script, it's not that much.
[attachment=663:2011-01-16_183133.jpg]
how to bind that in i will describe later, much later, but maybe some like to take a closer look at it 😉
i must be crazy, doing such a high detailed texture for a cockpit, you can't see half of it in the end...
Whoooaaaaa Gernot ... :ugeek:
That cockpit and pilot is just simply remarkable, outstanding and spitzen klasse to the n'th degree. The instrumentation is crisp and clear and very representative of the Pioneer HUD ... really cool detail to have the Rapier's outline shown in the instrumentation ... very neat! You have come back stronger than ever! Thank you very much Gernot for helping the community in this very benovelent way, your efforts are very much appreciated.
Thank you and all the best
a quick run through the rest of polygons needed for the body (complete including the previous ones
info = {
scale = 0.75,
lod_pixels = {.1,20,50,0},
bounding_radius = 15,
materials = {'cv_0', 'grey', 'chrome', 'layer', 'matte', 'red', 'pit', 'win', 'glow', 'e_glow', 'hole'},
tags = {'ship'},
ship_defs = {
{
'Tutandcommon',
{ 128*10^4,-383*10^4,1*10^6,-1*10^6,-1*10^6,1*10^6 },
2*10^6,
{
{ v(0,-.5,-16), v(0,0,-1) },
{ v(0,-.5,-16), v(0,0,-1) },
},
{ 11, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
11, 2, 3500000,
1
}
}
},
static = function(lod)
-- fuselage
local v0 = v(1,-.5,8)
local v1 = v(-1,-.5,8)
local v2 = v(2,-1,7)
local v3 = v(-2,-1,7)
local v4 = v(2,-1,-5)
local v4b = v(2,1,-5)
local v5 = v(-2,-1,-5)
local v5b = v(-2,1,-5)
local v6 = v(1,-1,-15)
local v7 = v(-1,-1,-15)
local v8 = v(2,1.16,-3)
local v9 = v(-2,1.16,-3)
local v10 = v(1,1.5,8)
local v11 = v(-1,1.5,8)
local v12 = v(2,2,7)
local v13 = v(-2,2,7)
local v14 = v(1,2,-3)
local v15 = v(-1,2,-3)
local v16 = v(1,2,-5)
local v17 = v(-1,2,-5)
local v18 = v(1,1,-7)
local v19 = v(-1,1,-7)
local v20 = v(.75,0,-16)
local v21 = v(-.75,0,-16)
local v22 = v(1.5,1.16,-3)
local v24 = v(1.5,1,-5)
-- excavation
local v70 = v(1,2,6.5)
local v71 = v(-1,2,6.5)
local v72 = v(1,2,3.5)
local v73 = v(-1,2,3.5)
local v74 = v(1,1.85,6.5)
local v75 = v(-1,1.85,6.5)
set_material('win',0,0,.05,1,1,1,1.5,100)
--[[ i guess that needs a short explanation,
first name the material 'win', then follows the values for R, G, B
in this case because it's a black shiny window thing r = 0, g = 0, b = .05 just al little bit of blue
the 4th value is the alpha channel and determines the opacity of the material
in this case 1 for opaque
next three values are specular colors R, G, B, we want to make something that nearly mirrors
so r = 1, g = 1, b = 1.5, 1.5? yes this is allowed and makes a strong reflection that fades to blue
next value is specularity level 1 - 100 here 100, don't use higher numbers here that causes a GL error
i know it would result in a very acute reflection but causes a error and we don't like that.
there would possibly follow three more values for the light emitting R, G, B, (glow).
--]]
use_material('cv_0')
-- side
xref_quad(v0,v2,v12,v10)
xref_quad(v2,v4,v4b,v12)
xref_quad(v4,v6,v20,v4b)
xref_tri(v12,v8,v14)
xref_tri(v22,v24,v14) -- a special one
-- top
xref_quad(v4b,v20,v18,v24) -- a crease!! very small, it's been smoothened by the program
xref_quad(v8,v4b,v24,v22)
quad(v10,v12,v13,v11)
quad(v12,v14,v15,v13)
quad(v14,v16,v17,v15)
quad(v18,v20,v21,v19)
-- back
quad(v0,v10,v11,v1)
-- bottom
quad(v0,v1,v3,v2) -- clockwise if you look at the bottom from top
quad(v2,v3,v5,v4)
quad(v4,v5,v7,v6)
-- front
quad(v6,v7,v21,v20)
-- filler, later scoop glow or whatever
xref_tri(v8,v22,v14)
-- window
use_material('win')
xref_quad(v16,v14,v24,v18) -- a dangerous one containing a crease
quad(v16,v18,v19,v17)
end,
dynamic = function(lod)
set_material('cv_0',get_arg_material(0))
end
})
ok, we got the fuselage ready
[attachment=436:2011-01-17_025857.jpg]
now it' time to learn something new and very handy
a extrusion, a command that allows us to build quick bodys from a base, people who worked with a CAD program will know this propably, there you "grab" maybe 4 vertices or edges and extrude them to a body.
this is similar to that.
since we have set_insideout(true/false), a cool tool to create simple excavations in a quad, without breaking the quad up to many tris.
HINT: extrusions won't work in y direction
first we have to specify the "base" quad for the extrusion
it's a bit different like what you see on the picture of the mesh, because i used separate quads, not to have wrong normals
when starting a extrusion clockwise to turn the inside out
it is v70,v71,v74,v75 and additionally 72, we need instead of defining new ones. i took the existing vectors from my first version, int won't matter here when it didn't starts in the centre.
extrusion requests some data
extrusion(vector start,vector end,vector up,floating scale,vectors for the base)
set_insideout(true)
extrusion(v70,v72,v(0,1,0),1,v70,v71,v75,v74)
set_insideout(false)
the resulting body will be extruded from it's base quad from vector start to vector end
we use a new material here "matte" it's specified as follows.
put this right under the previously set material ('win')
set_material('matte', .1,.1,.1,1,.3,.3,.3,5)
---
but i cant see no excavation in my ship!
wait, we're not ready yet
use_material('hole')
quad(v70,v72,v73,v71)
zbias(0)
yet, another material this one is fully transparent and when you call a quad or tri with this material before you call the poly that should be cutout with it, it will be cutout where the transparent poly is positioned, ok?
set_material('hole', 0,0,0,0,0,0,0,0)
goes to the list of materials on top, i would keep all set_material commands together, that only will help you.
so where does this polygon has to be called (in hierarchy of called polys).
right, before we create the 12,14,15,13 quad, or simply in front of what we have entitled with "-- top", but after our extrusion we have made. extrusion will stay now on top of our polygon calls and the "hole" will follow right after cutting out everything that follows.
use_material('matte')
set_insideout(true)
extrusion(v78,v79,v(0,1,0),1,v70,v71,v75,v74)
set_insideout(false)
--texture(nil)
zbias(1,v(0,0,0),v(0,1,0))
use_material('hole')
quad(v70,v72,v73,v71)
zbias(0)
it will look like this snippet
what we can do now before we do the more sophisticated stuff, is to assign a different material to some faces.
we want the front quad and the whole back end in matte material, that looks much better
our rearranged script looks now like this:
info = {
scale = 1,
lod_pixels = {.1,20,50,0},
bounding_radius = 15,
materials = {'cv_0', 'grey', 'chrome', 'layer', 'matte', 'red', 'pit', 'win', 'glow', 'e_glow', 'hole'},
tags = {'ship'},
ship_defs = {
{
'Tutandcommon',
{ 128*10^4,-383*10^4,1*10^6,-1*10^6,-1*10^6,1*10^6 },
2*10^6,
{
{ v(0,-.5,-16), v(0,0,-1) },
{ v(0,-.5,-16), v(0,0,-1) },
},
{ 11, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
11, 2, 3500000,
1
}
}
},
static = function(lod)
local v0 = v(1,-.5,8)
local v1 = v(-1,-.5,8)
local v2 = v(2,-1,7)
local v3 = v(-2,-1,7)
local v4 = v(2,-1,-5)
local v4b = v(2,1,-5)
local v5 = v(-2,-1,-5)
local v5b = v(-2,1,-5)
local v6 = v(1,-1,-15)
local v7 = v(-1,-1,-15)
local v8 = v(2,1.16,-3)
local v9 = v(-2,1.16,-3)
local v10 = v(1,1.5,8)
local v11 = v(-1,1.5,8)
local v12 = v(2,2,7)
local v13 = v(-2,2,7)
local v14 = v(1,2,-3)
local v15 = v(-1,2,-3)
local v16 = v(1,2,-5)
local v17 = v(-1,2,-5)
local v18 = v(1,1,-7)
local v19 = v(-1,1,-7)
local v20 = v(.75,0,-16)
local v21 = v(-.75,0,-16)
local v22 = v(1.5,1.16,-3)
local v24 = v(1.5,1,-5)
-- excavation
local v70 = v(1,2,6.5)
local v71 = v(-1,2,6.5)
local v72 = v(1,2,3.5)
local v73 = v(-1,2,3.5)
local v74 = v(1,1.85,6.5)
local v75 = v(-1,1.85,6.5)
local v76 = v(1,1.85,3.5)
local v77 = v(-1,1.85,3.5)
local v78 = v(0,0,6.5)
local v79 = v(0,0,3.5)
set_material('win',0,0,.05,1,1,1,1.5,100)
set_material('matte', .1,.1,.1,1,.3,.3,.3,5)
set_material('hole', 0,0,0,0,0,0,0,0)
-- excavation
use_material('matte')
set_insideout(true)
extrusion(v78,v79,v(0,1,0),1,v70,v71,v75,v74)
set_insideout(false)
--texture(nil)
zbias(1,v(0,0,0),v(0,1,0))
use_material('hole')
quad(v70,v72,v73,v71)
zbias(0)
use_material('cv_0')
-- side
xref_quad(v2,v4,v4b,v12)
xref_quad(v4,v6,v20,v4b)
xref_tri(v12,v8,v14)
xref_tri(v22,v24,v14) -- a special one
-- top
xref_quad(v4b,v20,v18,v24) -- a crease!! very small, it's been smoothened by the program
xref_quad(v8,v4b,v24,v22)
quad(v12,v14,v15,v13)
quad(v14,v16,v17,v15)
quad(v18,v20,v21,v19)
-- bottom
quad(v2,v3,v5,v4)
quad(v4,v5,v7,v6)
-- filler, later scoop glow or whatever
xref_tri(v8,v22,v14)
-- window
use_material('win')
xref_quad(v16,v14,v24,v18) -- a dangerous one containing a crease
quad(v16,v18,v19,v17)
use_material('matte')
-- front
quad(v6,v7,v21,v20)
-- back
quad(v0,v10,v11,v1)
xref_quad(v0,v2,v12,v10)
quad(v10,v12,v13,v11)
quad(v0,v1,v3,v2)
end,
dynamic = function(lod)
set_material('cv_0',get_arg_material(0))
end
})
one thing for shure this is not the last time we have to rearrange the script, textures will change a lot in the hierarchy of the model, since it is more important to call a texture if ever possible only once.
imagine you load a texture and project it from a angle to the model, it's only logical to arrange all polygons that belongs to this projection at one time. many changes in material won't matter compared to that.
further the whole mesh we created is present at lowest LOD to, but LOD 1 is used also as collision mesh to detect collision, hitting, with the object in the game. faces we don't "see" or have no effect on a collision we don't have to include to LOD 1 (i.e the cutout quad and the extrusion).
but even that we keep up until we have the textures, because then this stuff really starts to matter.
now we are ready to create the wings from a bezier flat, that isn't that hard as it sounds.
again our drawing on the grided sheet becomes handy
[attachment=455:rap_top_s2.jpg]
if you look close you can see a vector i noted in the right back outer corner
it has 32 as count
guess what this standalone point is for?
it determines the mid point of our first quadric bezier flat (i hope i didn't messed that up)
but there are two curves i can see...
yep, the second one is inside of the model, simply because the curve is turned inside.
because it wasn't so easy to find out on the paper where that is to place, i left it out and guessed one which i
corrected by looking at the result.
the whole bezier flat stuff is a bit complicated, but wait we help us with some basic principles known about bezier curves
a quadric bezier starts at one point and leads over a second point to the end point
[attachment=437:quadric_bezier.jpg]
a cubic bezier starts at a point and leads over two points to the end
[attachment=438:cubic_bezier.jpg]
there are a lot of principle graphics on the web, with some you even can experiment a bit.
the drawings are not very proper, but will show what's the idea behind.
well i figured out two possibilities for our flat
flat(divs,v(0,1,0),{v30},{v32,v34},{v36},{v28,v62},{v38})
flat(divs,v(0,1,0),{v35},{v33,v31},{v39},{v63},{v29,v37})
the crux behind the flats is that you will have to respect the winding order like allways
most of the time i get nearly a headake when i follow my intention and the result is looking like anything else as what i expected.
still i guess there must be a better solution as the above two.
well and here also becomes my fault i made by counting 8 instead of existing 7 units for the size of the wing
because i was aware that the quadric curve when drawn into a regular quad will describe exactly the radius
as a circle did when placed into the power of two sized quad.
or to tell in other words it should describe then exactly a quarter circle.
but, a quad one side 8 the other 7 isn't quadratic and the resulting bezier is "bended".
if it's just for the model it wouldn't matter and i guess for the model i calculated right, but because i used my drawing as template for the texture, it came out wrong (the texture).
well maybe we do a new one together in this tutorial which will fit, it has to. proper drawed coordinates of a meshs view
will have to fit to the mesh.
but it was even my first attempt to do such without a software in which you can easely place and size the mesh as you like on the texture.
should i go on? is anyone following?
i do anyway
let's get to the g spot
bezier flats, bezier quads and all the other aliens from the planet of geometry
we (i) had the idea to create a nice curved wing, how can this be made?
[attachment=464:rapier_wing3.jpg]
we could use something like this to get a point3 that will be close to what we like to get, but only close.
it looks and i should have known it it's not possible to get a proper quarter circle with a quadric bezier.
finally i'm not shure if we could reach that with a cubic bezier, it will allways just be close to, but never match exactly.
since it is that way its a bit hard and nearly useless to calculate that.
finally i would say we use still the quadric bezier and tweak what we got until we satisfied, thats enough imo.
i leave commands down here as they are, but it's not a good solution.
even that has given me some headake.
to use only one flat command is not very good and the flat never gets sectioned to triangles in the way i like it.
so it's better to use two flats one for the "outside" quarter and one for "inside".
this allows us to intersect it exactly how we need it and the shape is afterwards very smooth and has no wrinkles or gaps in it
so read the part below but it's not the final solution i will add a diferent one on the bottom of the post
ATTEMPT TO MAKE A WINGPART FROM ONE FLAT
now we have this strange command
flat(integer divs, vector normal, { v_line },{ v_quadric1, v_quadric_endpoint },{v_cubic1, v_cubic2, v_cubic_endpoint },etc )
it will allow us to make the wing in one take
first i have to explain the args it takes i guess,
in general { } marks tables of vectors here
if one vector stands alone in { } it marks the start of a line, if i would put i.e the above p1, p3, and p2 put each in a brace
i would get a tri filled with triangles according to how many divs i specified. that's not very useful but we need even lines to connect one curve with the other to get the final flat
if you put two points into a brace it will draw a quadric bezier, provided that there is a starting point previously
if you put three into a brace it draws a cubic bezier, same as above starting point previous.
the starting point of a bezier can be the end point of another bezier or a single line point, depends on what you like to get.
so we like to get our wing we have to start somewhere, but have to keep in mind that the whole thing must follow the counterclockwise winding order.
intentionally we would start at p5, draw a line to p1 and would lead the (quadric) bezier over p3 to p2 draw again a line to p4 and lead again a bezier over p6 to p7 the line from p7 to p5 we don't need to specify it's offens that the flat has to be closed to be filled.
i would like to start at p5 because it would fill the flat with tris with the curve between p1 and p2 as endpoints.
stop!
there is a problem the second bezier didn't follows the winding order and will be shown on the underside if at all
it would be nice if that would work so easy, but it doesn't.
really a problem one is counterclockwise the other clockwise if we just follow the outline.
it's not easy and i'm not fully satisfied with what i got in the finished model, maybe we find a better solution together.
what i did first is to start the curve at p1 leading over p3 to p2 and draw a line to p4 then leading the second bezier over p6 to p7 finishing with a line to p5.
but hey i thought we can't follow the line clockwise?
that's true but it's also important where the filling starts/ends
since we started at p1 the first bezier gets filled from p1 with the tris ending between p2 and p4
that is not bad but there is still a problem the first bezier crosses the second and that is pretty shitty.
this is because we have this line point p4 which will be taken as end point for the filling of the flat it has to be taken as end because the next bezier starts there.
that's not what we wanted.
another try
we start at the left side instead the rightside of the model
you would have to imagine our graphic is mirrored is that possible?
now we start with p2 and draw the bezier over p3 to p1,
but thats counterclockwise?
no, we are on the left side now, forgot?
next we draw a line from the end (p1) to p5 and a second one to p7 from there a bezier over p6 to p4
and it will be closed to p2.
this time the flat gets filled with tris starting at p2 and their endpoints are splattered between p3 and p1,
the second bezier gets filled from p2 with tris ending between p4 and p5 and a single tri p2, p5, p1, because it has to be closed.
thats neither a very beautiful one but has no crossing tris and no wrong winding neither it came out completely wrong and the normals are even proper (that could happen, don't ask what kind of flats i had before i found this one, none had looked like what i wanted, or it looked like this but one bezier had the normals wrong).
what i don't like at this solution is the filling between p2,p3,p1 and the single tri drawed by the lines, this produces a rift between them when the flat describes a height difference what it should on the top side, on the bottomside which is flat it doesn't matters.
but not bad for beginners, at least it works and i figured that out myself.
one cool thing is that when we close the back between the top and bottom wingpart with a quadric bezier quad we can use the same vectors as for the wing and it closes perfect, because a bezier curve will have allways the same radius when used the same vectors.
it's getting late and i guess i post the finished wing next time.
of course one who might have followed that perceptive could make that now himself.
the system is know and the vectors can be located on the top drawing if you simply count the cm grid, the height or thickness of the wing is more or less given by the body we allready have (0-1m).
of course one cm on the drawing is 1m(unit) on the model.
and if youre not number dislexia like i am, you will get rid of my mistake also and the drawing will fit perfectly as base for the texture.
FINAL WINGPART OF THE RAPIER
what i did now is to separate the flat into two commands, it looks far better then all we found out to this point
if you look at the collisionmesh you see that it looks allready very nice
[attachment=465:2011-01-22_034804.jpg][attachment=466:2011-01-22_035031.jpg]
even when you check the view from the side you can see all is in a good swing.
no more crazy big triangles which will make the wing looking bad from the sideview.
i simply split the flat command above into two commands
flat(divs,v(-.155,1,0),{v35},{v43},{v41},{v39,v37})
flat(divs,v(-.155,1,0),{v43},{v35},{v33,v31})
we have now one forming the "outside" quarter circle and
one forming the "inside" quarter circle.
the vectors havn't changed so we can use the same data as before (mainly, to fit the wing to the texture we have later to tweak that a bit)
of course you could leave it that way it's nice also, but since i have a texture with a given curve of a circle, we would have to fit that to it.
to draw the texture after the bezier is quite more complicated from my point of view, because we would have to draw a bezier curve instead of using just a circle as base. some classic drawing programs allow such of course, but the program i use is not a drawing program, it's a paint program.
where's the difference?
drawing programs use lines and bezier curves and you can set and move the knots where you like to have them until your curve has the right shape.
in pure paintbrush you won't have such, you can maybe draw a simple bezier line, but you can't move the knots neither you can grab and strech the extensions of the knot.
more recent paint programs allow both, but i must say i didn't own one and also they have other disadvantages to my old Picture Publisher. mostly it's how they use masks and objects and foremost because they loose the negative masked part of a texture when you transform the picture (resize it) and that's bad and useless for me because i use often negative masked textures to make special things like little outspared flats on a shape that stay in a different color to the base color of the shape. further i work since a long time with it and don't have to think a second where to find a tool i need,
while in other programs i can't find them or have to search for them each time i lke to use it, this is frustrating.
well, i guess they think a negative masked part isn't good for nothing except to make something vanish.
but for textures it isn't that way, you need it to make transparency, but maybe a controlled one not simply i don't need the negative part. i like to blend materials maybe or the described "cutouts".
i would use the GIMP, but exactly this is the reason why i didn't use it (maybe i should tell them my problem).
i'm also not very common with how they use objects, but also this is a strongly used feature by me.
i workout my textures in several layers, this allows me to change a layer without touching the rest of the texture.
but i guess i jumped to far from where we are now
(btw, some might have noticed that allready, sometimes my textures look like there is nothing on them in a preview, thats because the most of it is set nagative, because maybe only a engine part should stay positive to get a certain material afterwards)
(usually i will loose all what you didn't see here when resizing the texture, but you know the cockpit of the rapier and there is something, the positive part is only for the glow).
---
you could alternatively paint your texture without exact boundings, so it will fit no matter how the curve is and leave the data in the localized vectors as it is.
yup im following a good idea cant add much in the way of programming but if u could get it into the game in some way im sure all those silent peeps downloading it would much appreciate it
no i won't upload the rapier, not before some have done it themselfes, i like to see what comes out. 😀
for the rest of my models, i know should post it to the repository so the stuff is ready with the next alpha release for all and you don't have to download fixes for fixes of fixes.
but exactly that's why i hold them back, when all is working proper then i will.
but theres a lot that isn't finished, some missing still good textures, some can be made "slimmer", others need animations, cockpits, extras.... and... and... and... 😯
I don't know if this is an appropriate place to post a thank you because it might disrupt the lessons, but, Thank You! I will learn from you my Jedi Master!
no, no, a post from time to time will only show me that i'm not sole.
this time we do it better and count the distance right, right?
that will give the ship a bit a different look, because the wings will be 1unit smaller
local v31 = v(-2,1,7)
local v33 = v(-9,1,7)
local v35 = v(-9,0,-1)
local v37 = v(-9,0,-5)
local v39 = v(-9,0,0)
local v41 = v(-5,.5,-1)
local v43 = v(-2,1,-1)
these are the vectors we need for the leftside wing top, a rightside side we don't need, because we use xref_again.
we could for shure make each wing separate, but it's not easy or you won't find a possibility at all to make the same wing on both sides, because of the winding order. but when the part get's mirrored with xref all is fine.
one disadvantage to that, we HAVE to texture the whole top with one texture, because the xref_part will act like one part.
leftside this time?
yes, remember we didn't found a good solution on the right side, there is maybe one that looks the same, but using xref is much simplier rather to try and try until you find the same on the other side.
i was shure, i couldn't find no proper way to do the eagles body single for left and rightside, but after i played around with the flat command for the rapier i found one, so it is possible, but a mindbender to do so.
i will try this once on the eagle to see if the flat gets a better surface because i'm not fully satisfied with it (it's not 100% FE2 compliant).
since in fe2 normals are specified for each vertice and not given, you can make a flat there that follows once clockwise and once counterclockwise winding order in ONE FLAT. there are other reasons he did it this way and also the reason why sometimes parts simply vanish for the eye before they should because the normals reached the the limit for their side.
but he saved a lot of processing time with that in '93!
and things have gettin much better since we have the set_insideout command, makes life easy end you can have a flat
that works the same way on both sides, just turn it insideout for one side and all is fine. i guess that works similar to xref, except each part stands alone now and you could use the same (half) texture for left and right side, if wanted.
this would make our texture much smaller.
it is to remark here that the BEST way to texture the model would be each part get's his own little texture, we will see later if we can cut them out of our map we drawed and applie to each part. using a large top view like we have now
wastes a lot of unused texture space. but if we separate the body from the wings after we painted our texture, most of the unused wasted space is left aside. that is in our example HALF of the bitmap.
if you look at models like they are made in older games, each little part, sometimes only a few polys, have their own texture. that's much better rather to use a large single view. of course the way we do it here for a scripted model not as easy as if you would build it with a CAD prog. but let's say therefore more sophisticated, working with a CAD prog. everybody can learn and splitting up the texture for even each poly is only the pressing of a button away today.
the second advantage to that is that you can use the same snippets for many models, let's say we have a race track like i made once one. and you like to have many different looking buildings on trackside, you can use i.e. allways the same or same few windows, walls, roofs and so on. that sounds overaged but it's still allways better to save as much processing time as you can. it is maybe to think about if we shouldn't stagger appearing objects in groups/sequences like it was done in end 90's for racing games. all that is unseen then will not be processed before it comes to visibility, or to tell in other words it makes no sense to render whats behind a turn before you are in mid of the turn so you can see whats behind. one reason why old sports car runs much more fluid as NFS3 or 4 who are aged the same. you won't have this occasional stuttering when it comes to render a lot of new stuff if you split the sequences at the right point, something i hate when playing a racing game. further there is this big difference of how they are textured NFS uses a (small) single texture for the whole model, SCGT uses textures for each part like discribed, in the end the texture could be sized bigger over all, but uses less processing time. unfortunatly i glued my texture for the "tudor style house" or the chappel, i posted in very beginning here, together. i still belive it would be better if i had used the original i made for the SCGT track.
but i converted simply what i did with it for FFED3D and there you have to use one texture for the whole model.
i'm shure some miss the chappel in city3k, maybe it appears once as a "museum" into a archology, best would be and still a wish of mine, at least two different types of cities, so we could have buildings for planets with breathable atmosphere and place the nice ancient buildings there including the factory with the chimneys, a wind power plant, bridges and whatever that is common here on earth (it is to think about streets to and you could animate little vehicles that appear from time to time and drive around in the city, not to much just a few from time to time. as well as one for the cities on all planets that has no or no breathable atmosphere and use the archologies, plantation domes and so on. it is planned by me to let the shuttle land and start from the 3k factories as animation, but not easy if at all on a seeded city because you won't know where they appear. second then i thought hey you could make tiny spaceports of them, let's say for the less inhabited worlds cities, no big spaceport and you can land there only with small ships. the original planned size of the factory is a bit larger as it is now and a good pilot can land on them, i tried once, all is allready included to the model.
enough Utopian, let's get back to work, let us make the wing now
i reworked the topview so it's better to identify the vectors on it also i updated it to what we have now
[attachment=456:rap_top_s2.jpg]
xref_flat(4*lod,v(0,1,0),{v35},{v33,v31},{v43},{v41},{v39,v37})
again a few words to that command, first we have to specify of how many tris the flat will be made of, respectively how many divisions it becomes. you could enter here just 16 i.e. but that's not clever, because it would have then allways 16 divisions (each section of the flat) no matter if the object is near or far. but we have in Pioneer a LEVEL OF DETAIL, short LOD. this allows us to give any bezier surface as much divisions as it's useful at a certain distance, same goes to so called "primitives" as circles, cylinders, tubes, spheres and the new thing we have, lathe.
that's why here stands 4*lod, that means at closest (lod4) we get 16 divs, at farest view (lod1) 4,
let's say we use often the same divisions, then we can localize the divisions and write something like this, best at end of the localized vectors;
local divs = 4*lod
now we can use simply "divs" each time we need for our model such.
xref_flat(divs,v(0,1,0),{v35},{v33,v31},{v43},{v41},{v39,v37})
of course that makes only sense when you use often the same amount of divisions (usually you will).
the next thing here are the normals we have to specify for the flat, even if we have the winding order as important factor for the normals this is a bezier flat and it gets allways flat looking normals. you can manipulate them a bit with that let's say when our part is inclined to one side. without a control over the normals they would be straight in the direction of the view you build your flat (x,y,z) and shading will become like a plane that faces in this direction. but if you enter the inclination degree here it will be shaded like it's inclined (or declined?).
that's in this case v(0,1,0) for straight upwards, maybe we can tune them a bit because our wing top is inclined a bit.
let's see how far we are now with our "flügerli" (swiss for airplane).
[attachment=457:2011-01-19_160210.jpg]
you can see that our bezier flat has exact the same normals as all the rest of the quads that are facing straight upwards.
let's tune the normals a bit,
xref_flat(4*lod,v(-.15,1,0),{v35},{v33,v31},{v43},{v41},{v39,v37}) (that was guesswork)
[attachment=458:2011-01-19_160800.jpg]
not bad, at least not longer straight upwards.
one couls calculate th inclination proper and enter it to the normals vector.
that would work this way,
we have in the vectors v(x,y,z), if we do this v(0,1,0) that means upwards, v(1,0,0) means to the right and v(0,0,-1) to the front.
we like to incline it exactly how it's in the model, what can we do?
ok, first we must know some more basics, for 1, wherever that stands (for normals or vector up when you see such), we can assume 90°to the next value (not easy to explain), v(1,1,0) as example would mean 45° to the right.
v(-1,1,0) to the left or to give a example on our wing the normals would be inclined 45° downwards.
that sound more complicated as it is. try to play around with that and you will understand, you can take this idea as
helper, you look from the back to your ship and pull on the wings normals in the direction you specified, because z axis is untouched it is like they rotate along z they can't go any other direction.
another example take a sheet of paper and look at the edge of it in horizontal alignment (so you see only the edge), now try to pull the right end of the sheet to left what happens? the sheet get folded downwards (or upwards).
i guess with that we can work, at least we have something we can feed a caculator with.
to evaluate the inclination of our wing we need a drawing.
interruption.
one clever lad could create from the vectors and commands used here a replacement ship for FE2/FFE.
you would just have to find a fitting one that offers enough space to hack the new verts in and create new polys.
the principles are the foremost the same only that all is in hex code, but once you know what maybe 0x0010 stands for under a certain adress, it's possible. thx again to jongware, he created a little proggy that spits out all models of FFE in text form
with additional explanation to what each (most) byte stands for. there is a risk, some data is unknown, or points to special tables somwhere else in the program, so it's impossible i.e. to change the type of thrusters in the code for the object, there are different types in FE2 some have 4 some 6 thrusters others no or only 2 (worst of all they arn't allways identical in FE2 and FFE) and thats not only for the visible part of the ship, some you have no manual control over the thrusters some you can control all of them single. but just for fun, why not?
maybe as a side trip i will start such and see what comes out.
my very personal FE2 ship 😉
a extreme simplified method to evaluate the angle...
[attachment=459:rapier_wing2.jpg]
7 units wide
1 unit high
if we had
7 units to 7 units then we had 45° right?
and if i'm not nuts, 1 unit is 45/7 = 6.428...
because the relation for 45° is 1:1
we divide 1/6.428 = 0.155...
you see my guessing wasn't bad (in fact i used 0.2 first, checked the model in the viewer, but i wasn't satisfied. construction worker hm? yes, if you had worked 25 years as a construction worker you wouldn't measure things with a balance a circle and a plummet, you measure things by the eye).
i guess mathematicians will get a laughing clamp, but well it works and it works also if you like to know the value for a certain rotation of a part, basta.
---
apropos CLAMP
and if you like to know the rotation when using Matrix.rotate for a imported .obj you can use
Matrix.rotate("target rotation " * pi/360,v(rotation axis))
that can be very helpful and you can animate a part allready when loading it with
local rot = target rotation * (math.pi/360)*math.clamp(get_arg(0),0,1)
and
Matrix.rotate(rot,v(rotation axis))
why all this math.clamp stuff (some don't use it)?
simply because get_arg(0) outputs 0 to .99 and not 1
if you use math.clamp the value is math.clamp("start value","end value") whatever that might be, i.e. 0.00 to 1.
the output is 0.00 to 1!
a slight difference of 0.01 but when multiplied it can be a quite big difference.
if you like to stop the animation at a certain timepoint, i.e. the flaps for the U.C. use "math.clamp(get_arg(0),0,0.3))"
now the output is 0.00 to 1 in the timespan of 0.00 to 0.30
if you like to start i.e. at timepoint 0.30 let's say because the wheels should not get in conflict with the animation for the flap use math.clamp((get_arg(0)-0.3),0.3,1) and results in 0.00 to 1 in the timespan of 0.3 to 0.99
(usually i use the third part of the full animation time for the flaps and the left two thirds for the wheels, that makes sense, if you have space enough between flaps and wheels you can set the wheels startpoint a bit earlier or the flaps endpoint somewhat later, which looks very smooth then).
this is a real good method to rotate your parts when you make a model with a CAD prog.
rotate the part in your CAD, check where you can read out the transformation/rotation values (somewhere for shure).
use the value your CAD gave you as value for the rotation of the part in the above ways either one or the other.
no more fiddling around or testing needed.
ja, ja, danke, danke, bitte, bitte 😆
has cost me some time to find that out, usually it did it by trie and error until i had ENOUGH of that.
---
but we make a scripted model and this was just ment as a general advice for all that make models here for pioneer and like to animate them.
I'm digesting your tutorial more slowly than you're feeding it to us, but I read through the part describing how to place vectors and put quads on them. It now makes sense! I'm using this tutorial to learn how to make things for Pioneer, and
It. Could. WORK!!!
[attachment=460:youngfrankenstein.jpg]
Hardcore man, hardcore. impractical but worth having an understanding of, certainly makes one appreciate a nice graphical interface.;)
yup, i had the idea to, would be great to have a pioneer lua CAD, such could be made i guess.
but apart from that i love the very "ancient" way to build models, they feel so "lightweighted" and have some advantages to "stiff" objects, you can control each vector of any poly, that makes them very flexibel.
morphing is just a "few keystrokes" away.
i overhauled my rapier, while i was working on the tutorial
the cockpit is now scripted to (except the pilot).
well the wings, sides and bottom is missing now, i've also made new textures for it (uff!).
texturing i mean the final attachment is a horror sometimes, the only thing you often can't predetermine and needs many tries until they are placed right. but it's cool painting a view of amesh on a paper and to see it works afterwards.
i know the same would cost only the 100th of the time with a CAD, but that's "lame", just exporting the UV.
even when i done that often to for scripted models, exporting from the viewer using OGLE, loading the mesh to blender and export uv data.
but i want to show here that all can be done without a CAD program.
if it comes to "normal" models a blend of both is best i guess, you can use the advantages of both, stiff simple meshes can be done on the CAD, bezier and dynamic stuff, scripted.
anyway i love the scripts, you can load a model to the game like nowhere i guess.
i.e. the trees i used for the archology, only TWO models (.obj), but when setup as function you can squeeze or strech them over each vector, each looks different.
there is one little disadvantage, i.e. when you create a body from a primitive such as a sphere or a cylinder you can only map the texture from one side. ther is no way to place the polys single on the texture. but maybe we have once something like a cylindrical texture projection, that would help.
marcel, try to workout the rapier step by step, i guess it will work (hopefully). just "copy" it.
after we finished, then i guess you're not far away from your first own.
fortunately, you wont have to think about the Undercarriage, there is one on it's way you can use for any ship with a flat bottom. call the function with a few arguments and length, width, heigth, wheel size, everything is like you need it.
i will even make it possible to predetermine a simple texture as long as the texture follows some standarts.
same goes to the materials then, you would have to use the names used in the function, therefore you can determine afterwards the flaps material, the recess' material as well as the material for the piston and arms.
or just use a finished submodel that will include standart textures and materials, this you can take then also as a template how to call the function. the cage or recess how it dan calls, will have a "cut a hole" poly like the one i presented here by default, so it's open allways as soon as the UC is called (as long as called at the right position in hierarchy). but gimme some time to finish it, i guess the overhauled rapier will include the function (or i try to set it up soon, but first the bottom texture has to be made new).
one advantage of the "flexible" UC is you can paint the flaps before you model them, position and size the UC after it and use snippets from the big texture for the flaps, but we will see.
my gunboat uses a close to the final function UC allready, but i stopped to work on it, because of the overhauled rapier.
the pistons are a cheat, only a texture that moves and stretches together with a tapered cylinder 😉
another hint, if you work on a scripted model you will use the modelviewer heavyly, so best is to copy complete pioneer to a different folder, remove all models except the one you are working on, you will see the viewer will load much faster, because he didn't have to load all the models then (aternatively you can zip them to let them get ignored).
(something funny, when i look at a pic from the modelviewer, i allways like to turn the model around 😆 )
Once again, excellent work! I'll fly that Rapier proudly, like someone who assembles his own airplane from a kit!
I have an idle thought. What is the frame-rate difference between a scripted and cad model? Assuming the number of polygons are the same, does one render faster than the other?