Moving Exterior Meshes to Interior Cells

Post » Fri May 13, 2011 5:07 pm

Hello everyone,

I'm currently trying to design a system that moves exterior meshes (such as statics, lights, furniture, etc) from the exterior worldspace to a (random) vanilla interior cell. Currently the script works as it is supposed to - objects are successfully moved from the exterior to the interior. However, a problem arises when the interior mesh is rotated in regards to its exterior mesh - if the interior mesh is rotated by X degrees, then all the moved exterior meshes will be off by that X degree.

Here are some screenshots in order to illustrate the problem:
Exterior Mesh:
Spoiler
[img]http://foxybox.kicks-ass.org/upload/EXteriorMesh.jpg[/img]

Interior mesh:
Spoiler
[img]http://foxybox.kicks-ass.org/upload/InteriorMesh.jpg[/img]


And here is the requisite code to accomplish this (note the trigonometry, which I was trying to use to move the meshes in respect to the Z angle of the interior door mesh):
Spoiler
		if (objectref != 0)		;				if (player.GetInSameCell objectref == 0)					; good...					set objectx to objectref.GetPos X					set objecty to objectref.GetPos Y					set objectz to objectref.GetPos Z					if (objectref.GetObjectType == 28)						if (objectz < lowestzpoint)							set lowestzpoint to objectz							if (lowestzpoint < parentcellwaterheight)								set lowestzpoint to (parentcellwaterheight + 100)							endif						endif					endif					set rotation to 0					player.SetAngle Z exteriordoorzrot					set rotation to (player.GetHeadingAngle objectref)					set rotation to (rotation + (exteriordoorzrot - interiordoorzrot))					Print "Player getheading: " + $rotation					set objectxrot to objectref.GetAngle X					set objectyrot to objectref.GetAngle Y					set objectzrot to objectref.GetAngle Z							set tempdistance to exteriordoorref.GetDistance objectref - player.GetDistance exteriordoorref					if (rotation < 0)							set newobjectx to interiordoorx - ((cos rotation) * tempdistance)						set newobjecty to interiordoory + ((sin rotation) * tempdistance)					endif						if (rotation > 0)						set newobjectx to interiordoorx + ((cos rotation) * tempdistance)						set newobjecty to interiordoory - ((sin rotation) * tempdistance)					endif;					set tempdistancex to (objectx - exteriordoorx);					set tempdistancex to (abs tempdistancex);					set tempdistancex to ((cos rotation) * tempdistance) + tempdistancex;					set tempdistancey to (objecty - exteriordoory);					set tempdistancey to (abs tempdistancey);					set tempdistancey to ((sin rotation) * tempdistance) + tempdistancey					set tempdistancez to (objectz - exteriordoorz);					set tempdistancez to (abs tempdistancez);					Print "Exteriordoorref cell: " + $exteriordoorref.GetParentCell + ", objectref cell: " + $objectref.GetParentCell + ", interiorcell: " + $interiorcell					if (objectref.GetObjectType == 28 && exteriordoorref.GetDistance objectref <= 400)						; probably the exterior mesh of the house...						set objectref to Apple						set objectref to GetNextRef						GoTo 1					endif					if (tempdistance <= 8000)						; also good...;						PrintC "RenIntStaticsNodeQuestScript: Moving exterior item to interior space...";						set newobjectx to (interiordoorx + tempdistancex);						set newobjecty to (interiordoory + tempdistancey)						set newobjectz to (interiordoorz + tempdistancez)						let tempobjectref := objectref.GetBaseObject						let tempobjectref := interiordoorref.PlaceAtMe tempobjectref 1 0 0										if (objectzrot > 360)							set objectzrot to (objectzrot - 360)						endif						if (objectzrot < 0)							set objectzrot to (objectzrot + 360)						endif						let arraysize := (ar_Size intobjectreference) + 1						ar_Resize intobjectreference arraysize						ar_Insert intobjectreference arraysize tempobjectref						tempobjectref.SetPos X newobjectx						tempobjectref.SetPos Y newobjecty						tempobjectref.SetPos Z newobjectz 						tempobjectref.SetAngle X objectxrot						tempobjectref.SetAngle Y objectyrot						tempobjectref.SetAngle Z objectzrot							Print "Exterior door x, y, z: " + $exteriordoorx + " " + $exteriordoory + " " + $exteriordoorz + ", z-angle: " + $exteriordoorzrot							Print "Object x, y, z: " + $objectx + " " + $objecty + " " + $objectz + ", cell: " + $exteriorcell + ", tempdistance: " + $tempdistance							Print "Tempdistancex: " + $tempdistancex + ", tempdistancey: " + $tempdistancey + ", tempdistancez: " + $tempdistancez							Print "Interior door x, y, z: " + $interiordoorx + " " + $interiordoory + " " + $interiordoorz + ", z-angle: " + $interiordoorzrot							Print "Placed object (" + $tempobjectref.GetFormIDString + ") at position: " + $newobjectx + ", " + $newobjecty + ", " + $newobjectz + " in cell: " + $interiorcell + ", rotation: " + $rotation					endif;				endif			set objectref to Apple			set objectref to GetNextRef			GoTo 1		endif

So, anyone have any inkling of how I might accomplish this? ^.^

Edit: Updated the script a bit. Uses unit circle stuff, but it's still a smidgen off... plus the added meshes still aren't being properly rotated to reflect the rotation change in the interior mesh.
User avatar
Tom Flanagan
 
Posts: 3522
Joined: Sat Jul 21, 2007 1:51 am

Post » Fri May 13, 2011 4:52 pm

The problem is that vanilla interiors are not rotated accordingly to the exterior building meshes
What adjusts this in game is the North Marker.

I am not good at anolyzing other people scripts, but as far as I could understand, you are using the exterior and interior doors as 'anchors', so besides the doors Z angle differences, you need also to take into account the North Marker rotation.

You may also take a look at the user function http://cs.elderscrolls.com/constwiki/index.php/PositionRelativeXYZ. It has the math to position an object relative to another, so if you calculate the XYZ and Z angle differences from the external object to the external door and use them as parameter for the function, it should work.

If you are interested I can create a function that does the three steps: get the position relative to a OriginAnchor, PlaceAtMe an object and positions it relative to a TargetAnchor.
User avatar
Sanctum
 
Posts: 3524
Joined: Sun Aug 20, 2006 8:29 am

Post » Fri May 13, 2011 9:03 am

The problem is that vanilla interiors are not rotated accordingly to the exterior building meshes
What adjusts this in game is the North Marker.

I am not good at anolyzing other people scripts, but as far as I could understand, you are using the exterior and interior doors as 'anchors', so besides the doors Z angle differences, you need also to take into account the North Marker rotation.

You may also take a look at the user function http://cs.elderscrolls.com/constwiki/index.php/PositionRelativeXYZ. It has the math to position an object relative to another, so if you calculate the XYZ and Z angle differences from the external object to the external door and use them as parameter for the function, it should work.

If you are interested I can create a function that does the three steps: get the position relative to a OriginAnchor, PlaceAtMe an object and positions it relative to a TargetAnchor.
Actually that's partially what my script currently does - but my math was wrong. Hopefully now that I've seen the math in the PositionRelativeXYZ script I can just copy that over. Thanks!

Edit: Yay! Working!
User avatar
Stacey Mason
 
Posts: 3350
Joined: Wed Nov 08, 2006 6:18 am


Return to IV - Oblivion

cron