Tính toán bậc bốn sao cho điểm xương theo một hướng xác định


7

Trong một nỗ lực để giải quyết câu hỏi này , tôi quyết định tìm ra các hướng tuyệt đối (không gian thế giới) của mỗi khớp trong tư thế nguồn (như các vectơ đơn vị chuẩn hóa), và sau đó xoay các khớp của mục tiêu để khớp với hướng đó. Vấn đề là, làm thế nào để tôi tính toán bậc bốn xoay sao cho xương (vectơ từ khớp đến con của nó) theo hướng xác định trong không gian thế giới.

CẬP NHẬT: Đây là suy nghĩ hiện tại của tôi. Đối với mỗi xương, ma trận biến đổi sẽ là:

(1) absolute transform = local rotation * relative transform to parent in bind pose * parent absolute trasform

Vì vậy, giả sử chúng ta có 3 khớp: Vai -> Khuỷu tay -> Cổ tay. Chúng tôi đã có một biến đổi tuyệt đối cho Vai và đang cố gắng tính toán xoay cho Khuỷu tay sao cho Khuỷu tay -> Cổ tay sẽ đi theo hướng tương tự như trong hoạt hình nguồn. Từ (1), các phép biến đổi tuyệt đối sẽ là:

(2) ELBOW absolute = ELBOW local * SHOULDER to ELBOW relative * SHOULDER absolute

(3) WRIST absolute = WRIST local * ELBOW to WRIST relative * ELBOW absolute

Bằng cách thay thế, chúng tôi nhận được:

(4) WRIST absolute = WRIST local * ELBOW to WRIST relative * ELBOW local *
                     SHOULDER to ELBOW relative * SHOULDER absolute

Hằng số của chúng tôi là: ELBOW to WRIST relative, SHOULDER to ELBOW relative, và SHOULDER absolute. WRIST localsẽ chỉ bao gồm xoay vòng, không có bản dịch / tỷ lệ. Vấn đề là tìm một giá trị sao cho ELBOW local...

(5) normalize(position(ELBOW absolute) - position(WRIST absolute)) = desired direction

(6) ELBOW local consists only of rotations (no translation/scale)

Bây giờ vì chúng ta đã biết chiều dài của xương và hướng mong muốn, có thể ước tính phần vị trí của WRIST absolute, nhưng xoay sẽ không xác định được (và vấn đề này dường như không thể thực hiện đệ quy, AFAICT).

Suy nghĩ ban đầu của tôi là bởi vì WRIST localchỉ xoay vòng và tôi sẽ giải quyết nó trong lần lặp tiếp theo của vòng lặp, tôi hoàn toàn có thể bỏ qua nó trong tính toán ELBOW local. Câu trả lời của Steven Stadnick bên dưới cho thấy nó có thể không dễ dàng như vậy, vì sự định hướng của xương rất quan trọng đối với việc lột da. Tuy nhiên, nếu tôi có thể làm việc này trên một cây gậy, tôi có thể đi qua cây cầu đó sau.


2
Hừm, vì vậy nếu tôi hiểu đúng: targetDir = normalize (childPos - selfPos) . Nếu bạn có một dòng điện , vậy thì tại sao không tính toán quat từ góc trục .. tương tự như cách họ đề xuất ở đây
teodron

@teodron - Nếu chỉ dễ dàng như vậy, nhưng có 3 ma trận khác, nó sẽ được nhân lên. Tôi sẽ cập nhật câu hỏi.
Robert Fraser

Một câu hỏi, bởi vì tôi có cảm giác rằng câu hỏi cập nhật của bạn đang giữ một câu trả lời rõ ràng mà bạn không muốn: Tại sao bạn không viết: M = inv(childRelative) * childAbsolute * inv(parentAbsolute) * inv(selfRelative)như bạn làm với các phương trình ma trận như vậy? Các ma trận selfRelative và childRelative là gì? Cách thông thường mà người ta thực hiện chuyển đổi chuỗi là: childTransform = ParentToChild * ParentTransform . Các ma trận khác không rõ ràng trong mục đích của chúng là gì. Vấn đề là thú vị và nó có thể sẽ sưng lên để phá vỡ bí ẩn :).
teodron

@teodron - Xin lỗi, tôi nên đã rõ ràng hơn. selfRelative là ma trận đặt ra ràng buộc của cha mẹ với xương này (ParentToChild mà bạn nói). childRelative là ma trận liên kết của xương hiện tại với đứa trẻ đang nói đến. Đây là từ bộ xương và được cố định. Đối với "tại sao không giải quyết nó như một phương trình ma trận bình thường", hai lý do: thứ nhất, M cần phải chỉ xoay và tôi cũng không có ma trận conAbsolute hoàn chỉnh, chỉ có phần vị trí.
Robert Fraser

1
Vấn đề phức tạp, dường như chưa được xác định rõ ràng , do đó, các thủ thuật nghịch đảo bình phương / giả nhỏ nhất có thể giúp ích, nhưng đó là một mớ hỗn độn và bạn phải thực hiện bằng số. Trước hết, chỉ cần ma trận xoay của bạn thêm 4 ẩn số và không tuyến tính, trong khi bạn elbow_localgiới thiệu 8 phương trình khác .. đó là 4 phương trình với 8 ẩn số .. Hãy xem xét sử dụng các chuỗi động học .. với ít độ tự do hơn. Bạn đã nghe nói về hội nghị Denavit-Hartenberg chưa? Tôi đã sử dụng nó với kết quả khá tốt
teodron

Câu trả lời:


3

Từ mô tả của bạn về vấn đề của bạn, có vẻ như cốt lõi của vấn đề có thể là đại diện của bạn hiện đang thiếu dữ liệu. Xương không chỉ đơn giản là vectơ từ khớp này sang khớp tiếp theo - đó là ma trận biến đổi hoàn toàn đại diện cho hướng của khung cục bộ, liên quan đến không gian thế giới hoặc đối với khung cục bộ của xương tiếp theo 'lên chuỗi' . Ví dụ, hãy tưởng tượng một nhân vật có vết sẹo trên cẳng tay của họ; có vectơ từ khuỷu tay của nhân vật đến cổ tay của họ sẽ cho bạn biết vị trí của bàn tay họ, nhưng nó không mang đủ thông tin để cho bạn biết vết sẹo sẽ ở đâu - ví dụ, dù nó chỉ lên hay chỉ xuống. Thông tin định hướng này phải là một phần của bộ xương nguồn của bạn.

Một khi bạn có những thứ được thể hiện dưới dạng các khung định hướng cục bộ đầy đủ và không chỉ đơn giản là các vectơ định hướng, phần còn lại của thông tin sẽ dễ dàng rơi ra; chính xác như bạn đã đề xuất trong bài đăng của mình, bạn sẽ sử dụng nghịch đảo ma trận để 'bóc tách' các lớp biến đổi của mình và lấy ma trận M ngon ngọt ở giữa. Chẳng hạn, nếu bạn có childAbs = childRel * M * selfRel * ParentAbs, sau đó nhân với childRel -1 ở bên trái của cả hai bên, sau đó ParentAbs -1 * selfRel -1 ở bên phải của cả hai bên để lấy M = childRel - 1 * conAbs * cha mẹ -1 * selfRel -1 . Lưu ý rằng việc đảo ngược một sản phẩm của ma trận sẽ thay đổi thứ tự nghịch đảo của chúng được nhân lên, do đó thứ tự quan trọng ở đây - (A * B) -1 không (nói chung) bằng A -1 * B -1 , nhưng thay vào đó là B -1 * A -1 .

Khi bạn đã có ma trận M của mình, sẽ có rất nhiều thông tin trên web về cách chuyển đổi nó thành một nhóm thứ tư; nếu bạn đang tìm kiếm sự giúp đỡ với bước cụ thể đó, thì hãy cho tôi biết và tôi có thể bổ sung điều này bằng một vài liên kết, nhưng có vẻ như có một số vấn đề khác bạn sẽ phải giải quyết ngay bây giờ trước khi bạn cần xem xét nó

EDIT: Sau một vài ngày để suy nghĩ về nó, tôi đã viết ra mô tả sơ bộ này về quá trình đi từ không gian thế giới đến thông tin địa phương; hy vọng điều này sẽ làm sáng tỏ hơn một chút.

Tôi sẽ làm việc theo sơ đồ tách rời trong đó mỗi xương bao gồm một ma trận xoay và chuyển vị; ma trận xoay được áp dụng ở phần gốc của xương và sự dịch chuyển được đưa ra theo tọa độ xương-cục bộ. Điều này thực hiện hai điều quan trọng:

  1. Nó cho phép nhiều xương được gắn vào cùng một ổ cắm, làm cho một bộ xương thích hợp dễ dàng hơn một chút - ví dụ, xương đòn có thể dễ dàng gắn vào một điểm trung tâm giữa xương đòn hoặc xương ngón tay đến một điểm trung tâm trên cổ tay.
  2. Điều đó có nghĩa là hầu hết hoạt hình của xương có thể được thực hiện bằng cách chỉ thay đổi góc xoay liên quan đến xương đó; ví dụ, một bắp tay có thể được di chuyển bằng cách thay đổi hướng của nó, làm cho vị trí của khuỷu tay bị dịch chuyển xung quanh. Trên thực tế, xương thường sẽ có độ dịch chuyển (0, 0, L), trong đó L là chiều dài của xương - đầu xa của xương nằm dọc theo trục Z cục bộ từ điểm gắn của xương.

Đây không nhất thiết là cách tiếp cận tôi muốn thực hiện, nhưng nó đơn giản nhất cho nói chuyện về cách thực hiện; Mặc dù kết quả chính xác sẽ không thể áp dụng trực tiếp cho tình huống của bạn, IMHO thực sự là tốt nhất: nó mang đến cho bạn cơ hội hiểu rõ hơn về cách thức hoạt động của phái sinh và cách rút ra các công thức chính xác sẽ áp dụng cho phiên bản vấn đề của chính bạn.

Một vài định nghĩa nhanh về số lượng chúng tôi đang làm việc với: Một siêu ký tự 'w' chỉ định một giá trị không gian thế giới, trong khi 'l' biểu thị một giá trị cục bộ. Chúng tôi sẽ sử dụng P cho vị trí và R để xoay; ví dụ, xương P w sẽ là vị trí mục tiêu không gian thế giới của xương, (trái ngược với vị trí cơ sở của nó, tất nhiên là vị trí mục tiêu của cha mẹ của nó), trong khi xương R l sẽ là hướng xương cục bộ - đó là là, làm thế nào nó được xoay đối với khung của cha mẹ nó.

Bây giờ, với điều này, chúng ta có thể rút ra vị trí mục tiêu và định hướng của bất kỳ khớp nào - như một số ý kiến ​​cho thấy, mối quan hệ được đệ quy. Đặc biệt, chúng tôi có

R w con = R w cha mẹ * R l con

P w con = P w cha + R w con * P l con

(Những người này nói, tương ứng, 'Định hướng thế giới của trẻ là định hướng địa phương của nó bao gồm định hướng thế giới của cha mẹ' và 'Vị trí thế giới của trẻ là vị trí thế giới của cha mẹ được bù đắp bởi sự dịch chuyển cục bộ của nó (như được dịch thành phù hợp tọa độ thế giới) '.)

Với điều này, bây giờ chúng ta có thể giải các phương trình này để tìm các tham số của xương - đó là R l và P l - về mặt dữ liệu không gian thế giới mà chúng ta đưa ra. Điều này cũng đưa ra một lý do khác tại sao chúng ta không chỉ cần vị trí mà còn định hướng không gian thế giới của tất cả các khớp; nó là một thành phần thiết yếu để giải quyết.

Tìm định hướng địa phương là đơn giản; chúng ta chỉ có thể nhân cả hai mặt của phương trình định hướng của mình với nghịch đảo của định hướng không gian thế giới của cha mẹ, nhận được

R l con = R w cha -1 * R w con

Sự dịch chuyển cục bộ cũng tương đối dễ hình dung, vì chúng ta biết sự dịch chuyển trong không gian thế giới và ma trận biến đổi để đi từ không gian địa phương sang không gian thế giới (có nghĩa là chúng ta biết ma trận đi theo hướng khác):

P l con = R w con -1 * (P w con - P w cha )

Cũng lưu ý một điều: không có phương trình nào phụ thuộc vào vị trí hoặc hướng của xương cha mẹ, chỉ là giá trị không gian thế giới cho cha mẹ và con - vì vậy trong khi họ cảm thấy đệ quy (và tính toán để tìm giá trị không gian thế giới cho xương cần phải đi từ gốc của bộ xương ra lá của nó vì phụ thuộc vào kết quả) chúng thực sự có thể được thực hiện theo bất kỳ thứ tự nào.

Hy vọng rằng điều này mang lại cho bạn cảm giác tốt hơn cho những gì đang diễn ra - thật dễ dàng bị sa lầy trong tất cả các biến đổi bay xung quanh. Hãy cho tôi biết nếu điều này sẽ giúp!


Bộ xương nguồn bao gồm các phép quay. Điều vectơ chỉ là một nỗ lực để tôi nhắm mục tiêu lại nó. Tôi có thể dễ dàng có được vòng xoay nguồn (liên quan đến khung của chính nó), nhưng tôi không biết điều này sẽ giúp tôi như thế nào, vì nguồn có một tư thế ràng buộc khác. Đối với phần thứ hai của bài viết của bạn, vấn đề là tìm ra childAbsolute sẽ là gì - tôi biết vị trí, nhưng không phải là xoay cục bộ của nó.
Robert Fraser


@Fraser I worry that we're talking past each other a bit, but I simply don't understand how you can not care what the local rotation of the child bone will be. That data is essential for any skinning application on the skeleton, shy of stick-figure animation (or 2d, but then we're talking about a different problem entirely). What are you doing with your target pose such that orientations aren't a part of it?
Steven Stadnicki

@Fraser Nếu bạn đang nói 'Tôi chỉ có vị trí trên khớp của tư thế đích chứ không phải bất kỳ định hướng nào' và bạn cũng cần xác định hướng hợp lý cho xương của tư thế mục tiêu, thì đó là một vấn đề khác hoàn toàn (và khó hơn nhiều) , nhưng ngay cả ở đó tôi cảm thấy vấn đề sẽ được giải quyết tốt hơn nhiều bằng cách cố gắng tìm ra cách bạn có thể lấy hướng ra khỏi dữ liệu đặt mục tiêu của mình, thay vì tự mình tạo ra một hướng 'hợp lý'.
Steven Stadnicki

Tôi đã viết lại câu hỏi để làm cho nó rõ ràng hơn những gì tôi đang cố gắng thực hiện. Đây là video về sự tiến bộ của tôi tính đến 2 tuần trước: youtube.com/watch?v=H6Qq37TM4Pg ... Cảm ơn tất cả sự giúp đỡ của bạn, anh bạn.
Robert Fraser

2

Nếu tôi hiểu đúng, bạn đang lưu trữ toàn bộ các xương xương đỉnh vào một ma trận. Tôi nghĩ rằng vấn đề của bạn liên quan nhiều hơn đến cách bạn lưu trữ Xương hơn là bản thân họ.

Tôi sẽ cố gắng giải thích ý của tôi là:

Vì về cơ bản bạn có kết quả của phép quay (xương xoay để sử dụng làm mô hình) và bạn muốn biết tứ phương sẽ tạo ra kết quả đó cho các xương khác, tại sao bạn không thể lưu trữ xương dưới dạng vectơ, thay vì tạo ra một ma trận?

Bạn có thể một xương được lưu trữ dưới dạng một vectơ làm từ 2 điểm (Đầu, Đuôi). Vì bạn đang xoay nó, Head sẽ là điểm tựa và Tail sẽ xoay quanh một trục tùy ý. Đó là một công việc bậc bốn.

Bây giờ, vì bạn có vị trí 'nghỉ ngơi' của Bone A và bạn muốn khớp với hướng Bone B, bạn cần biết lượng xoay Alpha và Trục. Đúng?

Lấy góc giữa 2 Bone vectơ A và B, bạn sẽ tìm thấy Alpha và kết quả chuẩn hóa của sản phẩm chéo của AxB sẽ giúp bạn có được Trục.

Điều duy nhất khiến điều này trở nên phức tạp hơn đối với bạn là bạn cần ngoại suy Bone Vector khỏi ma trận bạn đang sử dụng trước đó để có thể bạn chỉ cần lưu trữ xương dưới dạng vectơ (cặp điểm) thay vì tạo ma trận.

Also, since you are basically rotating a bone in relation to how its parent was rotated (that's what I got from your code) then you probably could simply ignore all that.

Since you want to match another bone's position, you already know that position to be legit, so all the relative-rotation stuff shouldn't be necessary.


The problem with storing them as vectors is interpolation between frames or blending multiple animations.
Robert Fraser

I can't comment other users answers (yet) so...anyway, if you need more data than just 2 points, then store them in a manner that suits you. Both answers you got till now are pointed at the same problem: you're either missing data or you're using a format that causes you problem. If a bone contains rotation and translation, you could just store the respective infos without dealing with a full matrix and so avoiding the whole conversion. Using just quaternions and 2-3 points per bone, the position of the child would just be dependant on the parent's one so the system should take care of itself.
Darkwings

Toàn bộ mục đích của việc này là để có thể nhắm mục tiêu lại hoạt hình từ bộ xương này sang bộ xương khác để kết quả có thể bị kiện như hoạt hình do nghệ sĩ tạo ra, cũng như được pha trộn với hoạt hình do thủ tục và nghệ sĩ tạo ra. Dữ liệu tôi đang lưu trữ là một phần tư xoay vòng cho mỗi xương so với cha mẹ của nó cho mỗi khung. Điều này đã làm việc cho hình ảnh động nhập khẩu. Tôi không muốn thay đổi cách tôi lưu trữ hình ảnh động kết quả - bước này hoàn toàn là một phần của đường ống; Tôi muốn kết quả cuối cùng hoạt động giống như (và hoạt động cùng với) các hình ảnh động khác.
Robert Fraser

I saw the video. I'm still convinced that to easily store a rotation relative to a known axis (relative to the parent bone) you're still complicating your life. I understand that the reason you want a rotation-only matrix is to prevent unwanted translations, resulting in invalid parent-children position. Something that couldn't happen anyway if you were using the parent bone as the axis bound using just quaternions. Else you'd need to endlessly convert from matrix to quaternion, and then matrix again. In short, I share Steven Stadnicki's POV, when he says that it's not just a math problem.
Darkwings
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.