Jump to content
The Dark Mod Forums

Attachment Positions


Springheel

Recommended Posts

I'm trying to get the new candles working with holders but I'm having a little bit of trouble figuring out how attachment positions actually work.

 

I've read the wiki page but it still isn't clicking for me.

 

Here's how the attachment positions are listed in the candle entities, but I find the comments confusing:

"def_attach"			"atdm:moveable_candle_default_unlit"

"pos_attach"			"candle"		// At the attach point called "candle"...

"attach_pos_name_1"		"candle"		// ... which is defined here.

"name_attach"			"candle"		// Set a name to pass along spawnargs

"attach_pos_origin_1"	"0 0 10.5"		// Offset the candle X units in the Z direction

 

My questions:

 

1. Does the name listed in "pos_attach" only affect that specific entity? Does it matter if two different entities have a "pos_attach" "candle", for example?

 

2. What is the purpose of "name_attach"? I don't understand the difference between it and "attach_pos_name_1".

 

3. "attach_pos_origin_1" offsets the attachment point from the origin of the model, correct? Does this need to be defined on every entity using this attachment point? Can "candle" be defined differently on different entities?

 

4. If I wanted to put an offset on the thing being attached to the attachment point (a candle, in this case), how do I do it? The wiki says to use "origin_new_pos" and "angle_new_pos", but that didn't work when I tried it. I assume you have to work the name of the attachment position into those spawnargs somehow, but I'm not sure how. Should it be "origin_candle"?

Link to comment
Share on other sites

I should probably update the wiki page myself, haven't had time to do that yet. I don't think the comments in that def file are entirely correct.

 

To answer your questions:

1. Does the name listed in "pos_attach" only affect that specific entity? Does it matter if two different entities have a "pos_attach" "candle", for example?

Pos_attach is supposed to go along with def_attach. It is the spawnarg that defines "For this entity that I'm attaching, where is it going to go on the entity I'm attaching it to?"

 

For example, say you want to attach a dagger and put it in the hand position (that you've defined somewhere else)

 
"def_attach1" "ai_weapon_dagger"
"name_attach1" "melee_weapon"
"pos_attach1" "hand_right"

 

If you give more than one def_attached entity the same pos_attach, that means they're attached to the same position on the entity they're being attached to. This might be okay in some cases where two entities are referenced to the same point and modeled so that they don't overlap with eachother, like say two necklaces that both hang off the neck, or a dagger held in the hand and a ring on the same hand both referenced to the center of palm position.

 

2. What is the purpose of "name_attach"? I don't understand the difference between it and "attach_pos_name_1".

Again, name_attach goes with the object you are def_attaching, no the position you are attaching it to. It is optional, and it sometimes gets used by animations or other code to refer back to the attached object. For example, the re-attachment code. Suppose you attach two daggers and want them to draw one while leaving the other one. How do you address which dagger to draw and which to leave sheathed? They all haven't spawned yet so you don't know what the entity names will be, and they both have the same class name (ai_weapon_dagger), and the position they're attached to is going to be changing (one will go from sheath to hand, etc). So you can't use any of those things to reference them with certainty. The answer is: Give them a unique attachment name, this is the name_attach spawnarg.

 

"attach_pos_name_1" is the name of the attachment point you've defined elsewhere. For example, on a candle holder you've set up an attachment point for where the typical candle origin will go. You want to name it "candle", use attach_pos_name.

 

3. "attach_pos_origin_1" offsets the attachment point from the origin of the model, correct? Does this need to be defined on every entity using this attachment point? Can "candle" be defined differently on different entities?

For non-MD5 models, that is correct. It is defining where this attach position will be relative to the origin of the model. This all applies to the entity getting something attached to it, so it is not set on the entity that will be attached. For MD5 models like AI, it's the offset from the joint you specify in attach_pos_joint, not their origin.

 

It does not have to be defined on every entity being attached to this attachment point. It does have to be defined on entities that will have things attached to them at that attachment point. If it's not defined, it just defaults to their origin. It is inherited though, so hopefully it can just be defined on a parent/base object. In other words, it's defined on the candle holder, not on every single candle you're attaching (but on every candle you're attaching, you do have to at least put in the name of this attachment point so that it knows where to attach).

 

4. If I wanted to put an offset on the thing being attached to the attachment point (a candle, in this case), how do I do it? The wiki says to use "origin_new_pos" and "angle_new_pos", but that didn't work when I tried it. I assume you have to work the name of the attachment position into those spawnargs somehow, but I'm not sure how. Should it be "origin_candle"?

I don't have access to the source right now to check those spawnarg names, unfortunately, and I won't be back home until Wednesday. You're right that it has to include the attach position name in the attached entity spawnarg. origin_candle may be right. But I don't remember exactly, it could be origin_pos_candle or origin_candle_pos.

Link to comment
Share on other sites

The overall conceptual view is this:

 

Attach positions get defined and named on the entity that will have things attached to it (e.g.: a candle holder or a guard). The positions are set up with some general attachment in mind, like a candle or a weapon held in the hand. The positions define where the origin of this attached object will be by default, and should be set up so that most of these types of objects attach in a way that looks right.

 

When you def_attach object 1 to object 2, you get to decide which of object 2's attach positions to use. For example, attaching a dagger to a guard, do you want it to attach to a hand or a hip sheath or leg sheath, etc.

 

Since the obects that will be attached are not all modeled the same, you can set position-specific offsets on them. For instance a special dagger might say "When I'm held in the hand, I need to be 2 units over compared to all other daggers." So in that dagger entity's def file, you define an offset on this particular dagger that only applies when it is attached to the "hand" position.

 

Since all AI are modeled a little differently, you may need to slightly adjust the hand position on each one. For ease of maintanence, you can use the inherited hand position and just add an offset to it, rather than having to maintain a completely different set of coordinates. For example, a fat AI might need new belt attachment positions that are farther out, but rather than figure out these coordinates from scratch you can just inherit the belt attachment positions of the default AI and write in a small offset.

 

This system replaced the old one where you couldn't have more than one attachment position and you had to define a new set of coordinates on every entity for every possible entity it could be attached to.

Link to comment
Share on other sites

"attach_pos_name_hipsheathl" "hip_sheath_l"

"attach_pos_joint_hipsheathl" "Hips"

 

I think I've got the gist of it. I don't understand the above, however. What is "attach_pos_name_hipsheathl"? What is the significance of "hipsheathl", when the defined name is "hip_sheath_l"?

Can I just use "attach_pos_name_whateverthehellIwan

t" when setting a new attachment point?

Link to comment
Share on other sites

I think I've got the gist of it. I don't understand the above, however. What is "attach_pos_name_hipsheathl"? What is the significance of "hipsheathl", when the defined name is "hip_sheath_l"?

Can I just use "attach_pos_name_whateverthehellIwan

t" when setting a new attachment point?

 

Yeah, you can call that label whatever you want, as long as it's a unique name. It could be 1, 2, 3, etc, but that would get confusing with inheritence, so I thought it would be good to keep a fairly descriptive name.

Link to comment
Share on other sites

  • 1 month later...

Obviously I still don't understand exactly how these work. I don't know why I can't wrap my head around it. :wacko:

 

Once an attachment point is set, how do you tell a prop to use that attachment point? Right now, our attachable props still use the old method, where they reference a joint.

 

The only things that use the new attachment method (that I can find) are hats and weapons, both of which are built into the entity, and seem to use 3 separate spawnargs.

 

"def_attach1" "atdm:moveable_longsword"

"name_attach1" "melee_weapon"

"pos_attach1" "hip_sheath_l"

 

But those spawnargs are attached to the base entity (that carries the object). Suppose I then wanted to add a hammer on his back as well. Would I have to type all three key/vals into the entity editor? That doesn't seem right.

 

I'm actually trying to make some attachment points for the belt, for keys and purses. But I can't even get started, because I don't know how to tell a purse entity to use the new attachment point.

 

If I want to make a belt purse entity, how do I establish that it should use a belt attachment point? With the normal def_attach system, I would add "joint" "Hips" to the purse entity. How do I do it with the attachment point system?

Link to comment
Share on other sites

I never wrapped my head around it, either, so I cannot help much :blush:

 

So far I only ever attached things to entity by defining the attachement point on the entity, then telling the entity to def_attach another entity on the point just defined. However, these points where all relativ to the entity origin, not some joint on it...

 

Edit: I think you need:

 

* define an attachment point on the base entiy, give it a name, a joint and a possible offset:

 

def/tdm_ai_head_base.def
16:		"attach_pos_name_velvetcap_1"						"velvetcap_1"
17:	 "attach_pos_joint_velvetcap_1"				  "Head"
18:	 "attach_pos_origin_velvetcap_1"				 "0 0 0"
19:	 "attach_pos_angles_velvetcap_1"				 "0 0 0"

 

Then you can attach any entity to "velvetcap_1" and it will land at the correct position. But I have no idea how to actually do that, and I have no idea how to modify the position of the entity to-be-attached if it should have a further offset...

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Then you can attach any entity to "velvetcap_1" and it will land at the correct position. But I have no idea how to actually do that,

 

Yeah, that's where I'm stuck too.

Link to comment
Share on other sites

I also cannot figure out how to rotate attached entities (like the torch, which is seriously off) without rotating the attachment point itself, which seems to defeat the point. The examples on the wiki page are not working for me.

Link to comment
Share on other sites

But those spawnargs are attached to the base entity (that carries the object). Suppose I then wanted to add a hammer on his back as well. Would I have to type all three key/vals into the entity editor? That doesn't seem right.

That's correct, all those spawnargs are on the "base" entity, the thing that's being attached to, not the item you're attaching. When you attach a new item to some position, you need at least these two args on the thing that you're attaching to:

"def_attach1" "atdm:moveable_longsword"
"pos_attach1" "hip_sheath_l"

That says what entity type you're attaching, and what position you're attaching it to. EDIT: For example, say you had two positions relative to the same joint, like a dagger on the belt to the left of the spine joint, and a second position on the belt to the right of the spine joint. In the old system, you couldn't do that. The dagger would have a "joint" argument on it, and that's the only joint it could attach to, and it only had one offset from that joint. You would have to make two different entityDefs for a dagger attached in two different places, and that quickly becomes a disaster to maintain. In the new system, you can define different positions on the AI that are relative to different joints or even different offsets from the same joint, and then specify the position you want to attach the item to right after you say which item you're attaching, in the AI spawnargs.

 

The name_attach1 is optional, only really needed if some code needs to refer back to specific attachments (like if you want to have the AI grab them off their body and into their hands later on, so you need reference names for the "reattach" command).

 

The position offsets and orientation data is on the attached-to entity, (in the attach_pos_* spawnargs) but to offset certain entities relative to those default positions, you can add offsets on the attached entity. The wiki page left this out. (I also noticed the wiki page didn't say what entity any of the spawnargs go on, hence Spring's confusion). The optional spawnargs on the attached entity are:

origin_<position name>
angles_<position name>

 

So you can define a position that's at some easy reference point on the belt, like right on the outer surface of the belt, vertically in the middle, horizontally on the right hip. Call that position belt_righthip. Now, suppose you want to attach both purses and keys to this point. Purses work fine on the default position, but keys were modeled differently and need to be rotated or offset to look right when attached there. So you use the belt_righthip position on the AI spawnargs next to the def_attach for both purses and keys. Then on the attached key entity spawnargs, put in

origin_belt_righthip 0 -2 0
angles_belt_righthip 90 0 0

This tells keys how to orient themselves with respect to the point you defined on the AI (so relative to the outer surface of belt, vertically in middle of belt, horizontally on right hip, how should keys and purses be oriented/offest?)

 

That way, different AI with different bodies can move the position around in their def file (fatter AI has the belt farther out compared to their spine joint, for example), but purses and keys can still keep the same offset to that desired position, they don't need to know what AI they're attached to.

 

Finally, there's a feature where if an AI's attach position is slightly different from the base class positon, you can define it as an offset to that position rather than absolute coordinates. This isn't mandatory, I'm not even sure it's needed, but might be easier to maintain than several sets of absolute coordinates.

 

The way to do that is, in the AI spawnargs:

attach_posmod_name_1 <name of position you're modifying on this AI>
attach_posmod_origin_1 <offset from position origin>
attach_posmod_angles_1 <rotational offset from position orientation>

So it's basically the same as the attach_pos definition, but uses posmod instead to make it relative to a position you've already defined, for example, on an inherited def like humanoid_base.

 

You can still use the old attachment system if you've got an entity that will only ever be attached to one thing in one place. It's less flexible but a little faster to set up in that case.

Link to comment
Share on other sites

That's correct, all those spawnargs are on the "base" entity, the thing that's being attached to, not the item you're attaching. When you attach a new item to some position, you need at least these two args on the thing that you're attaching to:

 

"def_attach1" "atdm:moveable_longsword"

"pos_attach1" "hip_sheath_l"

 

 

Ok, I can see the benefit to us when setting things that are attached by default, like weapons or armour, but what about something like keys? How is a mapper going to know what the "pos_attach1" name that they should use is, if it isn't on the attached entity? Is there going to be some kind of a master list somewhere for them to look it up?

 

Also, how does a mapper know what number to append to the "def_attach" line? Some AI already have 3 things attached to them by default...if I say "def_attach2" on a builder guard, I'll replace one of the pauldrons. Will they work if I type them both in without a number?

Link to comment
Share on other sites

On every AI I've used, plain old "def_attach" has always been open. Pauldrons and amulets have always started with def_attach1/2/3.

 

If they want to double-check, they can open up in DR's entity box "view inherited properties" and they can scroll down to the def_attaches to see what item takes up what number.

yay seuss crease touss dome in ouss nose tair

Link to comment
Share on other sites

Ok, I can see the benefit to us when setting things that are attached by default, like weapons or armour, but what about something like keys? How is a mapper going to know what the "pos_attach1" name that they should use is, if it isn't on the attached entity? Is there going to be some kind of a master list somewhere for them to look it up?

 

The master list could be on the base class for that skeleton. You can view inherited properties in DR and look through the attach_pos_name* for the names of the attach positions.

 

Ideally, we would have a better list, like DR could parse those spawnargs into a GUI menu and you could point and click at the position you wanted to use, or even create a new attach position within the editor, but that's something for the future.

Link to comment
Share on other sites

Ah, I realize what one of my problems was...the wiki said "angle", and it should be "angles". Fixed the wiki page.

Link to comment
Share on other sites

Is there an easier way to test attachment points? I find handling the rotation values a pain in the ass--it's not intuitive to me at all, and having to spend five minutes reloading the map each time I try a new value doesn't help.

 

The old dynamic attachment commands don't seem to work with the new system, however. Is there some other option I could use to speed up the process of testing values?

Link to comment
Share on other sites

I've been using a combination of "tdm_attach_rot" / "tdm_attach_offset" console commands and reloadDecls / spawn. Tweak the offset first, until you're satisfied with that, then save the values to the entityDefs and move on to rotation.

Link to comment
Share on other sites

Thanks, I didn't know you could spawn new guards in the same session with updated values. That's a HELL of a lot faster than having to reload the game each time. <_<

 

(It's also a lot of fun to watch them start fighting when they notice each other...) :D

post-9-1249239799_thumb.jpg

Link to comment
Share on other sites

  • 1 year later...

I'm looking through "TODO:" notes around the code (cannot access bugtracker :( ). Noticed a strange comment related to "attach_posmod_name_*" spawnarg. And this thread is the only one which mentions it.

 

1. Are "attach_posmod_name_*" and "attach_pos_name_*" used?

 

2. Here is the piece of code in "attach_posmod_name_*" handler:

 

// TODO: Prove mathematically that adding the angles is the same as converting
// the angles to rotation matrices and multiplying them??
pPos->angleOffset += ang;

 

I think it is wrong.

 

EDIT: 3. Are there any other places in code where Euler angles are added instead of taking composition of rotations?

 

 

Link to comment
Share on other sites

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

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

    • OrbWeaver

      Finally got round to publishing a tutorial on baking normal maps in Blender, since most of the ones we have are inaccessible or years out of date.
      · 0 replies
    • nbohr1more

      The FAQ wiki is almost a proper FAQ now. Probably need to spin-off a bunch of the "remedies" for playing older TDM versions into their own article.
      · 1 reply
    • nbohr1more

      Was checking out old translation packs and decided to fire up TDM 1.07. Rightful Property with sub-20 FPS areas yay! ( same areas run at 180FPS with cranked eye candy on 2.12 )
      · 3 replies
    • taffernicus

      i am so euphoric to see new FMs keep coming out and I am keen to try it out in my leisure time, then suddenly my PC is spouting a couple of S.M.A.R.T errors...
      tbf i cannot afford myself to miss my network emulator image file&progress, important ebooks, hyper-v checkpoint & hyper-v export and the precious thief & TDM gamesaves. Don't fall yourself into & lay your hands on crappy SSD
       
      · 7 replies
    • OrbWeaver

      Does anyone actually use the Normalise button in the Surface inspector? Even after looking at the code I'm not quite sure what it's for.
      · 7 replies
×
×
  • Create New...