summaryrefslogblamecommitdiff
path: root/src/lib/ephysics/ephysics_body.cpp
blob: 8998d89fc6e86b66c8f96135461e34e0d36eaa30 (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                    
                  



                                         
                                                        
                                      
 

                          

                 
                             
                             
                                    




                   






                                                  
             
 
                                                              

                                                                            
                                                              
                                                        




                                                                      
                                      
                         

  



                                 
                  

  
                                     

                       
  
 
                                     
 
                           
               



                   
                    
  
 
                                
                            


                     
           










                                                               





















































                                                                                                                                                                                           
           
                                                                                                    

               
                   
                
                                                                           



                                        


                                
                           
 

                                      
 
                                                   
                                               

                                                                              
                                                          
 

                                                                     


                                                          



                                                                            

      





                                                                     
                                          
      
                                                           





                                             











                                                              




                           



                                       



                           



                                                     
 














                                                             
                  

                                                                               
 

                                                               
                           


      










                                                                         
                                      
                                                                                            

                                        
                                
 

                                                   





                                                                  

                                    
                        












                                                           


                















































                                                                                
           
                                                                                                                         







                                                                                
                                                                                              
 
                                               
                        
                    
                   
                
              
                       
 

                                                     
 
                                              
                                           
      

                                                             
                                              

                                                           
                                                                        
                                                  
                                          
                                                                       


                                                                             

                                                                          

      
             
                                                                       
 
                                                            


           







                                                            

                                           




                    
                                                        




                                        
                                           

                                                            

                                           


      


















                                                                           







                                                                    

                             
 
                                                            
                                                           



            


















                                                                         


                                                         
                                        


                                         


                                                      


                     
                        

                                             



                                
                                    
 
                               

                                     

                                    



                                                        

                                                                                
                                       


                                                                    
                                                                 
                                                     
 


                      

                                                           
 
                                          

                                                                 


                                                                          
                                       


                                                                    
                                                                 
                                                     


           
 

                                          
      



                                                                            
 

                                              
                                                    
           
                                                                  
 

                                                                 
 

                                       

      
                          








                                                
                        



                                                        
                        

 



                                                                    
 
                                              

                                                    





                                                                           











                                                                     




                                                            



                                                                    
                                   




                                                                     

 







                                                                                                                          
                                                                                                  
 

                                                                        
                                           







                                                                 

 















































                                                                                                           


                                                               



                                        

                                                                           




                                                                          
                
             















                                                                         







                                                             
                                         
                                           
                                                              
      

                                                      
                                                 
                         


                                                                                
                                            













                                                                         
                                         
                                           



                                                               
                                                 


                         


                                                                                
                                            












                                                                   


                      
                                                                                               

                       
               







                                                             
                                         


                      


                       



                       
                     




                      
                                                                                                                                                
 


                                                           

                       






                                                 
 
                                                            


                                                    
                      

      
                                             


                                               
                              

      
                                

                                                         
                                                                
                                                    






                                                               


                                             
                            

      
                                         

                                           



                                                          








                                                        
               











                          


           
                                                                                                                                    

                                                



                                                                       




                                                       











                                                                                                  









                                                                         
           
























                                                                           
                                  
                                                              


           
















                                                                             
                                                              

 






                                                               









                                                                        

                                         

 
           



                                                                   
                             

                                             

                                         








                                                                 
                            
           
                                                     





                                                          





                                                                 
                                        




           



                                                         


                                                            
                       
                                                   











                                                                    




                                                                                                                                                 
                                   














                                                                   
                                                                         


                                             
                                                               






                                                           
                                                        
                                                               


                                                       

                                                         















                                                                      


                       





                                                                         
                                                                                    
 
                         
                           
                                
                     



                                               
                 
 

                                                                      

                                             
      
                                                                            

                                                   
                                                               
                                           
 
                                                  

                                                    
                                                           
      

                                                   


                                                                          
      

       
                                                           
 
                                               
                                                                      
      
 


                    


                       
 
                                           


           
                                                                                  
 
                           

                     
                        

                                               

                                                                   

                


                                                          
 
                                              
                                          


                                               





                                                                     




                                                                     
 
                                           
 
                                                                         


           
                                                                                                                           

                                                
            

                                                     
                                                  

            
                                                                         
 
                                         
                                                   







                                                                          
                                            

 
            
                                                                                                                            

                                               
                     



                                            

                                                      






                                                       
           

                                                                   
                                                            















                                                                                 
                           



                                                




































                                                                                 
           


                                       
               
               
                                        



                                                                         
                                                                                
                                                                            
                                                                                   
 
                               

                                                                                 









                                                                               

                                      


                                                      






                                                                        
 






                                                  
                          




              
                                                                                                                              


























                                                                     

                             


















                                                                            
                                                                 




           
                                                        
 
































                                                                  
 








































                                                                                
                                                                       

                                                      




                                                   















































































































                                                                                
                                                                       

                                                      


           
                                                                             
 
                                                 
                           
                     
                     
                 
               
 
                                              

                                                                  



                                                   
 
                                                          
                                               



                                                               
                                               
 
                                    
 

                    
                                                                           


               
                                              
      

                                           

                                                                          

               
 

                                                                  
 

                              


                                                                           
                                                            
                                                                         

 
           

































                                                                         




                                             








                                                           

                                                             
                                                      
 


                                                                  








                                                                          




                                                                         
      

                                                


      
    

                                               


                                                                 



                                                                       
 
                                           


                                                                 


                                                                  


    

                                                      
                               
                             
 
                                                            
                                                          

                                                        
                                                             
                                                              



                                                             


                                                            
 
                              

            

                                                                    


                                                     


                                                              

 
         
                                                                                                                           








                                                                   
                            













                                                                                  
    
                                                                                                     
 
                                      


                          
 
                                                              

            

                                                 

                  
      


                                                        
 
                               
                                                                               
                                         
 


                                                     
                                         
 



                                                                             


             
                                                       



                           





                                                      
















































                                                                                 






































                                                                                     


                                                                           
                                
                                           
 






                                                          
 


                                                         
 


                                                            


                                                                          

















                                                                                 


                                                         

 















































                                                                                 





                                     

                                                                 

                                         
 
                                




                                             














                                                                                 
                                                                             

 


                                                                                   
                                 






                                                                       


                                                    
                      
                                                                                                             

                       
 
                                                                                
                                                  
                          
 
                            

                                                            
 
                                       
                                                 
 
                                                      
                                             
 


               


















                                                                                                                     





                                                                    

                                      
 
                                                     

                                      

                                                               

      
                                                    

                                       


                                                              

      
                                                      

                                       

                                                                      

      
                                                   

                                         

                                                               
      


                                                 


















                                                                                    
                                                 

















                                                              
                                             

 

                                                                                                     
 
                            


                                        
                                       



                                                                    

                                                              
 
                                                 
      




                                                 

 








































                                                                                    



















                                                                                
                    
                                                                                           

                       
                                        

                                   

                                                      








                                                          

                                                                 

                                                                 

                                                                              
 





                                                
                                                      


                  



                                   
                                                
 
                                                            

                                                  











                                                                              




                                                      

                                                   
 



                                                                                




                                       

                                   

                                      


                                             
 

               
          
          

                                             





                    
           
                                                                                                                    





                                                                       



                       


                                            



                                                 






                                                                 


                      

 



                                                                                                             
                     



















                                                                              
                                                                              
                                            

                 
                                





                                         
 



                                                                                 
 





                                                                             








                                            






















                                                                                                                                                           
                                















                                                            
                                                                          
                                           

















                                                                                                           





                          
                                               
                                                       




                                        
                                         









                                                                                                           












                                                                               
                                         


                                                                       
 











                                                                                                                            
 














                                                                            
                                            

 


                                                                                           






                                                 






                                                                            




                                                                          
 


                                                                
 
                                            



                
                                 
                                                                                                          


















                                                            
                                                            
                                                 
                                                           


















































                                                                                 
                                                                     











                                                             
                                                     



























                                                                              

                                         

                                                                      






                                                                              

                                                                      





                                                                             
                                            















                                             
                    
                                                      

                       
                                        


                                   

                                                                              






                                                
                                   

                                                          








                                                                   
                                                





                                                
                                                                


                  
                                              

                                                   
                                                                           









                                                                     



                                                      
 

                                                   
 



                                                                                 




                                       

                                   
                                      

               
          
          

                                             
                                        




                    
                                      


               
                    


























                                                                              
                                                 
 
                                     
                       
 
              
      
                                                  


                    
                                                                    




                                                     
 
                                   
                                                                                
                                                  
                                              

                                      


                    


                                                 
                                               


                                   


                                                                           






                                                
                                   
















                                                                               
                                                                


                  
                                         

                                                   
                                                                            









                                                                     



                                                      
 

                                                   
 



                                                                                 




                                       

                                   
                                      

               
          
              
                                                             

                                        




                    
                                      



                    

                                            
                                     
                       
 
              
      
                                             


                    
                                                              
 
                                   

                                                                           
                                         

                                      

 


                                                                     

                                                                     

                                                    

                             
                       
                     
                     
                     
                   












                                               






                                                             

                                        




                                                       


                                                             

                            







                                                                             

                                               


                         
                         



                                     
                                     

                           
                           


                                     
                       


                                          
                                        
 
                                     
                                    

      












                                                                              
                                      






                                             



                                                                                






                                                   
 
                                   


                                                                             

                                                                     
                                            

                                      

 


                                                            







                                                                              
 


                                                                             
 


                                                                            
 


                                                                           
 


                                                                             
 


                                                                            


                      
                                                                                                                                                                        
















                                                       
                              

                                                      




                                                                              
 



                    
                                                     
 
                            
                       
 
                                                                       
                                                                          
                                                               
               


                    
                                                        
 
                               

                       
                                                                     
                                                                            
                                                             
               


                    
                                                      
 
                            
                       
 
                                                                       
                                                                          
                                                              
               


                    
                                                       
 
                               

                       
                                                                     
                                                                           
























                                                                           
               




                                             

                                                                       
                                 
                            




                                      

                         





                                                      
                             


                                   
                             

                                        

 
         

                                                                                                
                                          
               



                                                                        
               




                                                                         
               


                      
      
                                                               
                                                                         
                                                                                
                                                                            
                                                                                   
                               



                                                                                 
                                                                               
           
      

                             
                                                              
                                                                                 

                       
      


                                                                                 

                                                                                 

                                                                         
      
 
                    
            
 
                                               
                                                                            
                                                                      
 
                                         
                                                                               
                                            
                                                                       
                                                                                    




                                                    
                    
 









                                                                      

                                                              
                                                                                
                                                                 
                                                                                   
                                                    
      
 
                          



                                                                                 
                                                                          
      
 















                                                                    
                                                                                                                                   


             
                                                      


               


                                                                 
                                        
      
                                                                              


               
                                         
                                                      
                                                                     
                                            


         
                                                                                   






                                                  
                                        
      
                                                                              


               
                                         
                                        
                                            


         
                                                                                 






                                                      
                                         
                                      
                                            


         
                                                                                                                                               

                     
                   








                                                      
                                              
                                                                     

                                               

                                                                   

                

                                                                       
                                      
                                                                       


                            










                                                        





                                                                  
                                         
                                                  
                     

                                            










                                                  
                     


         
                                                                                    
 





                                                             
                                                    
                                                                            
                                                                            

 














                                                                                                                     
         
                                                                                             
 
               
 
             
      
                                                        


               
                                               







                                                                         

 
         
                                                                                     






                                                         
                      
 
                                         
                                           


                                                                  
 
                                                                             
                                            

 

                                                                                              
 
             
      
                                                         
               

      
                      
 


                                                                           


         

                                                                                                            





                                                            

                      
                                         


                                                                               
                                            

 

                                                                                                                    





                                                                  
               

      

                      
                                               




                                                                               


         







                                       
                                         













                                                                 
                                            




                                

                                                                                             
             




                                                     

                      
                                         

                                                           
                                            


         
                                                                                                     
 
             




                                                

                      


                                                                              


         











                                                     
                                                                                                                                      














                                                                
                                                           




                                                                      
                                                                            










                                                                              

                                                


           
                                                                                                                    

                              
                        








                                                               




                                                     

                                                     
              

      
                  

 
           
                                                                                                                                     

                              
                        








                                                               





                                                                           

      
                  

 


                                                                       
                                                            






                                                                

 








                                                                      
                                         

                                                     
                                            










                                                         



                                               

 


                                                                 
                                                      






                                                          

 








                                                                
                                         

                                                  
                                            










                                                      



                                              













                                                           












                                                                                      
         
                                                                                      
 
               
                     
 





                                                   

                                               
                                         
                                           







                                                                   
                                            


         
                                                                                                                                    










                                                   
                                         
                                           
                                                                            
                                                                  

                                                                    
                                            


         
                                                                                                                         






                                                       

                      
                                         

                                                                      
                                            


         
                                                                                                                                  






                                                                      

                      

                                                                       
                                                                       


         
                                                                                              






                                                          
                                         
                                           
                                                                        
                                            


         
                                                                                                                          






                                                  

                      
                                         

                                                                       
                                            

 

                                                                                                                                   



                                                                 
               

      

                      


                                                                        

 
                          
                                                                                    
 
                             
                     



                                                 
                    

      







                                         
                                              




                                        
               

 




















                                                                             
         
                                                                          
 
                        
                     
                     






                                                 







                                                       
                                         
                                           
 
                                      

                                              

                       
                                                        

       


                                                                     
 
                                            


         






















                                                       
         
                                                                                    








                                                 
                                         

                                               

                                                                      
                                      
                                            


         
                                                                                                                                  









                                                 
                                         
                                    
                                                                          
                                                                

                                                                  
                                      
                                            


         
                                                                                                  
 





                                                 
                                         
                                    
                                                                             
                                      
                                            


         
                                                                                    
 
                           







                                                  
                                                          
 
                                         
                                          














                                                                                     












                                                  



                            

 
         
                                                                                         








                                                          
                          

 








                                                                
                                                  

















                                                                




















                                                                                





                                                 






















                                                                           























                                                              









                                                   
 
































                                                                          
           
                                                                                                               



























                                                                                 







                                                                                                                            
                                                                                                                                          





























                                                                               
                                                                                                                      
 
                                                     











                                                     
                                   






















                                                        
               
















                                                                 

                                                                                                                                   



                                                          

                                                      





































                                                                              
               



                                                             
               









                                                                        

                                                                                           




                                    

                                                      















                                                                 

                                                                                       




                                    

                                                      























                                                                           
                                                                                                                           
 
                                                     











                                                     
                                   
















                                                        
                               













                                                                 

                                                                                                                                        



                                                          

                                                           














































                                                                             

                                                                                                




                                    

                                                           















                                                                 

                                                                                            




                                    

                                                           






















                                                                           
           
                                                                                                                        



























                                                                           
                                                                                                                                     
 
                                        


                                          

                                                 




                                                               
                                                            
                                                                                





                                                                        

                                                          







                                                                               

                                                                          

 

                                                                                             




                                    

                                                 















                                                                 

                                                                                         




                                    

                                                 











                                                                   
                                                              









                                                                           
           
                                                                                                                              











                                                                       
                                                                                                                                                  














                                                                           
                         

                                                      
                                                                                 
                                                             

                                         


           
                                                                                                                           


                                                                   
                                                                                 
 




                                                                            
                                                                                 


           
                                                                                                                                           





                                               

                                                  


























                                                                              

                                                                              
 


                                                                  
                                                            
                                                                                 

                                                              
                                                                                 

















                                                                               
                                                                                    

                                              


                    
                                                                                                   


                                           

                                                  












                                                                               
                                                                                               




                                           

                                                  










                                                                   
                                                                    





                                                                       

















                                                                                                                              

                                                   

                                                                              

                                                

                                                                         



                                                                                 














                                                                                      

                                                   
                                                                     

                                                
                                                                


                                                                        















                                                                                  

                                                   
                                                                       

                                                
                                                                  


                                                                          




                                           


                   
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <Evas.h>
#include <Ecore.h>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"

#include <BulletCollision/CollisionShapes/btShapeHull.h>
#include <LinearMath/btGeometryUtil.h>

#pragma GCC diagnostic pop

#include <math.h>

#include "ephysics_trimesh.h"
#include "ephysics_private.h"
#include "ephysics_body_materials.h"

#ifdef  __cplusplus
extern "C" {
#endif

#define BODY_CLOTH_CHECK() \
   do { \
     if (body->type == EPHYSICS_BODY_TYPE_CLOTH) \
       { \
          WRN("Not supported for cloth"); \
          return; \
       } \
   } while(0)

typedef struct _EPhysics_Body_Callback EPhysics_Body_Callback;
typedef struct _EPhysics_Body_Evas_Stacking EPhysics_Body_Evas_Stacking;
typedef struct _EPhysics_Body_Soft_Body_Slice EPhysics_Body_Soft_Body_Slice;
typedef struct _EPhysics_Body_Face_Obj EPhysics_Body_Face_Obj;
typedef struct _EPhysics_Quaternion EPhysics_Quaternion;

struct _EPhysics_Body_Callback {
     EINA_INLIST;
     void (*func) (void *data, EPhysics_Body *body, void *event_info);
     void *data;
     EPhysics_Callback_Body_Type type;
     Eina_Bool deleted:1;
};

struct _EPhysics_Body_Collision {
     EPhysics_Body *contact_body;
     Evas_Coord x;
     Evas_Coord y;
     Evas_Coord z;
};

struct _EPhysics_Body_Evas_Stacking {
     Evas_Object *evas;
     float stacking;
};

struct _EPhysics_Body_Soft_Body_Slice
{
     Evas_Object *evas_obj;
     int index;
     struct {
          double x;
          double y;
     } p[3];
     float stacking;
};

struct _EPhysics_Body_Face_Obj {
    EPhysics_Body_Face face;
    Evas_Object *obj;
};

static void
_ephysics_body_cloth_anchor_mass_reset(EPhysics_Body *body)
{
   double anchor_mass;
   anchor_mass = 1 / (body->soft_body->m_nodes.size() * 0.025);

   for (int i = 0; i < body->soft_body->m_anchors.size(); i++)
     body->soft_body->m_anchors[i].m_node->m_im = anchor_mass;

   DBG("Cloth anchors mass reset.");
}

EAPI void
_ephysics_body_soft_body_light_apply(Evas_Map *m, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab, Evas_Coord bx, Evas_Coord by, Evas_Coord bz)
{
   double x, y, z, nx, ny, nz, ln, br;
   Evas_Coord mx, my, mz, mr, mg, mb, ma;
   int i;

   for (i = 0; i < 4; i++)
     {

        evas_map_point_coord_get(m, i, &mx, &my, &mz);
        evas_map_point_color_get(m, i, NULL, NULL, NULL, &ma);

        x = mx;
        y = my;
        z = mz;

        nx = sqrt(pow(bx - x, 2));
        ny = sqrt(pow(by - y, 2));
        nz = sqrt(pow(bz - z, 2));
        ln = nx + ny + nz;

        if (ln != 0.0)
          {
             nx /= ln;
             ny /= ln;
             nz /= ln;
          }

        x = lx - bx;
        y = ly - by;
        z = lz - bz;

        ln = pow(x, 2) + pow(y, 2) + pow(z, 2);
        ln = sqrt(ln);

        if (ln != 0.0)
          {
             x /= ln;
             y /= ln;
             z /= ln;
          }

        br = (nx * x) + (ny * y) + (nz * z);
        if (br < 0.0) br = 0.0;

        mr = ar + ((lr - ar) * br);
        mg = ag + ((lg - ag) * br);
        mb = ab + ((lb - ab) * br);

        evas_map_point_color_set(m, i, mr, mg, mb, ma);
     }
}

static void
_ephysics_body_soft_body_slices_apply(EPhysics_Body *body, Evas_Object *evas_obj, Eina_List *slices)
{
   double rate;
   void *list_data;
   Eina_List *l;
   Evas_Coord wy, wh, y0, y1, y2, x0, x1, x2, z0, z1, z2, w, h, bx, by, bz;
   Evas_Map *map;
   btVector3 p0, p1, p2;
   btSoftBody::tFaceArray faces;
   EPhysics_Body_Soft_Body_Slice *slice;
   int lr, lg, lb, ar, ag, ab;
   Evas_Coord lx, ly, lz;
   Eina_Bool light = EINA_FALSE;
   EPhysics_Camera *camera;

   int px, py, pz, foc;
   Eina_Bool perspective = EINA_FALSE;

   camera = ephysics_world_camera_get(body->world);
   rate = ephysics_world_rate_get(body->world);
   ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
                                      NULL);
   evas_object_geometry_get(evas_obj, NULL, NULL, &w, &h);

   ephysics_body_geometry_get(body, &bx, &by, &bz, NULL, NULL, NULL);

   if ((body->light_apply) ||
       (ephysics_world_light_all_bodies_get(body->world)))
     {
        ephysics_world_point_light_position_get(body->world, &lx, &ly, &lz);
        ephysics_world_point_light_color_get(body->world, &lr, &lg, &lb);
        ephysics_world_ambient_light_color_get(body->world, &ar, &ag, &ab);
        light = EINA_TRUE;
     }

   if (ephysics_camera_perspective_enabled_get(camera))
     {
        ephysics_camera_perspective_get(camera, &px, &py, &pz, &foc);
        perspective = EINA_TRUE;
     }

   EINA_LIST_FOREACH(slices, l, list_data)
     {
        slice = (EPhysics_Body_Soft_Body_Slice *)list_data;

        faces = body->soft_body->m_faces;
        p0 = faces[slice->index].m_n[0]->m_x;
        p1 = faces[slice->index].m_n[1]->m_x;
        p2 = faces[slice->index].m_n[2]->m_x;

        slice->stacking = p0.z() + p1.z() + p2.z();

        map = evas_map_new(4);

        evas_map_point_image_uv_set(map, 0, slice->p[0].x * w,
                                    slice->p[0].y * h);
        evas_map_point_image_uv_set(map, 1, slice->p[1].x * w,
                                    slice->p[1].y * h);
        evas_map_point_image_uv_set(map, 2, slice->p[2].x * w,
                                    slice->p[2].y * h);
        evas_map_point_image_uv_set(map, 3, slice->p[2].x * w,
                                    slice->p[2].y * h);

        x0 = p0.x() * rate;
        x1 = p1.x() * rate;
        x2 = p2.x() * rate;

        y0 = wh + wy - (p0.y() * rate);
        y1 = wh + wy - (p1.y() * rate);
        y2 = wh + wy - (p2.y() * rate);

        z0 = p0.z() * rate;
        z1 = p1.z() * rate;
        z2 = p2.z() * rate;

        evas_map_point_coord_set(map, 0, x0, y0, z0);
        evas_map_point_coord_set(map, 1, x1, y1, z1);
        evas_map_point_coord_set(map, 2, x2, y2, z2);
        evas_map_point_coord_set(map, 3, x2, y2, z2);

        if (perspective)
          evas_map_util_3d_perspective(map, px, py, pz, foc);

        if (body->back_face_culling)
          {
             if (evas_map_util_clockwise_get(map))
                  evas_object_show(slice->evas_obj);
             else
               {
                  evas_map_free(map);
                  evas_object_hide(slice->evas_obj);
                  continue;
               }
          }

        if (light)
          _ephysics_body_soft_body_light_apply(map, lx, ly, lz, lr, lg, lb, ar,
                                               ag, ab, bx, by, bz);

        evas_object_map_set(slice->evas_obj, map);
        evas_object_map_enable_set(slice->evas_obj, EINA_TRUE);
        evas_map_free(map);
     }
}

static inline double
_ephysics_body_soft_body_slice_calc(double val, double delta, double max)
{
   double ret = val + delta / max;
   if (ret < 0)
     ret = 0;
   else if (ret > 1)
     ret = 1;
   return ret;
}

static EPhysics_Body_Soft_Body_Slice *
_ephysics_body_soft_body_slice_new(EPhysics_Body *body, double delta, double max, int index)
{
   EPhysics_Body_Soft_Body_Slice *slice;
   btSoftBody::tFaceArray faces;

   slice = (EPhysics_Body_Soft_Body_Slice *)calloc(
      1, sizeof(EPhysics_Body_Soft_Body_Slice));
   if (!slice)
     {
        ERR("Couldn't allocate EPhysics_Soft_Body_Slice memory.");
        return NULL;
     }

   faces = body->soft_body->m_faces;

   slice->index = index;
   slice->p[0].x = _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[0]->m_x.x(), delta, max);
   slice->p[0].y = 1 - _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[0]->m_x.y(), delta, max);
   slice->p[1].x = _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[1]->m_x.x(), delta, max);
   slice->p[1].y = 1 - _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[1]->m_x.y(), delta, max);
   slice->p[2].x = _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[2]->m_x.x(), delta, max);
   slice->p[2].y = 1 - _ephysics_body_soft_body_slice_calc(
      faces[slice->index].m_n[2]->m_x.y(), delta, max);

   return slice;
}

static Eina_List *
_ephysics_body_soft_body_slices_get(EPhysics_Body *body)
{
   Eina_List *l, *slices_list, *slices = NULL;
   void *ldata, *slice_data;
   EPhysics_Body_Face_Slice *face_slice;

   EINA_LIST_FOREACH(body->faces_slices, l, ldata)
     {
        face_slice = (EPhysics_Body_Face_Slice *)ldata;
        EINA_LIST_FOREACH(face_slice->slices, slices_list, slice_data)
             slices = eina_list_append(slices, slice_data);
     }

   return slices;
}

EAPI int
ephysics_body_soft_body_slice_index_get(EPhysics_Body *body, Evas_Object *slice)
{
   Eina_List *slices;
   void *ldata;
   EPhysics_Body_Soft_Body_Slice *slice_data;

   if (!body)
     {
        ERR("Can't get soft body slice index, body is null.");
        return -1;
     }

   if (body->type == EPHYSICS_BODY_TYPE_RIGID)
     {
        ERR("Can't get soft body slice index, operation not allowed for rigid"
            " bodies.");
        return -1;
     }

   slices = _ephysics_body_soft_body_slices_get(body);
   EINA_LIST_FREE(slices, ldata)
     {
        slice_data = (EPhysics_Body_Soft_Body_Slice *)ldata;
        if (slice_data->evas_obj == slice)
          return slice_data->index;
     }

   return -1;
}

static void
_ephysics_body_soft_body_slice_del_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
   EPhysics_Body_Soft_Body_Slice *slice = (EPhysics_Body_Soft_Body_Slice *)data;
   slice->evas_obj = NULL;
   evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
                                  _ephysics_body_soft_body_slice_del_cb);
}

static void
_ephysics_body_soft_body_slices_init(EPhysics_Body *body, Evas_Object *obj, Eina_List *slices)
{
   EPhysics_Body_Soft_Body_Slice *slice = NULL;
   btVector3 p0, p1, p2;
   void *slice_data;
   Evas_Coord w, h;
   Eina_List *l;
   Evas *evas;
   Evas_Object *parent;

   evas = evas_object_evas_get(obj);
   evas_object_geometry_get(obj, NULL, NULL, &w, &h);

   parent = evas_object_smart_parent_get(obj);
   EINA_LIST_FOREACH(slices, l, slice_data)
     {
        slice = (EPhysics_Body_Soft_Body_Slice *) slice_data;
        slice->evas_obj = evas_object_image_filled_add(evas);
        evas_object_layer_set(slice->evas_obj,
                              evas_object_layer_get(obj));
        evas_object_image_source_set(slice->evas_obj, obj);
        evas_object_image_source_events_set(slice->evas_obj, EINA_TRUE);
        evas_object_resize(slice->evas_obj, w, h);
        evas_object_show(slice->evas_obj);
        evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE);
        evas_object_event_callback_add(slice->evas_obj, EVAS_CALLBACK_DEL,
                                       _ephysics_body_soft_body_slice_del_cb,
                                       slice);

        if (parent) evas_object_smart_member_add(slice->evas_obj, parent);
     }

   if (slice)
     evas_object_image_source_visible_set(slice->evas_obj, EINA_FALSE);

   _ephysics_body_soft_body_slices_apply(body, obj, slices);
}

static void
_ephysics_body_soft_body_slices_free(Eina_List *slices)
{
   EPhysics_Body_Soft_Body_Slice *slice;
   void *slice_data;

   EINA_LIST_FREE(slices, slice_data)
     {
        slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
        if (slice->evas_obj)
          evas_object_del(slice->evas_obj);
        free(slice);
     }
}

static void
_ephysics_body_soft_body_slices_clean(Eina_List *slices)
{
   EPhysics_Body_Soft_Body_Slice *slice;
   void *slice_data;
   Eina_List *l;

   EINA_LIST_FOREACH(slices, l, slice_data)
     {
        slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
        if (slice->evas_obj)
          evas_object_del(slice->evas_obj);
     }
}

static btTransform
_ephysics_body_transform_get(const EPhysics_Body *body)
{
   btTransform trans;
   btVector3 center;
   btScalar radius;

   if (body->type == EPHYSICS_BODY_TYPE_RIGID)
     {
        body->rigid_body->getMotionState()->getWorldTransform(trans);
        return trans;
     }

   body->soft_body->getCollisionShape()->getBoundingSphere(center, radius);
   trans.setIdentity();
   trans.setOrigin(center);
   return trans;
}

static int
_ephysics_body_evas_stacking_sort_cb(const void *d1, const void *d2)
{
   const EPhysics_Body_Evas_Stacking *stacking1, *stacking2;

   stacking1 = (const EPhysics_Body_Evas_Stacking *)d1;
   stacking2 = (const EPhysics_Body_Evas_Stacking *)d2;

   if (!stacking1) return 1;
   if (!stacking2) return -1;

   if (stacking1->stacking < stacking2->stacking) return -1;
   if (stacking1->stacking > stacking1->stacking) return 1;

   return 0;
}

static EPhysics_Body_Evas_Stacking *
_ephysics_body_evas_stacking_new(Evas_Object *obj, float index)
{
   EPhysics_Body_Evas_Stacking *stacking;

   stacking = (EPhysics_Body_Evas_Stacking *)calloc(
                1, sizeof(EPhysics_Body_Evas_Stacking));

   if (!stacking)
     {
        ERR("Could not allocate ephysics soft body evas stacking data.");
        return NULL;
     }

   stacking->evas = obj;
   stacking->stacking = index;
   return stacking;
}

void
ephysics_body_evas_objects_restack(EPhysics_World *world)
{
   void *data, *slice_data, *stack_data;
   EPhysics_Body *body;
   btTransform trans;
   EPhysics_Body_Evas_Stacking *stacking;
   EPhysics_Body_Soft_Body_Slice *slice;
   Eina_List *l, *slices, *bodies, *stack_list = NULL;
   Evas_Object *prev_obj = NULL;
   Eina_Hash *hash;
   Eina_Iterator *it;
   int layer;
   Eina_List *ll = NULL;

   bodies = ephysics_world_bodies_get(world);

   if (!eina_list_count(bodies))
     return;

   hash = eina_hash_int32_new(NULL);

   EINA_LIST_FREE(bodies, data)
     {
        body = (EPhysics_Body *)data;
        if (body->deleted) continue;

        if (body->type == EPHYSICS_BODY_TYPE_RIGID)
          {
             if (!body->evas_obj) continue;
             trans = _ephysics_body_transform_get(body);
             stacking = _ephysics_body_evas_stacking_new(body->evas_obj,
                                                         trans.getOrigin().z());
             if (!stacking) goto error;

             layer = evas_object_layer_get(stacking->evas);
             stack_list = (Eina_List *)eina_hash_find(hash, &layer);
             stack_list = eina_list_append(stack_list, stacking);
             eina_hash_set(hash, &layer, stack_list);

             continue;
          }

        slices = _ephysics_body_soft_body_slices_get(body);
        if (!slices) continue;

        EINA_LIST_FREE(slices, slice_data)
          {
             slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;

             stacking = _ephysics_body_evas_stacking_new(slice->evas_obj,
                                                         slice->stacking);
             if (!stacking) goto error;

             layer = evas_object_layer_get(stacking->evas);
             stack_list = (Eina_List *)eina_hash_find(hash, &layer);
             stack_list = eina_list_append(stack_list, stacking);
             eina_hash_set(hash, &layer, stack_list);
          }
     }


   it = eina_hash_iterator_data_new(hash);
   while (eina_iterator_next(it, &data))
     {
        stack_list = (Eina_List *)data;
        stack_list = eina_list_sort(stack_list, eina_list_count(stack_list),
                                    _ephysics_body_evas_stacking_sort_cb);
        prev_obj = NULL;

        ll = eina_list_append(ll, stack_list);

        EINA_LIST_FOREACH(stack_list, l, stack_data)
          {
             stacking = (EPhysics_Body_Evas_Stacking *)stack_data;

             if (prev_obj)
               evas_object_stack_below(stacking->evas, prev_obj);

             prev_obj = stacking->evas;
          }
     }

   eina_iterator_free(it);

   EINA_LIST_FREE(ll, stack_data)
     {
        stack_list = (Eina_List *) stack_data;
        eina_hash_del_by_data(hash, stack_list);
        EINA_LIST_FREE(stack_list, slice_data)
          free(slice_data);
     }

   eina_hash_free(hash);
   return;

 error:
   ERR("Could not allocate evas stacking data memory.");
   eina_hash_free(hash);
}

static void
_ephysics_body_transform_set(EPhysics_Body *body, btTransform trans)
{
   btTransform origin;

   if (body->type != EPHYSICS_BODY_TYPE_RIGID)
     {
        origin = _ephysics_body_transform_get(body);
        body->soft_body->translate(trans.getOrigin() - origin.getOrigin());
        return;
     }
   body->rigid_body->getMotionState()->setWorldTransform(trans);
}

void
ephysics_body_activate(const EPhysics_Body *body, Eina_Bool activate)
{
   if (body->type == EPHYSICS_BODY_TYPE_RIGID)
     {
        body->rigid_body->activate(activate);
        return;
     }

   body->soft_body->activate(activate);
}

static void
_ephysics_body_forces_update(EPhysics_Body *body)
{
   body->force.x = body->rigid_body->getTotalForce().getX();
   body->force.y = body->rigid_body->getTotalForce().getY();
   body->force.z = body->rigid_body->getTotalForce().getZ();
   body->force.torque_x = body->rigid_body->getTotalTorque().getX();
   body->force.torque_y = body->rigid_body->getTotalTorque().getY();
   body->force.torque_z = body->rigid_body->getTotalTorque().getZ();
   body->rigid_body->clearForces();

   DBG("forces updated: %lf, %lf, %lf", body->force.x, body->force.y,
       body->force.z);
   DBG("torque updated: %lf, %lf, %lf", body->force.torque_x,
       body->force.torque_y, body->force.torque_z);
}

static inline void
_ephysics_body_sleeping_threshold_set(EPhysics_Body *body, double linear_threshold, double angular_threshold, double rate)
{
   body->rigid_body->setSleepingThresholds(linear_threshold / rate,
                                           angular_threshold / RAD_TO_DEG);
}

static inline void
_ephysics_body_linear_velocity_set(EPhysics_Body *body, double x, double y, double z, double rate)
{
   btVector3 linear_velocity = btVector3(x / rate, -y / rate, z / rate);

   ephysics_body_activate(body, EINA_TRUE);
   if (body->rigid_body)
     body->rigid_body->setLinearVelocity(linear_velocity);

   if (body->soft_body)
     {
        for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
          body->soft_body->m_nodes[i].m_v = linear_velocity;
     }
}

static void
_ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Body_Callback *cb)
{
   if (cb->deleted) return;

   cb->deleted = EINA_TRUE;

   if (body->walking)
     {
        body->to_delete = eina_list_append(body->to_delete, cb);
        return;
     }

   body->callbacks = eina_inlist_remove(body->callbacks, EINA_INLIST_GET(cb));
   free(cb);
}

static Eina_Bool
_ephysics_body_event_callback_call(EPhysics_Body *body, EPhysics_Callback_Body_Type type, void *event_info)
{
   Eina_Bool called = EINA_FALSE;
   EPhysics_Body_Callback *cb;
   void *clb;

   body->walking++;
   EINA_INLIST_FOREACH(body->callbacks, cb)
     {
        if ((cb->type == type) && (!cb->deleted))
          {
             cb->func(cb->data, body, event_info);
             called = EINA_TRUE;
          }
     }
   body->walking--;

   if (body->walking > 0) return called;

   EINA_LIST_FREE(body->to_delete, clb)
     {
        cb = (EPhysics_Body_Callback *) clb;
        body->callbacks = eina_inlist_remove(body->callbacks,
                                             EINA_INLIST_GET(cb));
        free(cb);
     }

   return called;
}

void
ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active)
{
   if (body->active == !!active) return;
   body->active = !!active;
   if (active) return;

   _ephysics_body_event_callback_call(body, EPHYSICS_CALLBACK_BODY_STOPPED,
                                      (void *) body->evas_obj);
};

Eina_Bool
ephysics_body_filter_collision(EPhysics_Body *body0, EPhysics_Body *body1)
{
   Eina_List *l;
   void *grp;

   if ((!body0->collision_groups) || (!body1->collision_groups))
     return EINA_TRUE;

   EINA_LIST_FOREACH(body0->collision_groups, l, grp)
     {
        if (eina_list_data_find(body1->collision_groups, grp))
          return EINA_TRUE;
     }

   return EINA_FALSE;
}

EAPI Eina_Bool
ephysics_body_collision_group_add(EPhysics_Body *body, const char *group)
{
   Eina_Stringshare *group_str;

   if (!body)
     {
        ERR("Can't add body collision group, body is null.");
        return EINA_FALSE;
     }

   ephysics_world_lock_take(body->world);
   group_str = eina_stringshare_add(group);
   if (eina_list_data_find(body->collision_groups, group_str))
     {
        INF("Body already added to group: %s", group);
        eina_stringshare_del(group_str);
        ephysics_world_lock_release(body->world);
        return EINA_TRUE;
     }

   body->collision_groups = eina_list_append(body->collision_groups, group_str);
   ephysics_world_lock_release(body->world);
   return EINA_TRUE;
}

EAPI Eina_Bool
ephysics_body_collision_group_del(EPhysics_Body *body, const char *group)
{
   Eina_Stringshare *group_str;

   if (!body)
     {
        ERR("Can't remove body collision group, body is null.");
        return EINA_FALSE;
     }

   ephysics_world_lock_take(body->world);
   group_str = eina_stringshare_add(group);
   if (!eina_list_data_find(body->collision_groups, group_str))
     {
        INF("Body isn't part of group: %s", group);
        eina_stringshare_del(group_str);
        ephysics_world_lock_release(body->world);
        return EINA_TRUE;
     }

   body->collision_groups = eina_list_remove(body->collision_groups, group_str);
   eina_stringshare_del(group_str);
   eina_stringshare_del(group_str);
   ephysics_world_lock_release(body->world);
   return EINA_TRUE;
}

EAPI const Eina_List *
ephysics_body_collision_group_list_get(const EPhysics_Body *body)
{
   if (!body)
     {
        ERR("Can't get the body's collision group, body is null.");
        return NULL;
     }

   return body->collision_groups;
}

static EPhysics_Body *
_ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_y, double cm_z)
{
   EPhysics_Body *body;
   double rate;

   body = (EPhysics_Body *) calloc(1, sizeof(EPhysics_Body));
   if (!body)
     {
        ERR("Couldn't create a new body instance.");
        return NULL;
     }

   rate = ephysics_world_rate_get(world);
   body->scale[0] = 1;
   body->scale[1] = 1;
   body->scale[2] = 1;
   body->size.w = rate;
   body->size.h = rate;
   body->size.d = rate;
   body->mass = mass;
   body->world = world;
   body->cm.x = cm_x;
   body->cm.y = cm_y;
   body->cm.z = cm_z;

   return body;
}

static EPhysics_Body *
_ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y, double cm_z)
{
   btRigidBody::btRigidBodyConstructionInfo *rigid_body_ci;
   btDefaultMotionState *motion_state;
   btRigidBody *rigid_body;
   EPhysics_Body *body;
   btScalar mass = 1;
   btVector3 inertia;

   if (!collision_shape)
     {
        ERR("Couldn't create a %s shape.", type);
        return NULL;
     }

   body = _ephysics_body_new(world, mass, cm_x, cm_y, cm_z);
   if (!body)
     {
        ERR("Couldn't create a new body instance.");
        goto err_body;
     }

   motion_state = new btDefaultMotionState();
   if (!motion_state)
     {
        ERR("Couldn't create a motion state.");
        goto err_motion_state;
     }

   inertia = btVector3(0, 0, 0);
   collision_shape->calculateLocalInertia(mass, inertia);

   rigid_body_ci = new btRigidBody::btRigidBodyConstructionInfo(
      mass, motion_state, collision_shape, inertia);
   if (!rigid_body_ci)
     {
        ERR("Couldn't create a rigid body construction info.");
        goto err_rigid_body_ci;
     }

   rigid_body = new btRigidBody(*rigid_body_ci);
   if (!rigid_body)
     {
        ERR("Couldn't create a rigid body.");
        goto err_rigid_body;
     }

   body->type = EPHYSICS_BODY_TYPE_RIGID;
   body->collision_shape = collision_shape;
   body->rigid_body = rigid_body;
   body->rigid_body->setUserPointer(body);
   body->rigid_body->setLinearFactor(btVector3(1, 1, 0));
   body->rigid_body->setAngularFactor(btVector3(0, 0, 1));

   if (!ephysics_world_body_add(body->world, body))
     {
        ERR("Couldn't add body to world's bodies list");
        goto err_world_add;
     }

   delete rigid_body_ci;

   INF("Body %p of type %s added.", body, type);
   return body;

err_world_add:
   delete rigid_body;
err_rigid_body:
   delete rigid_body_ci;
err_rigid_body_ci:
   delete motion_state;
err_motion_state:
   free(body);
err_body:
   delete collision_shape;
   return NULL;
}

static void
_ephysics_body_efl_canvas_object_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
   EPhysics_Body *body = (EPhysics_Body *) data;

   if (body->default_face)
     _ephysics_body_soft_body_slices_clean(body->default_face->slices);

   body->evas_obj = NULL;
   DBG("Evas object deleted. Updating body: %p", body);
}

static void
_ephysics_body_soft_body_anchors_rebuild(int node, btRigidBody *rigid_body, btSoftBody *soft_body)
{
   btTransform world_trans = rigid_body->getWorldTransform();
   btVector3 local = world_trans.inverse() * soft_body->m_nodes[node].m_x;

   for (int i = 0; i < soft_body->m_anchors.size(); i++)
     {
        if (soft_body->m_anchors[i].m_node == &soft_body->m_nodes[node])
          soft_body->m_anchors[i].m_local = local;
     }
}

void
ephysics_body_soft_body_bending_constraints_generate(EPhysics_Body *body)
{
   btSoftBody *soft_body = body->soft_body;

   for (; body->bending_constraints; body->bending_constraints--)
     soft_body->generateBendingConstraints(2, soft_body->m_materials
                                           [body->material_index]);
}

static void
_ephysics_body_cloth_constraints_rebuild(EPhysics_Body *body)
{
   btRigidBody *rigid_body;
   btSoftBody *soft_body;
   btSoftBody::Node *node;
   btSoftBody::Anchor anchor;
   int anchors_size = body->soft_body->m_anchors.size();

   soft_body = body->soft_body;

   if (anchors_size)
     {
        rigid_body = soft_body->m_anchors[0].m_body;
        for (int m = 0; m < anchors_size; m++)
          {
             anchor = soft_body->m_anchors[m];
             node = anchor.m_node;
             for (int n = 0; n < soft_body->m_nodes.size(); n++)
               {
                  if (node == &soft_body->m_nodes[n])
                    _ephysics_body_soft_body_anchors_rebuild(n, rigid_body,
                                                             soft_body);
               }
          }
     }
   soft_body->generateClusters(0);
   ephysics_body_soft_body_bending_constraints_generate(body);
}

static void
_ephysics_body_soft_body_constraints_rebuild(EPhysics_Body *body)
{
   btSoftBody *soft_body = body->soft_body;
   btRigidBody *rigid_body = body->rigid_body;

   if (soft_body->m_anchors.size() > 0)
     {
        for (int i = 0; i < soft_body->m_nodes.size(); i++)
          _ephysics_body_soft_body_anchors_rebuild(i, rigid_body, soft_body);
     }
   else
     {
        for (int i = 0; i < soft_body->m_nodes.size(); i++)
          soft_body->appendAnchor(i, rigid_body);
     }

   soft_body->generateClusters(0);
   ephysics_body_soft_body_bending_constraints_generate(body);
}

inline static double
_ephysics_body_volume_get(const EPhysics_Body *body)
{
   btVector3 vector = body->collision_shape->getLocalScaling();
   return vector.x() * vector.y() * vector.z();
}

void
_ephysics_body_soft_body_dragging_set(EPhysics_Body *body, int triangle)
{
   btSoftBody::Face face;
   btSoftBody::Node *node;

   body->dragging_data.triangle = triangle;
   body->dragging_data.dragging = EINA_TRUE;

   face = body->soft_body->m_faces[triangle];
   node = face.m_n[0];
   body->dragging_data.mass = node->m_im;
}

static void
_ephysics_body_soft_body_mass_set(EPhysics_Body *body, double mass)
{
   int valid_nodes;
   btSoftBody::Node node;
   double inverse_mass = 0.0;

   if (body->type == EPHYSICS_BODY_TYPE_SOFT)
     body->soft_body->setTotalMass(mass);
   else if (mass > 0.0)
     {
        valid_nodes = 0;
        for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
          {
             node = body->soft_body->m_nodes[i];
             if (node.m_im && !node.m_battach)
               valid_nodes++;
          }

        if (valid_nodes > 0)
          {
             inverse_mass = 1 / (mass / valid_nodes);
             if (body->dragging_data.dragging)
               {
                  valid_nodes++;
                  inverse_mass = 1 / (mass / valid_nodes);
                  body->dragging_data.mass = inverse_mass;
               }
          }

        for (int i = 0; i < body->soft_body->m_nodes.size(); i++)
          {
             node = body->soft_body->m_nodes[i];
             if (node.m_im && !node.m_battach)
               node.m_im = inverse_mass;
          }
     }
}

static void
_ephysics_body_mass_set(EPhysics_Body *body, double mass)
{
   btVector3 inertia(0, 0, 0);

   if (body->density)
     mass = body->density * _ephysics_body_volume_get(body);

   if (body->soft_body)
     _ephysics_body_soft_body_mass_set(body, mass);
   else
     {
        body->collision_shape->calculateLocalInertia(mass, inertia);
        body->rigid_body->setMassProps(mass, inertia);
        body->rigid_body->updateInertiaTensor();
     }

   body->mass = mass;
   DBG("Body %p mass changed to %lf.", body, mass);
}

static void
_ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z, Evas_Coord w, Evas_Coord h, Evas_Coord d, double rate)
{
   double mx, my, mz, sx, sy, sz;
   btTransform trans;
   int wy, height;
   btVector3 body_scale, old_scale;

   ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL,
                                      NULL, &height, NULL);
   height += wy;

   mx = (x + w * body->cm.x) / rate;
   my = (height - (y + h * body->cm.y)) / rate;
   mz = (z + d * body->cm.z) / rate;
   sx = (w <= 0) ? 1 : w / rate;
   sy = (h <= 0) ? 1 : h / rate;
   sz = (d <= 0) ? 1 : d / rate;

   trans = _ephysics_body_transform_get(body);
   trans.setOrigin(btVector3(mx, my, mz));
   body_scale = btVector3(sx, sy, sz);
   old_scale = btVector3(body->scale[0], body->scale[1], body->scale[2]);

   if (body->type == EPHYSICS_BODY_TYPE_SOFT)
     {
        body->soft_body->scale(btVector3(1, 1, 1) / old_scale);
        body->soft_body->scale(body_scale);
        body->rigid_body->proceedToTransform(trans);
        _ephysics_body_transform_set(body, trans);
        _ephysics_body_soft_body_constraints_rebuild(body);
     }
   else if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
     {
        body->soft_body->setTotalMass(body->mass, true);
        body->soft_body->scale(btVector3(1, 1, 1) / old_scale);
        body->soft_body->scale(body_scale);
        _ephysics_body_transform_set(body, trans);
        _ephysics_body_cloth_constraints_rebuild(body);
        body->soft_body->setTotalMass(body->mass, false);
        _ephysics_body_cloth_anchor_mass_reset(body);
     }
   else
     {
        body->collision_shape->setLocalScaling(body_scale);
        body->rigid_body->proceedToTransform(trans);

        if (!body->rigid_body->isStaticObject())
          _ephysics_body_mass_set(body, ephysics_body_mass_get(body));
     }

   _ephysics_body_transform_set(body, trans);
   ephysics_body_activate(body, EINA_TRUE);

   body->size.w = w;
   body->size.h = h;
   body->size.d = d;
   body->scale[0] = sx;
   body->scale[1] = sy;
   body->scale[2] = sz;

   DBG("Body %p position changed to (%lf, %lf, %lf).", body, mx, my, mz);
   DBG("Body %p scale changed to (%lf, %lf, %lf).", body, sx, sy, sz);
}

static void
_ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h, Evas_Coord d)
{
   Evas_Coord bx, by, bz;
   double rate, sx, sy, sz;
   btVector3 body_scale, center;
   btTransform trans;

   rate = ephysics_world_rate_get(body->world);
   sx = w / rate;
   sy = h / rate;
   sz = d / rate;

   DBG("Body %p scale changed to (%lf, %lf, %lf).", body, sx, sy, sz);

   body_scale = btVector3(sx, sy, sz);
   if (body->type == EPHYSICS_BODY_TYPE_SOFT)
     {
        btVector3 old_scale(body->scale[0], body->scale[1], body->scale[2]);
        trans = _ephysics_body_transform_get(body);

        body->soft_body->scale(btVector3(1, 1, 1) / old_scale);
        body->soft_body->scale(body_scale);

        _ephysics_body_transform_set(body, trans);
        body->rigid_body->proceedToTransform(trans);

        _ephysics_body_soft_body_constraints_rebuild(body);
     }
   else if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
     {
        ephysics_body_geometry_get(body, &bx, &by, &bz, NULL, NULL, NULL);
        _ephysics_body_geometry_set(body, bx, by, bz, w, h, d, rate);
        return;
     }
   else
     {
        body->collision_shape->setLocalScaling(body_scale);

        if(!body->rigid_body->isStaticObject())
          _ephysics_body_mass_set(body, ephysics_body_mass_get(body));
     }

   body->size.w = w;
   body->size.h = h;
   body->size.d = d;
   body->scale[0] = sx;
   body->scale[1] = sy;
   body->scale[2] = sz;

   ephysics_body_activate(body, EINA_TRUE);
}

static void
_ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z)
{
   double rate, mx, my, mz;
   btTransform trans;
   int wy, height;
   btVector3 body_scale;

   rate = ephysics_world_rate_get(body->world);
   ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL,
                                      NULL, &height, NULL);
   height += wy;

   mx = (x + body->size.w * body->cm.x) / rate;
   my = (height - (y + body->size.h * body->cm.y)) / rate;
   mz = (z + body->size.d * body->cm.z) / rate;

   trans = _ephysics_body_transform_get(body);
   trans.setOrigin(btVector3(mx, my, mz));

   if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
     _ephysics_body_transform_set(body, trans);
   else if (body->type == EPHYSICS_BODY_TYPE_SOFT)
     {
        _ephysics_body_transform_set(body, trans);
        body->rigid_body->proceedToTransform(trans);
        body->rigid_body->getMotionState()->setWorldTransform(trans);
     }
   else
     {
        body->rigid_body->proceedToTransform(trans);
        body->rigid_body->getMotionState()->setWorldTransform(trans);
     }

   ephysics_body_activate(body, EINA_TRUE);

   DBG("Body %p position changed to (%lf, %lf, %lf).", body, mx, my, mz);
}

static void
_ephysics_body_efl_canvas_object_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
   EPhysics_Body *body = (EPhysics_Body *) data;
   int w, h;

   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
   if ((w == body->size.w) && (h == body->size.h))
     return;

   DBG("Resizing body %p to w=%i, h=%i, d=%i", body, w, h, body->size.d);

   ephysics_world_lock_take(body->world);
   _ephysics_body_resize(body, w, h, body->size.d);

   if (body->type == EPHYSICS_BODY_TYPE_CLOTH)
     {
        _ephysics_body_soft_body_slices_clean(body->default_face->slices);
        _ephysics_body_soft_body_slices_init(body, body->evas_obj,
                                             body->default_face->slices);
     }

   ephysics_world_lock_release(body->world);
}

 static void
_ephysics_body_soft_body_evas_restack_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
   EPhysics_Body *body = (EPhysics_Body *)data;
   Eina_List *slices;
   void *ldata;
   EPhysics_Body_Soft_Body_Slice *slice;
   short layer = evas_object_layer_get(obj);

   slices = _ephysics_body_soft_body_slices_get(body);
   EINA_LIST_FREE(slices, ldata)
     {
        slice = (EPhysics_Body_Soft_Body_Slice *)ldata;
        evas_object_layer_set(slice->evas_obj, layer);
     }
   DBG("Body's slices layer reset to: %d", layer);
}

static void
_ephysics_body_face_slice_del(EPhysics_Body_Face_Slice *face_slice)
{
   _ephysics_body_soft_body_slices_free(face_slice->slices);
   free(face_slice->points_deform);
   free(face_slice);
}

static EPhysics_Body_Face_Slice *
_ephysics_body_face_slice_add(EPhysics_Body *body, EPhysics_Body_Face face)
{
   EPhysics_Body_Face_Slice *face_slice;

   face_slice = (EPhysics_Body_Face_Slice *)calloc(1,
                                               sizeof(EPhysics_Body_Face_Slice));
   if (!face_slice)
     return NULL;

   face_slice->face = face;
   body->faces_slices = eina_list_append(body->faces_slices, face_slice);
   face_slice->body = body;
   return face_slice;
   DBG("New face slice added to body %p", body);
}

static EPhysics_Body_Face_Slice *
_ephysics_body_face_slice_get(EPhysics_Body *body, EPhysics_Body_Face face)
{
   Eina_List *l;
   void *ldata;
   EPhysics_Body_Face_Slice *face_slice = NULL;

   EINA_LIST_FOREACH(body->faces_slices, l, ldata)
     {
        if (((EPhysics_Body_Face_Slice *)ldata)->face == face)
          {
             face_slice = (EPhysics_Body_Face_Slice *)ldata;
             break;
          }
     }

   return face_slice;
}

static EPhysics_Body_Face_Obj *
_ephysics_body_face_evas_object_get(EPhysics_Body *body, EPhysics_Body_Face face)
{
   Eina_List *l;
   void *ldata;
   EPhysics_Body_Face_Obj *face_obj;

   EINA_LIST_FOREACH(body->face_objs, l, ldata)
     {
        face_obj = (EPhysics_Body_Face_Obj *)ldata;
        if (face_obj->face == face)
          return face_obj;
     }

   DBG("Could not find requested face");
   return NULL;
}

static void
_ephysics_body_del(EPhysics_Body *body)
{
   EPhysics_Body_Callback *cb;
   void *ldata;
   void *group;
   EPhysics_Body_Face_Slice *face_slice;

   if (body->evas_obj)
     {
        evas_object_event_callback_del(body->evas_obj, EVAS_CALLBACK_DEL,
                                       _ephysics_body_efl_canvas_object_del_cb);
        evas_object_event_callback_del(body->evas_obj, EVAS_CALLBACK_RESIZE,
                                       _ephysics_body_efl_canvas_object_resize_cb);

        if (body->faces_slices)
          evas_object_event_callback_del(body->evas_obj, EVAS_CALLBACK_RESTACK,
                                       _ephysics_body_soft_body_evas_restack_cb);
     }

   while (body->callbacks)
     {
        cb = EINA_INLIST_CONTAINER_GET(body->callbacks,
                                       EPhysics_Body_Callback);
        body->callbacks = eina_inlist_remove(body->callbacks, body->callbacks);
        free(cb);
     }

   ephysics_constraint_body_del(body);

   EINA_LIST_FREE(body->collision_groups, group)
      eina_stringshare_del((Eina_Stringshare *)group);

   EINA_LIST_FREE(body->faces_slices, ldata)
     {
        face_slice = (EPhysics_Body_Face_Slice *)ldata;
        if (_ephysics_body_face_evas_object_get(body, face_slice->face))
          ephysics_body_face_evas_object_unset(body, face_slice->face);
        _ephysics_body_face_slice_del(face_slice);
     }

   if (body->rigid_body)
     {
        delete body->rigid_body->getMotionState();
        delete body->collision_shape;
        delete body->rigid_body;
     }

   delete body->soft_body;

   free(body);
}

static void
_ephysics_body_evas_object_map_apply(EPhysics_Body *body, Evas_Map *map, Evas_Object *obj, Eina_Bool bfc, Eina_Bool update_cw)
{
   EPhysics_Camera *camera = ephysics_world_camera_get(body->world);

   if (ephysics_camera_perspective_enabled_get(camera))
     {
        int px, py, z0, foc;
        ephysics_camera_perspective_get(camera, &px, &py, &z0, &foc);
        evas_map_util_3d_perspective(map, px, py, z0, foc);
     }

   if (bfc)
     {
        if (evas_map_util_clockwise_get(map))
          {
             if (update_cw)
               body->clockwise = EINA_TRUE;
             evas_object_show(obj);
          }
        else
          {
             if (update_cw)
               body->clockwise = EINA_FALSE;
             evas_map_free(map);
             evas_object_hide(obj);
             return;
          }
     }
   else
       evas_object_show(obj);

   if ((body->light_apply) ||
       (ephysics_world_light_all_bodies_get(body->world)))
     {
        int lr, lg, lb, ar, ag, ab;
        Evas_Coord lx, ly, lz;

        ephysics_world_point_light_position_get(body->world, &lx, &ly, &lz);
        ephysics_world_point_light_color_get(body->world, &lr, &lg, &lb);
        ephysics_world_ambient_light_color_get(body->world, &ar, &ag, &ab);
        evas_map_util_3d_lighting(map, lx, ly, lz, lr, lg, lb, ar, ag, ab);
     }

   evas_object_map_set(obj, map);
   evas_object_map_enable_set(obj, EINA_TRUE);
   evas_map_free(map);
}

static void
_ephysics_cloth_face_objs_update(EPhysics_Body *body EINA_UNUSED)
{

}

static voi