• Editor
  • RegionAttachment Explanation Request

Related Discussions
...

Hi,

Can you shed some light on what the updateOffset method does in the libgdx implementation of RegionAttachment?

I would like to see an example of a region attachment with just X, Y coordinates being set instead of uv vertices if possible as well.

It computes the 4 vertices of the region relative to 0,0. Just before it is drawn, the offset is translated, rotated, and scaled based on the bone it is attached to.

You can see spine-corona for an example that uses just x and y. Note that non-uniform scaling will not work correctly when done this way. Some toolkits can't draw a quad or rhomboid, so this is a limitation they have to deal with.

It's supposed to be that way. It isn't empty, it just has a name. In most runtimes, the region attachment holds things that can be reused for many skeletons: the texture, texture coordinates, attachment offset. In Corona all that stuff has to go in the Corona image, which is a scene graph node. Each skeleton instance needs its own set of Corona images, so there isn't anything to store in region attachment. See Skeleton.lua line 50 for where the image stuff happens. It isn't great, but that's Corona for you. Region attachments shouldn't be tied to a particular skeleton because they go in the skin which goes in the skeleton data which can be used for many different skeleton instances. That is the whole idea, the XxxData classes hold the bind pose and other data that is stateless. The non-Data classes hold the stateful data for one particular instance. This has a few advantages. Eg, it means you don't have to load all the data many times if you want multiple of the same skeleton. Also note Animation is stateless and can be used for many skeleton instances.

/rant :drunk:

I have ported the libgdx runtime from github to as3 and I am having trouble getting the image attachement to line up correctly with the bones.

I believe my issue is in either of two places. In the Bone.as class I changed the updateWorldTransform to use the as3 Matrix class so that it can handle the calculations, here is the method:

public function updateWorldTransform(flipX : Boolean, flipY : Boolean) : void {
			var parent : Bone = this._parent;
			
		var scaleX : Number = this.scaleX;
		var scaleY : Number = this.scaleY;
		if (flipX) {
			scaleX = -this.scaleX;
		}
		if (flipY) {
			scaleY = -this.scaleY;
		}
		
		_worldTransform.identity();
		_worldTransform.translate(this.x, this.y);
		_worldTransform.rotate(MathUtils.getRadiansFromDegrees(this.rotation));
		_worldTransform.scale(this.scaleX, this.scaleY);
		_worldRotation = this.rotation;
		
		if (parent != null) {
			var parentTransform : Matrix = parent.worldTransform;
			parentTransform.concat(_worldTransform);
			
			_worldRotation += parent.worldRotation;
			_worldTransform = parentTransform;
		}
	}

And in my custom StarlingRegionAttachment.as class that extends from RegionAttachment.as I am trying to draw the image texture in the correct position. Starling has an image class that can have xy coordinates set or you can use a transform matrix. I elected to go with the matrix:

override public function draw (displayObject : *, slot : Slot) : void {
			if (_region == null) throw new Error("RegionAttachment is not setup: " + this);
			if (_texture == null) throw new Error("RegionAttachment is not setup: " + this);
			
		var batch : QuadBatch = displayObject as QuadBatch;
		if(!_image)
			_image = new Image(_texture);
		
		var centerX : Number = width / 2;
		var centerY : Number = height / 2;

		//Get clone of bone world transform
		var boneTransform : Matrix = slot.bone.worldTransform;

		var imageMatrix : Matrix = _image.transformationMatrix;
		imageMatrix.identity();
		
		imageMatrix.translate(this.x - slot.bone.x, this.y - slot.bone.y);
		imageMatrix.rotate(MathUtils.getRadiansFromDegrees(this.rotation));
		imageMatrix.scale(this.scaleX, this.scaleY);
		//imageMatrix.translate(-centerX * this.scaleX, -centerY * this.scaleY);
		
		boneTransform.concat( imageMatrix );
		
		_image.width = this.width;
		_image.height = this.height;
		_image.transformationMatrix = boneTransform;
			
		batch.addImage(_image);
	}

I am not sure if you have any experience with the flash coordinate system and can shed some light on what I may be doing wrong here in my approach. The skin lines up almost right but its still off. If you don't have time, no worries.

Spine does not use traditional matrix transformations. See here, Spine does the same thing. I would port the code as-is and not use the AS matrix stuff.

Thanks for pointing me in the right direction. Great architecture and tool! I am integrating this into the GameBuilder Studio engine and making it open source, both bitmap rendering and Starling attachments, fyi. Will post when its up.

Can't wait for inverse kinematics support as I am use to 3D skeletal animation and rigging.